/** @file
 *  @brief Service Discovery Protocol handling.
 */

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <sys/types.h>
#include <sys/byteorder.h>
#include <sys/__assert.h>

#include <bluetooth/buf.h>
#include <bluetooth/sdp.h>

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_SDP)
#define LOG_MODULE_NAME bt_sdp
#include "common/log.h"

#include "hci_core.h"
#include "conn_internal.h"
#include "l2cap_internal.h"
#include "sdp_internal.h"

#define SDP_PSM 0x0001

#define SDP_CHAN(_ch) CONTAINER_OF(_ch, struct bt_sdp, chan.chan)

#define IN_RANGE(val, min, max) (val >= min && val <= max)

#define SDP_DATA_MTU 200

#define SDP_MTU (SDP_DATA_MTU + sizeof(struct bt_sdp_hdr))

#define MAX_NUM_ATT_ID_FILTER 10

#define SDP_SERVICE_HANDLE_BASE 0x10000

#define SDP_DATA_ELEM_NEST_LEVEL_MAX 5

/* Size of Cont state length */
#define SDP_CONT_STATE_LEN_SIZE 1

/* 1 byte for the no. of services searched till this response */
/* 2 bytes for the total no. of matching records */
#define SDP_SS_CONT_STATE_SIZE 3

/* 1 byte for the no. of attributes searched till this response */
#define SDP_SA_CONT_STATE_SIZE 1

/* 1 byte for the no. of services searched till this response */
/* 1 byte for the no. of attributes searched till this response */
#define SDP_SSA_CONT_STATE_SIZE 2

#define SDP_INVALID 0xff

struct bt_sdp {
	struct bt_l2cap_br_chan chan;
	struct k_fifo           partial_resp_queue;
	/* TODO: Allow more than one pending request */
};

static struct bt_sdp_record *db;
static uint8_t num_services;

static struct bt_sdp bt_sdp_pool[CONFIG_BT_MAX_CONN];

/* Pool for outgoing SDP packets */
NET_BUF_POOL_FIXED_DEFINE(sdp_pool, CONFIG_BT_MAX_CONN,
			  BT_L2CAP_BUF_SIZE(SDP_MTU), 8, NULL);

#define SDP_CLIENT_CHAN(_ch) CONTAINER_OF(_ch, struct bt_sdp_client, chan.chan)

#define SDP_CLIENT_MTU 64

struct bt_sdp_client {
	struct bt_l2cap_br_chan              chan;
	/* list of waiting to be resolved UUID params */
	sys_slist_t                          reqs;
	/* required SDP transaction ID */
	uint16_t                                tid;
	/* UUID params holder being now resolved */
	const struct bt_sdp_discover_params *param;
	/* PDU continuation state object */
	struct bt_sdp_pdu_cstate             cstate;
	/* buffer for collecting record data */
	struct net_buf                      *rec_buf;
};

static struct bt_sdp_client bt_sdp_client_pool[CONFIG_BT_MAX_CONN];

enum {
	BT_SDP_ITER_STOP,
	BT_SDP_ITER_CONTINUE,
};

struct search_state {
	uint16_t att_list_size;
	uint8_t  current_svc;
	uint8_t  last_att;
	bool     pkt_full;
};

struct select_attrs_data {
	struct bt_sdp_record        *rec;
	struct net_buf              *rsp_buf;
	struct bt_sdp               *sdp;
	struct bt_sdp_data_elem_seq *seq;
	struct search_state         *state;
	uint32_t                       *filter;
	uint16_t                        max_att_len;
	uint16_t                        att_list_len;
	uint8_t                         cont_state_size;
	uint8_t                         num_filters;
	bool                         new_service;
};

/* @typedef bt_sdp_attr_func_t
 *  @brief SDP attribute iterator callback.
 *
 *  @param attr Attribute found.
 *  @param att_idx Index of the found attribute in the attribute database.
 *  @param user_data Data given.
 *
 *  @return BT_SDP_ITER_CONTINUE if should continue to the next attribute
 *  or BT_SDP_ITER_STOP to stop.
 */
typedef uint8_t (*bt_sdp_attr_func_t)(struct bt_sdp_attribute *attr,
				   uint8_t att_idx, void *user_data);

/* @typedef bt_sdp_svc_func_t
 * @brief SDP service record iterator callback.
 *
 * @param rec Service record found.
 * @param user_data Data given.
 *
 * @return BT_SDP_ITER_CONTINUE if should continue to the next service record
 *  or BT_SDP_ITER_STOP to stop.
 */
typedef uint8_t (*bt_sdp_svc_func_t)(struct bt_sdp_record *rec,
				  void *user_data);

/* @brief Callback for SDP connection
 *
 *  Gets called when an SDP connection is established
 *
 *  @param chan L2CAP channel
 *
 *  @return None
 */
static void bt_sdp_connected(struct bt_l2cap_chan *chan)
{
	struct bt_l2cap_br_chan *ch = CONTAINER_OF(chan,
						   struct bt_l2cap_br_chan,
						   chan);

	struct bt_sdp *sdp = CONTAINER_OF(ch, struct bt_sdp, chan);

	BT_DBG("chan %p cid 0x%04x", ch, ch->tx.cid);

	k_fifo_init(&sdp->partial_resp_queue);
}

/** @brief Callback for SDP disconnection
 *
 *  Gets called when an SDP connection is terminated
 *
 *  @param chan L2CAP channel
 *
 *  @return None
 */
static void bt_sdp_disconnected(struct bt_l2cap_chan *chan)
{
	struct bt_l2cap_br_chan *ch = CONTAINER_OF(chan,
						   struct bt_l2cap_br_chan,
						   chan);

	struct bt_sdp *sdp = CONTAINER_OF(ch, struct bt_sdp, chan);

	BT_DBG("chan %p cid 0x%04x", ch, ch->tx.cid);

	(void)memset(sdp, 0, sizeof(*sdp));
}

/* @brief Creates an SDP PDU
 *
 *  Creates an empty SDP PDU and returns the buffer
 *
 *  @param None
 *
 *  @return Pointer to the net_buf buffer
 */
static struct net_buf *bt_sdp_create_pdu(void)
{
	return bt_l2cap_create_pdu(&sdp_pool, sizeof(struct bt_sdp_hdr));
}

/* @brief Sends out an SDP PDU
 *
 *  Sends out an SDP PDU after adding the relevant header
 *
 *  @param chan L2CAP channel
 *  @param buf Buffer to be sent out
 *  @param op Opcode to be used in the packet header
 *  @param tid Transaction ID to be used in the packet header
 *
 *  @return None
 */
static int bt_sdp_send(struct bt_l2cap_chan *chan, struct net_buf *buf,
		       uint8_t op, uint16_t tid)
{
	struct bt_sdp_hdr *hdr;
	uint16_t param_len = buf->len;
	int err;

	hdr = net_buf_push(buf, sizeof(struct bt_sdp_hdr));
	hdr->op_code = op;
	hdr->tid = tid;
	hdr->param_len = sys_cpu_to_be16(param_len);

	err = bt_l2cap_chan_send(chan, buf);
	if (err < 0) {
		net_buf_unref(buf);
	}

	return err;
}

/* @brief Sends an error response PDU
 *
 *  Creates and sends an error response PDU
 *
 *  @param chan L2CAP channel
 *  @param err Error code to be sent in the packet
 *  @param tid Transaction ID to be used in the packet header
 *
 *  @return None
 */
static void send_err_rsp(struct bt_l2cap_chan *chan, uint16_t err,
			 uint16_t tid)
{
	struct net_buf *buf;

	BT_DBG("tid %u, error %u", tid, err);

	buf = bt_sdp_create_pdu();

	net_buf_add_be16(buf, err);

	bt_sdp_send(chan, buf, BT_SDP_ERROR_RSP, tid);
}

/* @brief Parses data elements from a net_buf
 *
 * Parses the first data element from a buffer and splits it into type, size,
 * data. Used for parsing incoming requests. Net buf is advanced to the data
 * part of the element.
 *
 * @param buf Buffer to be advanced
 * @param data_elem Pointer to the parsed data element structure
 *
 * @return 0 for success, or relevant error code
 */
static uint16_t parse_data_elem(struct net_buf *buf,
				struct bt_sdp_data_elem *data_elem)
{
	uint8_t size_field_len = 0U; /* Space used to accommodate the size */

	if (buf->len < 1) {
		BT_WARN("Malformed packet");
		return BT_SDP_INVALID_SYNTAX;
	}

	data_elem->type = net_buf_pull_u8(buf);

	switch (data_elem->type & BT_SDP_TYPE_DESC_MASK) {
	case BT_SDP_UINT8:
	case BT_SDP_INT8:
	case BT_SDP_UUID_UNSPEC:
	case BT_SDP_BOOL:
		data_elem->data_size = BIT(data_elem->type &
					   BT_SDP_SIZE_DESC_MASK);
		break;
	case BT_SDP_TEXT_STR_UNSPEC:
	case BT_SDP_SEQ_UNSPEC:
	case BT_SDP_ALT_UNSPEC:
	case BT_SDP_URL_STR_UNSPEC:
		size_field_len = BIT((data_elem->type & BT_SDP_SIZE_DESC_MASK) -
				     BT_SDP_SIZE_INDEX_OFFSET);
		if (buf->len < size_field_len) {
			BT_WARN("Malformed packet");
			return BT_SDP_INVALID_SYNTAX;
		}
		switch (size_field_len) {
		case 1:
			data_elem->data_size = net_buf_pull_u8(buf);
			break;
		case 2:
			data_elem->data_size = net_buf_pull_be16(buf);
			break;
		case 4:
			data_elem->data_size = net_buf_pull_be32(buf);
			break;
		default:
			BT_WARN("Invalid size in remote request");
			return BT_SDP_INVALID_SYNTAX;
		}
		break;
	default:
		BT_WARN("Invalid type in remote request");
		return BT_SDP_INVALID_SYNTAX;
	}

	if (buf->len < data_elem->data_size) {
		BT_WARN("Malformed packet");
		return BT_SDP_INVALID_SYNTAX;
	}

	data_elem->total_size = data_elem->data_size + size_field_len + 1;
	data_elem->data = buf->data;

	return 0;
}

/* @brief Searches for an UUID within an attribute
 *
 * Searches for an UUID within an attribute. If the attribute has data element
 * sequences, it recursively searches within them as well. On finding a match
 * with the UUID, it sets the found flag.
 *
 * @param elem Attribute to be used as the search space (haystack)
 * @param uuid UUID to be looked for (needle)
 * @param found Flag set to true if the UUID is found (to be returned)
 * @param nest_level Used to limit the extent of recursion into nested data
 *  elements, to avoid potential stack overflows
 *
 * @return Size of the last data element that has been searched
 *  (used in recursion)
 */
static uint32_t search_uuid(struct bt_sdp_data_elem *elem, struct bt_uuid *uuid,
			 bool *found, uint8_t nest_level)
{
	const uint8_t *cur_elem;
	uint32_t seq_size, size;
	union {
		struct bt_uuid uuid;
		struct bt_uuid_16 u16;
		struct bt_uuid_32 u32;
		struct bt_uuid_128 u128;
	} u;

	if (*found) {
		return 0;
	}

	/* Limit recursion depth to avoid stack overflows */
	if (nest_level == SDP_DATA_ELEM_NEST_LEVEL_MAX) {
		return 0;
	}

	seq_size = elem->data_size;
	cur_elem = elem->data;

	if ((elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_UUID_UNSPEC) {
		if (seq_size == 2U) {
			u.uuid.type = BT_UUID_TYPE_16;
			u.u16.val = *((uint16_t *)cur_elem);
			if (!bt_uuid_cmp(&u.uuid, uuid)) {
				*found = true;
			}
		} else if (seq_size == 4U) {
			u.uuid.type = BT_UUID_TYPE_32;
			u.u32.val = *((uint32_t *)cur_elem);
			if (!bt_uuid_cmp(&u.uuid, uuid)) {
				*found = true;
			}
		} else if (seq_size == 16U) {
			u.uuid.type = BT_UUID_TYPE_128;
			memcpy(u.u128.val, cur_elem, seq_size);
			if (!bt_uuid_cmp(&u.uuid, uuid)) {
				*found = true;
			}
		} else {
			BT_WARN("Invalid UUID size in local database");
			BT_ASSERT(0);
		}
	}

	if ((elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_SEQ_UNSPEC ||
	    (elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_ALT_UNSPEC) {
		do {
			/* Recursively parse data elements */
			size = search_uuid((struct bt_sdp_data_elem *)cur_elem,
					   uuid, found, nest_level + 1);
			if (*found) {
				return 0;
			}
			cur_elem += sizeof(struct bt_sdp_data_elem);
			seq_size -= size;
		} while (seq_size);
	}

	return elem->total_size;
}

/* @brief SDP service record iterator.
 *
 * Iterate over service records from a starting point.
 *
 * @param func Callback function.
 * @param user_data Data to pass to the callback.
 *
 * @return Pointer to the record where the iterator stopped, or NULL if all
 *  records are covered
 */
static struct bt_sdp_record *bt_sdp_foreach_svc(bt_sdp_svc_func_t func,
						void *user_data)
{
	struct bt_sdp_record *rec = db;

	while (rec) {
		if (func(rec, user_data) == BT_SDP_ITER_STOP) {
			break;
		}

		rec = rec->next;
	}
	return rec;
}

/* @brief Inserts a service record into a record pointer list
 *
 * Inserts a service record into a record pointer list
 *
 * @param rec The current service record.
 * @param user_data Pointer to the destination record list.
 *
 * @return BT_SDP_ITER_CONTINUE to move on to the next record.
 */
static uint8_t insert_record(struct bt_sdp_record *rec, void *user_data)
{
	struct bt_sdp_record **rec_list = user_data;

	rec_list[rec->index] = rec;

	return BT_SDP_ITER_CONTINUE;
}

/* @brief Looks for matching UUIDs in a list of service records
 *
 * Parses out a sequence of UUIDs from an input buffer, and checks if a record
 * in the list contains all the UUIDs. If it doesn't, the record is removed
 * from the list, so the list contains only the records which has all the
 * input UUIDs in them.
 *
 * @param buf Incoming buffer containing all the UUIDs to be matched
 * @param matching_recs List of service records to use for storing matching
 * records
 *
 * @return 0 for success, or relevant error code
 */
static uint16_t find_services(struct net_buf *buf,
			      struct bt_sdp_record **matching_recs)
{
	struct bt_sdp_data_elem data_elem;
	struct bt_sdp_record *record;
	uint32_t uuid_list_size;
	uint16_t res;
	uint8_t att_idx, rec_idx = 0U;
	bool found;
	union {
		struct bt_uuid uuid;
		struct bt_uuid_16 u16;
		struct bt_uuid_32 u32;
		struct bt_uuid_128 u128;
	} u;

	res = parse_data_elem(buf, &data_elem);
	if (res) {
		return res;
	}

	if (((data_elem.type & BT_SDP_TYPE_DESC_MASK) != BT_SDP_SEQ_UNSPEC) &&
	    ((data_elem.type & BT_SDP_TYPE_DESC_MASK) != BT_SDP_ALT_UNSPEC)) {
		BT_WARN("Invalid type %x in service search pattern",
			data_elem.type);
		return BT_SDP_INVALID_SYNTAX;
	}

	uuid_list_size = data_elem.data_size;

	bt_sdp_foreach_svc(insert_record, matching_recs);

	/* Go over the sequence of UUIDs, and match one UUID at a time */
	while (uuid_list_size) {
		res = parse_data_elem(buf, &data_elem);
		if (res) {
			return res;
		}

		if ((data_elem.type & BT_SDP_TYPE_DESC_MASK) !=
		    BT_SDP_UUID_UNSPEC) {
			BT_WARN("Invalid type %u in service search pattern",
				data_elem.type);
			return BT_SDP_INVALID_SYNTAX;
		}

		if (buf->len < data_elem.data_size) {
			BT_WARN("Malformed packet");
			return BT_SDP_INVALID_SYNTAX;
		}

		if (data_elem.data_size == 2U) {
			u.uuid.type = BT_UUID_TYPE_16;
			u.u16.val = net_buf_pull_be16(buf);
		} else if (data_elem.data_size == 4U) {
			u.uuid.type = BT_UUID_TYPE_32;
			u.u32.val = net_buf_pull_be32(buf);
		} else if (data_elem.data_size == 16U) {
			u.uuid.type = BT_UUID_TYPE_128;
			sys_memcpy_swap(u.u128.val, buf->data,
					data_elem.data_size);
			net_buf_pull(buf, data_elem.data_size);
		} else {
			BT_WARN("Invalid UUID len %u in service search pattern",
				data_elem.data_size);
			net_buf_pull(buf, data_elem.data_size);
		}

		uuid_list_size -= data_elem.total_size;

		/* Go over the list of services, and look for a service which
		 * doesn't have this UUID
		 */
		for (rec_idx = 0U; rec_idx < num_services; rec_idx++) {
			record = matching_recs[rec_idx];

			if (!record) {
				continue;
			}

			found = false;

			/* Search for the UUID in all the attrs of the svc */
			for (att_idx = 0U; att_idx < record->attr_count;
			     att_idx++) {
				search_uuid(&record->attrs[att_idx].val,
					    &u.uuid, &found, 1);
				if (found) {
					break;
				}
			}

			/* Remove the record from the list if it doesn't have
			 * the UUID
			 */
			if (!found) {
				matching_recs[rec_idx] = NULL;
			}
		}
	}

	return 0;
}

/* @brief Handler for Service Search Request
 *
 * Parses, processes and responds to a Service Search Request
 *
 * @param sdp Pointer to the SDP structure
 * @param buf Request net buf
 * @param tid Transaction ID
 *
 * @return 0 for success, or relevant error code
 */
static uint16_t sdp_svc_search_req(struct bt_sdp *sdp, struct net_buf *buf,
				uint16_t tid)
{
	struct bt_sdp_svc_rsp *rsp;
	struct net_buf *resp_buf;
	struct bt_sdp_record *record;
	struct bt_sdp_record *matching_recs[BT_SDP_MAX_SERVICES];
	uint16_t max_rec_count, total_recs = 0U, current_recs = 0U, res;
	uint8_t cont_state_size, cont_state = 0U, idx = 0U, count = 0U;
	bool pkt_full = false;

	res = find_services(buf, matching_recs);
	if (res) {
		/* Error in parsing */
		return res;
	}

	if (buf->len < 3) {
		BT_WARN("Malformed packet");
		return BT_SDP_INVALID_SYNTAX;
	}

	max_rec_count = net_buf_pull_be16(buf);
	cont_state_size = net_buf_pull_u8(buf);

	/* Zero out the matching services beyond max_rec_count */
	for (idx = 0U; idx < num_services; idx++) {
		if (count == max_rec_count) {
			matching_recs[idx] = NULL;
			continue;
		}

		if (matching_recs[idx]) {
			count++;
		}
	}

	/* We send out only SDP_SS_CONT_STATE_SIZE bytes continuation state in
	 * responses, so expect only SDP_SS_CONT_STATE_SIZE bytes in requests
	 */
	if (cont_state_size) {
		if (cont_state_size != SDP_SS_CONT_STATE_SIZE) {
			BT_WARN("Invalid cont state size %u", cont_state_size);
			return BT_SDP_INVALID_CSTATE;
		}

		if (buf->len < cont_state_size) {
			BT_WARN("Malformed packet");
			return BT_SDP_INVALID_SYNTAX;
		}

		cont_state = net_buf_pull_u8(buf);
		/* We include total_recs in the continuation state. We calculate
		 * it once and preserve it across all the partial responses
		 */
		total_recs = net_buf_pull_be16(buf);
	}

	BT_DBG("max_rec_count %u, cont_state %u", max_rec_count, cont_state);

	resp_buf = bt_sdp_create_pdu();
	rsp = net_buf_add(resp_buf, sizeof(*rsp));

	for (; cont_state < num_services; cont_state++) {
		record = matching_recs[cont_state];

		if (!record) {
			continue;
		}

		/* Calculate total recs only if it is first packet */
		if (!cont_state_size) {
			total_recs++;
		}

		if (pkt_full) {
			continue;
		}

		/* 4 bytes per Service Record Handle */
		/* 4 bytes for ContinuationState */
		if ((MIN(SDP_MTU, sdp->chan.tx.mtu) - resp_buf->len) <
		    (4 + 4 + sizeof(struct bt_sdp_hdr))) {
			pkt_full = true;
		}

		if (pkt_full) {
			/* Packet exhausted: Add continuation state and break */
			BT_DBG("Packet full, num_services_covered %u",
			       cont_state);
			net_buf_add_u8(resp_buf, SDP_SS_CONT_STATE_SIZE);
			net_buf_add_u8(resp_buf, cont_state);

			/* If it is the first packet of a partial response,
			 * continue dry-running to calculate total_recs.
			 * Else break
			 */
			if (cont_state_size) {
				break;
			}

			continue;
		}

		/* Add the service record handle to the packet */
		net_buf_add_be32(resp_buf, record->handle);
		current_recs++;
	}

	/* Add 0 continuation state if packet is exhausted */
	if (!pkt_full) {
		net_buf_add_u8(resp_buf, 0);
	} else {
		net_buf_add_be16(resp_buf, total_recs);
	}

	rsp->total_recs = sys_cpu_to_be16(total_recs);
	rsp->current_recs = sys_cpu_to_be16(current_recs);

	BT_DBG("Sending response, len %u", resp_buf->len);
	bt_sdp_send(&sdp->chan.chan, resp_buf, BT_SDP_SVC_SEARCH_RSP, tid);

	return 0;
}

/* @brief Copies an attribute into an outgoing buffer
 *
 *  Copies an attribute into a buffer. Recursively calls itself for complex
 *  attributes.
 *
 *  @param elem Attribute to be copied to the buffer
 *  @param buf Buffer where the attribute is to be copied
 *
 *  @return Size of the last data element that has been searched
 *  (used in recursion)
 */
static uint32_t copy_attribute(struct bt_sdp_data_elem *elem,
			    struct net_buf *buf, uint8_t nest_level)
{
	const uint8_t *cur_elem;
	uint32_t size, seq_size, total_size;

	/* Limit recursion depth to avoid stack overflows */
	if (nest_level == SDP_DATA_ELEM_NEST_LEVEL_MAX) {
		return 0;
	}

	seq_size = elem->data_size;
	total_size = elem->total_size;
	cur_elem = elem->data;

	/* Copy the header */
	net_buf_add_u8(buf, elem->type);

	switch (total_size - (seq_size + 1U)) {
	case 1:
		net_buf_add_u8(buf, elem->data_size);
		break;
	case 2:
		net_buf_add_be16(buf, elem->data_size);
		break;
	case 4:
		net_buf_add_be32(buf, elem->data_size);
		break;
	}

	/* Recursively parse (till the last element is not another data element)
	 * and then fill the elements
	 */
	if ((elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_SEQ_UNSPEC ||
	    (elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_ALT_UNSPEC) {
		do {
			size = copy_attribute((struct bt_sdp_data_elem *)
					      cur_elem, buf, nest_level + 1);
			cur_elem += sizeof(struct bt_sdp_data_elem);
			seq_size -= size;
		} while (seq_size);
	} else if ((elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_UINT8 ||
		   (elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_INT8 ||
		   (elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_UUID_UNSPEC) {
		if (seq_size == 1U) {
			net_buf_add_u8(buf, *((uint8_t *)elem->data));
		} else if (seq_size == 2U) {
			net_buf_add_be16(buf, *((uint16_t *)elem->data));
		} else if (seq_size == 4U) {
			net_buf_add_be32(buf, *((uint32_t *)elem->data));
		} else {
			/* TODO: Convert 32bit and 128bit values to big-endian*/
			net_buf_add_mem(buf, elem->data, seq_size);
		}
	} else {
		net_buf_add_mem(buf, elem->data, seq_size);
	}

	return total_size;
}

/* @brief SDP attribute iterator.
 *
 *  Iterate over attributes of a service record from a starting index.
 *
 *  @param record Service record whose attributes are to be iterated over.
 *  @param idx Index in the attribute list from where to start.
 *  @param func Callback function.
 *  @param user_data Data to pass to the callback.
 *
 *  @return Index of the attribute where the iterator stopped
 */
static uint8_t bt_sdp_foreach_attr(struct bt_sdp_record *record, uint8_t idx,
				bt_sdp_attr_func_t func, void *user_data)
{
	for (; idx < record->attr_count; idx++) {
		if (func(&record->attrs[idx], idx, user_data) ==
		    BT_SDP_ITER_STOP) {
			break;
		}
	}

	return idx;
}

/* @brief Check if an attribute matches a range, and include it in the response
 *
 *  Checks if an attribute matches a given attribute ID or range, and if so,
 *  includes it in the response packet
 *
 *  @param attr The current attribute
 *  @param att_idx Index of the current attribute in the database
 *  @param user_data Pointer to the structure containing response packet, byte
 *   count, states, etc
 *
 *  @return BT_SDP_ITER_CONTINUE if should continue to the next attribute
 *   or BT_SDP_ITER_STOP to stop.
 */
static uint8_t select_attrs(struct bt_sdp_attribute *attr, uint8_t att_idx,
			 void *user_data)
{
	struct select_attrs_data *sad = user_data;
	uint16_t att_id_lower, att_id_upper, att_id_cur, space;
	uint32_t attr_size, seq_size;
	uint8_t idx_filter;

	for (idx_filter = 0U; idx_filter < sad->num_filters; idx_filter++) {

		att_id_lower = (sad->filter[idx_filter] >> 16);
		att_id_upper = (sad->filter[idx_filter]);
		att_id_cur = attr->id;

		/* Check for range values */
		if (att_id_lower != 0xffff &&
		    (!IN_RANGE(att_id_cur, att_id_lower, att_id_upper))) {
			continue;
		}

		/* Check for match values */
		if (att_id_lower == 0xffff && att_id_cur != att_id_upper) {
			continue;
		}

		/* Attribute ID matches */

		/* 3 bytes for Attribute ID */
		attr_size = 3 + attr->val.total_size;

		/* If this is the first attribute of the service, then we need
		 * to account for the space required to add the per-service
		 * data element sequence header as well.
		 */
		if ((sad->state->current_svc != sad->rec->index) &&
		    sad->new_service) {
			/* 3 bytes for Per-Service Data Elem Seq declaration */
			seq_size = attr_size + 3;
		} else {
			seq_size = attr_size;
		}

		if (sad->rsp_buf) {
			space = MIN(SDP_MTU, sad->sdp->chan.tx.mtu) -
				sad->rsp_buf->len - sizeof(struct bt_sdp_hdr);

			if ((!sad->state->pkt_full) &&
			    ((seq_size > sad->max_att_len) ||
			     (space < seq_size + sad->cont_state_size))) {
				/* Packet exhausted */
				sad->state->pkt_full = true;
			}
		}

		/* Keep filling data only if packet is not exhausted */
		if (!sad->state->pkt_full && sad->rsp_buf) {
			/* Add Per-Service Data Element Seq declaration once
			 * only when we are starting from the first attribute
			 */
			if (!sad->seq &&
			    (sad->state->current_svc != sad->rec->index)) {
				sad->seq = net_buf_add(sad->rsp_buf,
						       sizeof(*sad->seq));
				sad->seq->type = BT_SDP_SEQ16;
				sad->seq->size = 0U;
			}

			/* Add attribute ID */
			net_buf_add_u8(sad->rsp_buf, BT_SDP_UINT16);
			net_buf_add_be16(sad->rsp_buf, att_id_cur);

			/* Add attribute value */
			copy_attribute(&attr->val, sad->rsp_buf, 1);

			sad->max_att_len -= seq_size;
			sad->att_list_len += seq_size;
			sad->state->last_att = att_idx;
			sad->state->current_svc = sad->rec->index;
		}

		if (sad->seq) {
			/* Keep adding the sequence size if this packet contains
			 * the Per-Service Data Element Seq declaration header
			 */
			sad->seq->size += attr_size;
			sad->state->att_list_size += seq_size;
		} else {
			/* Keep adding the total attr lists size if:
			 * It's a dry-run, calculating the total attr lists size
			 */
			sad->state->att_list_size += seq_size;
		}

		sad->new_service = false;
		break;
	}

	/* End the search if:
	 * 1. We have exhausted the packet
	 * AND
	 * 2. This packet doesn't contain the service element declaration header
	 * AND
	 * 3. This is not a dry-run (then we look for other attrs that match)
	 */
	if (sad->state->pkt_full && !sad->seq && sad->rsp_buf) {
		return BT_SDP_ITER_STOP;
	}

	return BT_SDP_ITER_CONTINUE;
}

/* @brief Creates attribute list in the given buffer
 *
 *  Populates the attribute list of a service record in the buffer. To be used
 *  for responding to Service Attribute and Service Search Attribute requests
 *
 *  @param sdp Pointer to the SDP structure
 *  @param record Service record whose attributes are to be included in the
 *   response
 *  @param filter Attribute values/ranges to be used as a filter
 *  @param num_filters Number of elements in the attribute filter
 *  @param max_att_len Maximum size of attributes to be included in the response
 *  @param cont_state_size No. of additional continuation state bytes to keep
 *   space for in the packet. This will vary based on the type of the request
 *  @param next_att Starting position of the search in the service's attr list
 *  @param state State of the overall search
 *  @param rsp_buf Response buffer which is filled in
 *
 *  @return len Length of the attribute list created
 */
static uint16_t create_attr_list(struct bt_sdp *sdp, struct bt_sdp_record *record,
			      uint32_t *filter, uint8_t num_filters,
			      uint16_t max_att_len, uint8_t cont_state_size,
			      uint8_t next_att, struct search_state *state,
			      struct net_buf *rsp_buf)
{
	struct select_attrs_data sad;
	uint8_t idx_att;

	sad.num_filters = num_filters;
	sad.rec = record;
	sad.rsp_buf = rsp_buf;
	sad.sdp = sdp;
	sad.max_att_len = max_att_len;
	sad.cont_state_size = cont_state_size;
	sad.seq = NULL;
	sad.filter = filter;
	sad.state = state;
	sad.att_list_len = 0U;
	sad.new_service = true;

	idx_att = bt_sdp_foreach_attr(sad.rec, next_att, select_attrs, &sad);

	if (sad.seq) {
		sad.seq->size = sys_cpu_to_be16(sad.seq->size);
	}

	return sad.att_list_len;
}

/* @brief Extracts the attribute search list from a buffer
 *
 *  Parses a buffer to extract the attribute search list (list of attribute IDs
 *  and ranges) which are to be used to filter attributes.
 *
 *  @param buf Buffer to be parsed for extracting the attribute search list
 *  @param filter Empty list of 4byte filters that are filled in. For attribute
 *   IDs, the lower 2 bytes contain the ID and the upper 2 bytes are set to
 *   0xFFFF. For attribute ranges, the lower 2bytes indicate the start ID and
 *   the upper 2bytes indicate the end ID
 *  @param num_filters No. of filter elements filled in (to be returned)
 *
 *  @return 0 for success, or relevant error code
 */
static uint16_t get_att_search_list(struct net_buf *buf, uint32_t *filter,
				 uint8_t *num_filters)
{
	struct bt_sdp_data_elem data_elem;
	uint16_t res;
	uint32_t size;

	*num_filters = 0U;
	res = parse_data_elem(buf, &data_elem);
	if (res) {
		return res;
	}

	size = data_elem.data_size;

	while (size) {
		res = parse_data_elem(buf, &data_elem);
		if (res) {
			return res;
		}

		if ((data_elem.type & BT_SDP_TYPE_DESC_MASK) != BT_SDP_UINT8) {
			BT_WARN("Invalid type %u in attribute ID list",
				data_elem.type);
			return BT_SDP_INVALID_SYNTAX;
		}

		if (buf->len < data_elem.data_size) {
			BT_WARN("Malformed packet");
			return BT_SDP_INVALID_SYNTAX;
		}

		/* This is an attribute ID */
		if (data_elem.data_size == 2U) {
			filter[(*num_filters)++] = 0xffff0000 |
							net_buf_pull_be16(buf);
		}

		/* This is an attribute ID range */
		if (data_elem.data_size == 4U) {
			filter[(*num_filters)++] = net_buf_pull_be32(buf);
		}

		size -= data_elem.total_size;
	}

	return 0;
}

/* @brief Check if a given handle matches that of the current service
 *
 *  Checks if a given handle matches that of the current service
 *
 *  @param rec The current service record
 *  @param user_data Pointer to the service record handle to be matched
 *
 *  @return BT_SDP_ITER_CONTINUE if should continue to the next record
 *   or BT_SDP_ITER_STOP to stop.
 */
static uint8_t find_handle(struct bt_sdp_record *rec, void *user_data)
{
	uint32_t *svc_rec_hdl = user_data;

	if (rec->handle == *svc_rec_hdl) {
		return BT_SDP_ITER_STOP;
	}

	return BT_SDP_ITER_CONTINUE;
}

/* @brief Handler for Service Attribute Request
 *
 *  Parses, processes and responds to a Service Attribute Request
 *
 *  @param sdp Pointer to the SDP structure
 *  @param buf Request buffer
 *  @param tid Transaction ID
 *
 *  @return 0 for success, or relevant error code
 */
static uint16_t sdp_svc_att_req(struct bt_sdp *sdp, struct net_buf *buf,
			     uint16_t tid)
{
	uint32_t filter[MAX_NUM_ATT_ID_FILTER];
	struct search_state state = {
		.current_svc = SDP_INVALID,
		.last_att = SDP_INVALID,
		.pkt_full = false
	};
	struct bt_sdp_record *record;
	struct bt_sdp_att_rsp *rsp;
	struct net_buf *rsp_buf;
	uint32_t svc_rec_hdl;
	uint16_t max_att_len, res, att_list_len;
	uint8_t num_filters, cont_state_size, next_att = 0U;

	if (buf->len < 6) {
		BT_WARN("Malformed packet");
		return BT_SDP_INVALID_SYNTAX;
	}

	svc_rec_hdl = net_buf_pull_be32(buf);
	max_att_len = net_buf_pull_be16(buf);

	/* Set up the filters */
	res = get_att_search_list(buf, filter, &num_filters);
	if (res) {
		/* Error in parsing */
		return res;
	}

	if (buf->len < 1) {
		BT_WARN("Malformed packet");
		return BT_SDP_INVALID_SYNTAX;
	}

	cont_state_size = net_buf_pull_u8(buf);

	/* We only send out 1 byte continuation state in responses,
	 * so expect only 1 byte in requests
	 */
	if (cont_state_size) {
		if (cont_state_size != SDP_SA_CONT_STATE_SIZE) {
			BT_WARN("Invalid cont state size %u", cont_state_size);
			return BT_SDP_INVALID_CSTATE;
		}

		if (buf->len < cont_state_size) {
			BT_WARN("Malformed packet");
			return BT_SDP_INVALID_SYNTAX;
		}

		state.last_att = net_buf_pull_u8(buf) + 1;
		next_att = state.last_att;
	}

	BT_DBG("svc_rec_hdl %u, max_att_len 0x%04x, cont_state %u", svc_rec_hdl,
	       max_att_len, next_att);

	/* Find the service */
	record = bt_sdp_foreach_svc(find_handle, &svc_rec_hdl);

	if (!record) {
		BT_WARN("Handle %u not found", svc_rec_hdl);
		return BT_SDP_INVALID_RECORD_HANDLE;
	}

	/* For partial responses, restore the search state */
	if (cont_state_size) {
		state.current_svc = record->index;
	}

	rsp_buf = bt_sdp_create_pdu();
	rsp = net_buf_add(rsp_buf, sizeof(*rsp));

	/* cont_state_size should include 1 byte header */
	att_list_len = create_attr_list(sdp, record, filter, num_filters,
					max_att_len, SDP_SA_CONT_STATE_SIZE + 1,
					next_att, &state, rsp_buf);

	if (!att_list_len) {
		/* For empty responses, add an empty data element sequence */
		net_buf_add_u8(rsp_buf, BT_SDP_SEQ8);
		net_buf_add_u8(rsp_buf, 0);
		att_list_len = 2U;
	}

	/* Add continuation state */
	if (state.pkt_full) {
		BT_DBG("Packet full, state.last_att %u", state.last_att);
		net_buf_add_u8(rsp_buf, 1);
		net_buf_add_u8(rsp_buf, state.last_att);
	} else {
		net_buf_add_u8(rsp_buf, 0);
	}

	rsp->att_list_len = sys_cpu_to_be16(att_list_len);

	BT_DBG("Sending response, len %u", rsp_buf->len);
	bt_sdp_send(&sdp->chan.chan, rsp_buf, BT_SDP_SVC_ATTR_RSP, tid);

	return 0;
}

/* @brief Handler for Service Search Attribute Request
 *
 *  Parses, processes and responds to a Service Search Attribute Request
 *
 *  @param sdp Pointer to the SDP structure
 *  @param buf Request buffer
 *  @param tid Transaction ID
 *
 *  @return 0 for success, or relevant error code
 */
static uint16_t sdp_svc_search_att_req(struct bt_sdp *sdp, struct net_buf *buf,
				    uint16_t tid)
{
	uint32_t filter[MAX_NUM_ATT_ID_FILTER];
	struct bt_sdp_record *matching_recs[BT_SDP_MAX_SERVICES];
	struct search_state state = {
		.att_list_size = 0,
		.current_svc = SDP_INVALID,
		.last_att = SDP_INVALID,
		.pkt_full = false
	};
	struct net_buf *rsp_buf, *rsp_buf_cpy;
	struct bt_sdp_record *record;
	struct bt_sdp_att_rsp *rsp;
	struct bt_sdp_data_elem_seq *seq = NULL;
	uint16_t max_att_len, res, att_list_len = 0U;
	uint8_t num_filters, cont_state_size, next_svc = 0U, next_att = 0U;
	bool dry_run = false;

	res = find_services(buf, matching_recs);
	if (res) {
		return res;
	}

	if (buf->len < 2) {
		BT_WARN("Malformed packet");
		return BT_SDP_INVALID_SYNTAX;
	}

	max_att_len = net_buf_pull_be16(buf);

	/* Set up the filters */
	res = get_att_search_list(buf, filter, &num_filters);

	if (res) {
		/* Error in parsing */
		return res;
	}

	if (buf->len < 1) {
		BT_WARN("Malformed packet");
		return BT_SDP_INVALID_SYNTAX;
	}

	cont_state_size = net_buf_pull_u8(buf);

	/* We only send out 2 bytes continuation state in responses,
	 * so expect only 2 bytes in requests
	 */
	if (cont_state_size) {
		if (cont_state_size != SDP_SSA_CONT_STATE_SIZE) {
			BT_WARN("Invalid cont state size %u", cont_state_size);
			return BT_SDP_INVALID_CSTATE;
		}

		if (buf->len < cont_state_size) {
			BT_WARN("Malformed packet");
			return BT_SDP_INVALID_SYNTAX;
		}

		state.current_svc = net_buf_pull_u8(buf);
		state.last_att = net_buf_pull_u8(buf) + 1;
		next_svc = state.current_svc;
		next_att = state.last_att;
	}

	BT_DBG("max_att_len 0x%04x, state.current_svc %u, state.last_att %u",
	       max_att_len, state.current_svc, state.last_att);

	rsp_buf = bt_sdp_create_pdu();

	rsp = net_buf_add(rsp_buf, sizeof(*rsp));

	/* Add headers only if this is not a partial response */
	if (!cont_state_size) {
		seq = net_buf_add(rsp_buf, sizeof(*seq));
		seq->type = BT_SDP_SEQ16;
		seq->size = 0U;

		/* 3 bytes for Outer Data Element Sequence declaration */
		att_list_len = 3U;
	}

	rsp_buf_cpy = rsp_buf;

	for (; next_svc < num_services; next_svc++) {
		record = matching_recs[next_svc];

		if (!record) {
			continue;
		}

		att_list_len += create_attr_list(sdp, record, filter,
						 num_filters, max_att_len,
						 SDP_SSA_CONT_STATE_SIZE + 1,
						 next_att, &state, rsp_buf_cpy);

		/* Check if packet is full and not dry run */
		if (state.pkt_full && !dry_run) {
			BT_DBG("Packet full, state.last_att %u",
			       state.last_att);
			dry_run = true;

			/* Add continuation state */
			net_buf_add_u8(rsp_buf, 2);
			net_buf_add_u8(rsp_buf, state.current_svc);
			net_buf_add_u8(rsp_buf, state.last_att);

			/* Break if it's not a partial response, else dry-run
			 * Dry run: Look for other services that match
			 */
			if (cont_state_size) {
				break;
			}

			rsp_buf_cpy = NULL;
		}

		next_att = 0U;
	}

	if (!dry_run) {
		if (!att_list_len) {
			/* For empty responses, add an empty data elem seq */
			net_buf_add_u8(rsp_buf, BT_SDP_SEQ8);
			net_buf_add_u8(rsp_buf, 0);
			att_list_len = 2U;
		}
		/* Search exhausted */
		net_buf_add_u8(rsp_buf, 0);
	}

	rsp->att_list_len = sys_cpu_to_be16(att_list_len);
	if (seq) {
		seq->size = sys_cpu_to_be16(state.att_list_size);
	}

	BT_DBG("Sending response, len %u", rsp_buf->len);
	bt_sdp_send(&sdp->chan.chan, rsp_buf, BT_SDP_SVC_SEARCH_ATTR_RSP,
		    tid);

	return 0;
}

static const struct {
	uint8_t  op_code;
	uint16_t  (*func)(struct bt_sdp *sdp, struct net_buf *buf, uint16_t tid);
} handlers[] = {
	{ BT_SDP_SVC_SEARCH_REQ, sdp_svc_search_req },
	{ BT_SDP_SVC_ATTR_REQ, sdp_svc_att_req },
	{ BT_SDP_SVC_SEARCH_ATTR_REQ, sdp_svc_search_att_req },
};

/* @brief Callback for SDP data receive
 *
 *  Gets called when an SDP PDU is received. Calls the corresponding handler
 *  based on the op code of the PDU.
 *
 *  @param chan L2CAP channel
 *  @param buf Received PDU
 *
 *  @return None
 */
static int bt_sdp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
{
	struct bt_l2cap_br_chan *ch = CONTAINER_OF(chan,
			struct bt_l2cap_br_chan, chan);
	struct bt_sdp *sdp = CONTAINER_OF(ch, struct bt_sdp, chan);
	struct bt_sdp_hdr *hdr;
	uint16_t err = BT_SDP_INVALID_SYNTAX;
	size_t i;

	BT_DBG("chan %p, ch %p, cid 0x%04x", chan, ch, ch->tx.cid);

	BT_ASSERT(sdp);

	if (buf->len < sizeof(*hdr)) {
		BT_ERR("Too small SDP PDU received");
		return 0;
	}

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
	BT_DBG("Received SDP code 0x%02x len %u", hdr->op_code, buf->len);

	if (sys_cpu_to_be16(hdr->param_len) != buf->len) {
		err = BT_SDP_INVALID_PDU_SIZE;
	} else {
		for (i = 0; i < ARRAY_SIZE(handlers); i++) {
			if (hdr->op_code != handlers[i].op_code) {
				continue;
			}

			err = handlers[i].func(sdp, buf, hdr->tid);
			break;
		}
	}

	if (err) {
		BT_WARN("SDP error 0x%02x", err);
		send_err_rsp(chan, err, hdr->tid);
	}

	return 0;
}

/* @brief Callback for SDP connection accept
 *
 *  Gets called when an incoming SDP connection needs to be authorized.
 *  Registers the L2CAP callbacks and allocates an SDP context to the connection
 *
 *  @param conn BT connection object
 *  @param chan L2CAP channel structure (to be returned)
 *
 *  @return 0 for success, or relevant error code
 */
static int bt_sdp_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
{
	static const struct bt_l2cap_chan_ops ops = {
		.connected = bt_sdp_connected,
		.disconnected = bt_sdp_disconnected,
		.recv = bt_sdp_recv,
	};
	int i;

	BT_DBG("conn %p", conn);

	for (i = 0; i < ARRAY_SIZE(bt_sdp_pool); i++) {
		struct bt_sdp *sdp = &bt_sdp_pool[i];

		if (sdp->chan.chan.conn) {
			continue;
		}

		sdp->chan.chan.ops = &ops;
		sdp->chan.rx.mtu = SDP_MTU;

		*chan = &sdp->chan.chan;

		return 0;
	}

	BT_ERR("No available SDP context for conn %p", conn);

	return -ENOMEM;
}

void bt_sdp_init(void)
{
	static struct bt_l2cap_server server = {
		.psm = SDP_PSM,
		.accept = bt_sdp_accept,
		.sec_level = BT_SECURITY_L0,
	};
	int res;

	res = bt_l2cap_br_server_register(&server);
	if (res) {
		BT_ERR("L2CAP server registration failed with error %d", res);
	}
}

int bt_sdp_register_service(struct bt_sdp_record *service)
{
	uint32_t handle = SDP_SERVICE_HANDLE_BASE;

	if (!service) {
		BT_ERR("No service record specified");
		return 0;
	}

	if (num_services == BT_SDP_MAX_SERVICES) {
		BT_ERR("Reached max allowed registrations");
		return -ENOMEM;
	}

	if (db) {
		handle = db->handle + 1;
	}

	service->next = db;
	service->index = num_services++;
	service->handle = handle;
	*((uint32_t *)(service->attrs[0].val.data)) = handle;
	db = service;

	BT_DBG("Service registered at %u", handle);

	return 0;
}

#define GET_PARAM(__node) \
	CONTAINER_OF(__node, struct bt_sdp_discover_params, _node)

/* ServiceSearchAttribute PDU, ref to BT Core 4.2, Vol 3, part B, 4.7.1 */
static int sdp_client_ssa_search(struct bt_sdp_client *session)
{
	const struct bt_sdp_discover_params *param;
	struct net_buf *buf;

	/*
	 * Select proper user params, if session->param is invalid it means
	 * getting new UUID from top of to be resolved params list. Otherwise
	 * the context is in a middle of partial SDP PDU responses and cached
	 * value from context can be used.
	 */
	if (!session->param) {
		param = GET_PARAM(sys_slist_peek_head(&session->reqs));
	} else {
		param = session->param;
	}

	if (!param) {
		BT_WARN("No UUIDs to be resolved on remote");
		return -EINVAL;
	}

	buf = bt_sdp_create_pdu();

	/* BT_SDP_SEQ8 means length of sequence is on additional next byte */
	net_buf_add_u8(buf, BT_SDP_SEQ8);

	switch (param->uuid->type) {
	case BT_UUID_TYPE_16:
		/* Seq length */
		net_buf_add_u8(buf, 0x03);
		/* Seq type */
		net_buf_add_u8(buf, BT_SDP_UUID16);
		/* Seq value */
		net_buf_add_be16(buf, BT_UUID_16(param->uuid)->val);
		break;
	case BT_UUID_TYPE_32:
		net_buf_add_u8(buf, 0x05);
		net_buf_add_u8(buf, BT_SDP_UUID32);
		net_buf_add_be32(buf, BT_UUID_32(param->uuid)->val);
		break;
	case BT_UUID_TYPE_128:
		net_buf_add_u8(buf, 0x11);
		net_buf_add_u8(buf, BT_SDP_UUID128);
		net_buf_add_mem(buf, BT_UUID_128(param->uuid)->val,
				ARRAY_SIZE(BT_UUID_128(param->uuid)->val));
		break;
	default:
		BT_ERR("Unknown UUID type %u", param->uuid->type);
		return -EINVAL;
	}

	/* Set attribute max bytes count to be returned from server */
	net_buf_add_be16(buf, BT_SDP_MAX_ATTR_LEN);
	/*
	 * Sequence definition where data is sequence of elements and where
	 * additional next byte points the size of elements within
	 */
	net_buf_add_u8(buf, BT_SDP_SEQ8);
	net_buf_add_u8(buf, 0x05);
	/* Data element definition for two following 16bits range elements */
	net_buf_add_u8(buf, BT_SDP_UINT32);
	/* Get all attributes. It enables filter out wanted only attributes */
	net_buf_add_be16(buf, 0x0000);
	net_buf_add_be16(buf, 0xffff);

	/*
	 * Update and validate PDU ContinuationState. Initial SSA Request has
	 * zero length continuation state since no interaction has place with
	 * server so far, otherwise use the original state taken from remote's
	 * last response PDU that is cached by SDP client context.
	 */
	if (session->cstate.length == 0U) {
		net_buf_add_u8(buf, 0x00);
	} else {
		net_buf_add_u8(buf, session->cstate.length);
		net_buf_add_mem(buf, session->cstate.data,
				session->cstate.length);
	}

	/* Update context param to the one being resolving now */
	session->param = param;
	session->tid++;

	return bt_sdp_send(&session->chan.chan, buf, BT_SDP_SVC_SEARCH_ATTR_REQ,
			   session->tid);
}

static void sdp_client_params_iterator(struct bt_sdp_client *session)
{
	struct bt_l2cap_chan *chan = &session->chan.chan;
	struct bt_sdp_discover_params *param, *tmp;

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&session->reqs, param, tmp, _node) {
		if (param != session->param) {
			continue;
		}

		BT_DBG("");

		/* Remove already checked UUID node */
		sys_slist_remove(&session->reqs, NULL, &param->_node);
		/* Invalidate cached param in context */
		session->param = NULL;
		/* Reset continuation state in current context */
		(void)memset(&session->cstate, 0, sizeof(session->cstate));

		/* Check if there's valid next UUID */
		if (!sys_slist_is_empty(&session->reqs)) {
			sdp_client_ssa_search(session);
			return;
		}

		/* No UUID items, disconnect channel */
		bt_l2cap_chan_disconnect(chan);
		break;
	}
}

static uint16_t sdp_client_get_total(struct bt_sdp_client *session,
				  struct net_buf *buf, uint16_t *total)
{
	uint16_t pulled;
	uint8_t seq;

	/*
	 * Pull value of total octets of all attributes available to be
	 * collected when response gets completed for given UUID. Such info can
	 * be get from the very first response frame after initial SSA request
	 * was sent. For subsequent calls related to the same SSA request input
	 * buf and in/out function parameters stays neutral.
	 */
	if (session->cstate.length == 0U) {
		seq = net_buf_pull_u8(buf);
		pulled = 1U;
		switch (seq) {
		case BT_SDP_SEQ8:
			*total = net_buf_pull_u8(buf);
			pulled += 1U;
			break;
		case BT_SDP_SEQ16:
			*total = net_buf_pull_be16(buf);
			pulled += 2U;
			break;
		default:
			BT_WARN("Sequence type 0x%02x not handled", seq);
			*total = 0U;
			break;
		}

		BT_DBG("Total %u octets of all attributes", *total);
	} else {
		pulled = 0U;
		*total = 0U;
	}

	return pulled;
}

static uint16_t get_record_len(struct net_buf *buf)
{
	uint16_t len;
	uint8_t seq;

	seq = net_buf_pull_u8(buf);

	switch (seq) {
	case BT_SDP_SEQ8:
		len = net_buf_pull_u8(buf);
		break;
	case BT_SDP_SEQ16:
		len = net_buf_pull_be16(buf);
		break;
	default:
		BT_WARN("Sequence type 0x%02x not handled", seq);
		len = 0U;
		break;
	}

	BT_DBG("Record len %u", len);

	return len;
}

enum uuid_state {
	UUID_NOT_RESOLVED,
	UUID_RESOLVED,
};

static void sdp_client_notify_result(struct bt_sdp_client *session,
				     enum uuid_state state)
{
	struct bt_conn *conn = session->chan.chan.conn;
	struct bt_sdp_client_result result;
	uint16_t rec_len;
	uint8_t user_ret;

	result.uuid = session->param->uuid;

	if (state == UUID_NOT_RESOLVED) {
		result.resp_buf = NULL;
		result.next_record_hint = false;
		session->param->func(conn, &result);
		return;
	}

	while (session->rec_buf->len) {
		struct net_buf_simple_state buf_state;

		rec_len = get_record_len(session->rec_buf);
		/* tell the user about multi record resolution */
		if (session->rec_buf->len > rec_len) {
			result.next_record_hint = true;
		} else {
			result.next_record_hint = false;
		}

		/* save the original session buffer */
		net_buf_simple_save(&session->rec_buf->b, &buf_state);
		/* initialize internal result buffer instead of memcpy */
		result.resp_buf = session->rec_buf;
		/*
		 * Set user internal result buffer length as same as record
		 * length to fake user. User will see the individual record
		 * length as rec_len insted of whole session rec_buf length.
		 */
		result.resp_buf->len = rec_len;

		user_ret = session->param->func(conn, &result);

		/* restore original session buffer */
		net_buf_simple_restore(&session->rec_buf->b, &buf_state);
		/*
		 * sync session buffer data length with next record chunk not
		 * send to user so far
		 */
		net_buf_pull(session->rec_buf, rec_len);
		if (user_ret == BT_SDP_DISCOVER_UUID_STOP) {
			break;
		}
	}
}

static int sdp_client_receive(struct bt_l2cap_chan *chan, struct net_buf *buf)
{
	struct bt_sdp_client *session = SDP_CLIENT_CHAN(chan);
	struct bt_sdp_hdr *hdr;
	struct bt_sdp_pdu_cstate *cstate;
	uint16_t len, tid, frame_len;
	uint16_t total;

	BT_DBG("session %p buf %p", session, buf);

	if (buf->len < sizeof(*hdr)) {
		BT_ERR("Too small SDP PDU");
		return 0;
	}

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
	if (hdr->op_code == BT_SDP_ERROR_RSP) {
		BT_INFO("Error SDP PDU response");
		return 0;
	}

	len = sys_be16_to_cpu(hdr->param_len);
	tid = sys_be16_to_cpu(hdr->tid);

	BT_DBG("SDP PDU tid %u len %u", tid, len);

	if (buf->len != len) {
		BT_ERR("SDP PDU length mismatch (%u != %u)", buf->len, len);
		return 0;
	}

	if (tid != session->tid) {
		BT_ERR("Mismatch transaction ID value in SDP PDU");
		return 0;
	}

	switch (hdr->op_code) {
	case BT_SDP_SVC_SEARCH_ATTR_RSP:
		/* Get number of attributes in this frame. */
		frame_len = net_buf_pull_be16(buf);
		/* Check valid buf len for attribute list and cont state */
		if (buf->len < frame_len + SDP_CONT_STATE_LEN_SIZE) {
			BT_ERR("Invalid frame payload length");
			return 0;
		}
		/* Check valid range of attributes length */
		if (frame_len < 2) {
			BT_ERR("Invalid attributes data length");
			return 0;
		}

		/* Get PDU continuation state */
		cstate = (struct bt_sdp_pdu_cstate *)(buf->data + frame_len);

		if (cstate->length > BT_SDP_MAX_PDU_CSTATE_LEN) {
			BT_ERR("Invalid SDP PDU Continuation State length %u",
			       cstate->length);
			return 0;
		}

		if ((frame_len + SDP_CONT_STATE_LEN_SIZE + cstate->length) >
		     buf->len) {
			BT_ERR("Invalid frame payload length");
			return 0;
		}

		/*
		 * No record found for given UUID. The check catches case when
		 * current response frame has Continuation State shortest and
		 * valid and this is the first response frame as well.
		 */
		if (frame_len == 2U && cstate->length == 0U &&
		    session->cstate.length == 0U) {
			BT_DBG("record for UUID 0x%s not found",
				bt_uuid_str(session->param->uuid));
			/* Call user UUID handler */
			sdp_client_notify_result(session, UUID_NOT_RESOLVED);
			net_buf_pull(buf, frame_len + sizeof(cstate->length));
			goto iterate;
		}

		/* Get total value of all attributes to be collected */
		frame_len -= sdp_client_get_total(session, buf, &total);

		if (total > net_buf_tailroom(session->rec_buf)) {
			BT_WARN("Not enough room for getting records data");
			goto iterate;
		}

		net_buf_add_mem(session->rec_buf, buf->data, frame_len);
		net_buf_pull(buf, frame_len);

		/*
		 * check if current response says there's next portion to be
		 * fetched
		 */
		if (cstate->length) {
			/* Cache original Continuation State in context */
			memcpy(&session->cstate, cstate,
			       sizeof(struct bt_sdp_pdu_cstate));

			net_buf_pull(buf, cstate->length +
				     sizeof(cstate->length));

			/* Request for next portion of attributes data */
			sdp_client_ssa_search(session);
			break;
		}

		net_buf_pull(buf, sizeof(cstate->length));

		BT_DBG("UUID 0x%s resolved", bt_uuid_str(session->param->uuid));
		sdp_client_notify_result(session, UUID_RESOLVED);
iterate:
		/* Get next UUID and start resolving it */
		sdp_client_params_iterator(session);
		break;
	default:
		BT_DBG("PDU 0x%0x response not handled", hdr->op_code);
		break;
	}

	return 0;
}

static int sdp_client_chan_connect(struct bt_sdp_client *session)
{
	return bt_l2cap_br_chan_connect(session->chan.chan.conn,
					&session->chan.chan, SDP_PSM);
}

static struct net_buf *sdp_client_alloc_buf(struct bt_l2cap_chan *chan)
{
	struct bt_sdp_client *session = SDP_CLIENT_CHAN(chan);
	struct net_buf *buf;

	BT_DBG("session %p chan %p", session, chan);

	session->param = GET_PARAM(sys_slist_peek_head(&session->reqs));

	buf = net_buf_alloc(session->param->pool, K_FOREVER);
	__ASSERT_NO_MSG(buf);

	return buf;
}

static void sdp_client_connected(struct bt_l2cap_chan *chan)
{
	struct bt_sdp_client *session = SDP_CLIENT_CHAN(chan);

	BT_DBG("session %p chan %p connected", session, chan);

	session->rec_buf = chan->ops->alloc_buf(chan);

	sdp_client_ssa_search(session);
}

static void sdp_client_disconnected(struct bt_l2cap_chan *chan)
{
	struct bt_sdp_client *session = SDP_CLIENT_CHAN(chan);

	BT_DBG("session %p chan %p disconnected", session, chan);

	net_buf_unref(session->rec_buf);

	/*
	 * Reset session excluding L2CAP channel member. Let's the channel
	 * resets autonomous.
	 */
	(void)memset(&session->reqs, 0,
		     sizeof(*session) - sizeof(session->chan));
}

static const struct bt_l2cap_chan_ops sdp_client_chan_ops = {
		.connected = sdp_client_connected,
		.disconnected = sdp_client_disconnected,
		.recv = sdp_client_receive,
		.alloc_buf = sdp_client_alloc_buf,
};

static struct bt_sdp_client *sdp_client_new_session(struct bt_conn *conn)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_sdp_client_pool); i++) {
		struct bt_sdp_client *session = &bt_sdp_client_pool[i];
		int err;

		if (session->chan.chan.conn) {
			continue;
		}

		sys_slist_init(&session->reqs);

		session->chan.chan.ops = &sdp_client_chan_ops;
		session->chan.chan.conn = conn;
		session->chan.rx.mtu = SDP_CLIENT_MTU;

		err = sdp_client_chan_connect(session);
		if (err) {
			(void)memset(session, 0, sizeof(*session));
			BT_ERR("Cannot connect %d", err);
			return NULL;
		}

		return session;
	}

	BT_ERR("No available SDP client context");

	return NULL;
}

static struct bt_sdp_client *sdp_client_get_session(struct bt_conn *conn)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(bt_sdp_client_pool); i++) {
		if (bt_sdp_client_pool[i].chan.chan.conn == conn) {
			return &bt_sdp_client_pool[i];
		}
	}

	/*
	 * Try to allocate session context since not found in pool and attempt
	 * connect to remote SDP endpoint.
	 */
	return sdp_client_new_session(conn);
}

int bt_sdp_discover(struct bt_conn *conn,
		    const struct bt_sdp_discover_params *params)
{
	struct bt_sdp_client *session;

	if (!params || !params->uuid || !params->func || !params->pool) {
		BT_WARN("Invalid user params");
		return -EINVAL;
	}

	session = sdp_client_get_session(conn);
	if (!session) {
		return -ENOMEM;
	}

	sys_slist_append(&session->reqs, (sys_snode_t *)&params->_node);

	return 0;
}

/* Helper getting length of data determined by DTD for integers */
static inline ssize_t sdp_get_int_len(const uint8_t *data, size_t len)
{
	BT_ASSERT(data);

	switch (data[0]) {
	case BT_SDP_DATA_NIL:
		return 1;
	case BT_SDP_BOOL:
	case BT_SDP_INT8:
	case BT_SDP_UINT8:
		if (len < 2) {
			break;
		}

		return 2;
	case BT_SDP_INT16:
	case BT_SDP_UINT16:
		if (len < 3) {
			break;
		}

		return 3;
	case BT_SDP_INT32:
	case BT_SDP_UINT32:
		if (len < 5) {
			break;
		}

		return 5;
	case BT_SDP_INT64:
	case BT_SDP_UINT64:
		if (len < 9) {
			break;
		}

		return 9;
	case BT_SDP_INT128:
	case BT_SDP_UINT128:
	default:
		BT_ERR("Invalid/unhandled DTD 0x%02x", data[0]);
		return -EINVAL;
	}

	BT_ERR("Too short buffer length %zu", len);
	return -EMSGSIZE;
}

/* Helper getting length of data determined by DTD for UUID */
static inline ssize_t sdp_get_uuid_len(const uint8_t *data, size_t len)
{
	BT_ASSERT(data);

	switch (data[0]) {
	case BT_SDP_UUID16:
		if (len < 3) {
			break;
		}

		return 3;
	case BT_SDP_UUID32:
		if (len < 5) {
			break;
		}

		return 5;
	case BT_SDP_UUID128:
	default:
		BT_ERR("Invalid/unhandled DTD 0x%02x", data[0]);
		return -EINVAL;
	}

	BT_ERR("Too short buffer length %zu", len);
	return -EMSGSIZE;
}

/* Helper getting length of data determined by DTD for strings */
static inline ssize_t sdp_get_str_len(const uint8_t *data, size_t len)
{
	const uint8_t *pnext;

	BT_ASSERT(data);

	/* validate len for pnext safe use to read next 8bit value */
	if (len < 2) {
		goto err;
	}

	pnext = data + sizeof(uint8_t);

	switch (data[0]) {
	case BT_SDP_TEXT_STR8:
	case BT_SDP_URL_STR8:
		if (len < (2 + pnext[0])) {
			break;
		}

		return 2 + pnext[0];
	case BT_SDP_TEXT_STR16:
	case BT_SDP_URL_STR16:
		/* validate len for pnext safe use to read 16bit value */
		if (len < 3) {
			break;
		}

		if (len < (3 + sys_get_be16(pnext))) {
			break;
		}

		return 3 + sys_get_be16(pnext);
	case BT_SDP_TEXT_STR32:
	case BT_SDP_URL_STR32:
	default:
		BT_ERR("Invalid/unhandled DTD 0x%02x", data[0]);
		return -EINVAL;
	}
err:
	BT_ERR("Too short buffer length %zu", len);
	return -EMSGSIZE;
}

/* Helper getting length of data determined by DTD for sequences */
static inline ssize_t sdp_get_seq_len(const uint8_t *data, size_t len)
{
	const uint8_t *pnext;

	BT_ASSERT(data);

	/* validate len for pnext safe use to read 8bit bit value */
	if (len < 2) {
		goto err;
	}

	pnext = data + sizeof(uint8_t);

	switch (data[0]) {
	case BT_SDP_SEQ8:
	case BT_SDP_ALT8:
		if (len < (2 + pnext[0])) {
			break;
		}

		return 2 + pnext[0];
	case BT_SDP_SEQ16:
	case BT_SDP_ALT16:
		/* validate len for pnext safe use to read 16bit value */
		if (len < 3) {
			break;
		}

		if (len < (3 + sys_get_be16(pnext))) {
			break;
		}

		return 3 + sys_get_be16(pnext);
	case BT_SDP_SEQ32:
	case BT_SDP_ALT32:
	default:
		BT_ERR("Invalid/unhandled DTD 0x%02x", data[0]);
		return -EINVAL;
	}
err:
	BT_ERR("Too short buffer length %zu", len);
	return -EMSGSIZE;
}

/* Helper getting length of attribute value data */
static ssize_t sdp_get_attr_value_len(const uint8_t *data, size_t len)
{
	BT_ASSERT(data);

	BT_DBG("Attr val DTD 0x%02x", data[0]);

	if (len < 1) {
		goto err;
	}

	switch (data[0]) {
	case BT_SDP_DATA_NIL:
	case BT_SDP_BOOL:
	case BT_SDP_UINT8:
	case BT_SDP_UINT16:
	case BT_SDP_UINT32:
	case BT_SDP_UINT64:
	case BT_SDP_UINT128:
	case BT_SDP_INT8:
	case BT_SDP_INT16:
	case BT_SDP_INT32:
	case BT_SDP_INT64:
	case BT_SDP_INT128:
		return sdp_get_int_len(data, len);
	case BT_SDP_UUID16:
	case BT_SDP_UUID32:
	case BT_SDP_UUID128:
		return sdp_get_uuid_len(data, len);
	case BT_SDP_TEXT_STR8:
	case BT_SDP_TEXT_STR16:
	case BT_SDP_TEXT_STR32:
	case BT_SDP_URL_STR8:
	case BT_SDP_URL_STR16:
	case BT_SDP_URL_STR32:
		return sdp_get_str_len(data, len);
	case BT_SDP_SEQ8:
	case BT_SDP_SEQ16:
	case BT_SDP_SEQ32:
	case BT_SDP_ALT8:
	case BT_SDP_ALT16:
	case BT_SDP_ALT32:
		return sdp_get_seq_len(data, len);
	default:
		BT_ERR("Unknown DTD 0x%02x", data[0]);
		return -EINVAL;
	}
err:
	BT_ERR("Too short buffer length %zu", len);
	return -EMSGSIZE;

}

/* Type holding UUID item and related to it specific information. */
struct bt_sdp_uuid_desc {
	union {
		struct bt_uuid    uuid;
		struct bt_uuid_16 uuid16;
		struct bt_uuid_32 uuid32;
	      };
	uint16_t                     attr_id;
	uint8_t                     *params;
	uint16_t                     params_len;
};

/* Generic attribute item collector. */
struct bt_sdp_attr_item {
	/*  Attribute identifier. */
	uint16_t                  attr_id;
	/*  Address of beginning attribute value taken from original buffer
	 *  holding response from server.
	 */
	uint8_t                  *val;
	/*  Says about the length of attribute value. */
	uint16_t                  len;
};

static int bt_sdp_get_attr(const struct net_buf *buf,
			   struct bt_sdp_attr_item *attr, uint16_t attr_id)
{
	uint8_t *data;
	uint16_t id;

	data = buf->data;
	while (data - buf->data < buf->len) {
		ssize_t dlen;

		/* data need to point to attribute id descriptor field (DTD)*/
		if (data[0] != BT_SDP_UINT16) {
			BT_ERR("Invalid descriptor 0x%02x", data[0]);
			return -EINVAL;
		}

		data += sizeof(uint8_t);
		if ((data + sizeof(id) - buf->data) > buf->len) {
			return -EINVAL;
		}
		id = sys_get_be16(data);
		BT_DBG("Attribute ID 0x%04x", id);
		data += sizeof(uint16_t);

		dlen = sdp_get_attr_value_len(data,
					      buf->len - (data - buf->data));
		if (dlen < 0) {
			BT_ERR("Invalid attribute value data");
			return -EINVAL;
		}

		if (id == attr_id) {
			BT_DBG("Attribute ID 0x%04x Value found", id);
			/*
			 * Initialize attribute value buffer data using selected
			 * data slice from original buffer.
			 */
			attr->val = data;
			attr->len = dlen;
			attr->attr_id = id;
			return 0;
		}

		data += dlen;
	}

	return -ENOENT;
}

/* reads SEQ item length, moves input buffer data reader forward */
static ssize_t sdp_get_seq_len_item(uint8_t **data, size_t len)
{
	const uint8_t *pnext;

	BT_ASSERT(data);
	BT_ASSERT(*data);

	/* validate len for pnext safe use to read 8bit bit value */
	if (len < 2) {
		goto err;
	}

	pnext = *data + sizeof(uint8_t);

	switch (*data[0]) {
	case BT_SDP_SEQ8:
		if (len < (2 + pnext[0])) {
			break;
		}

		*data += 2;
		return pnext[0];
	case BT_SDP_SEQ16:
		/* validate len for pnext safe use to read 16bit value */
		if (len < 3) {
			break;
		}

		if (len < (3 + sys_get_be16(pnext))) {
			break;
		}

		*data += 3;
		return sys_get_be16(pnext);
	case BT_SDP_SEQ32:
		/* validate len for pnext safe use to read 32bit value */
		if (len < 5) {
			break;
		}

		if (len < (5 + sys_get_be32(pnext))) {
			break;
		}

		*data += 5;
		return sys_get_be32(pnext);
	default:
		BT_ERR("Invalid/unhandled DTD 0x%02x", *data[0]);
		return -EINVAL;
	}
err:
	BT_ERR("Too short buffer length %zu", len);
	return -EMSGSIZE;
}

static int sdp_loop_seqs(uint8_t **data, size_t len)
{
	ssize_t slen;
	ssize_t pre_slen;
	uint8_t *end;

	if (len <= 0) {
		return -EMSGSIZE;
	}

	pre_slen = -EINVAL;
	slen = -EINVAL;
	end = *data + len;
	/* loop all the SEQ */
	while (*data < end) {
		/* how long is current UUID's item data associated to */
		slen = sdp_get_seq_len_item(data, end - *data);
		if (slen < 0) {
			break;
		}
		pre_slen = slen;
	}

	/* return the last seq len */
	if (pre_slen < 0) {
		return slen;
	}

	return pre_slen;
}

static int sdp_get_uuid_data(const struct bt_sdp_attr_item *attr,
			     struct bt_sdp_uuid_desc *pd,
			     uint16_t proto_profile,
			     uint8_t proto_profile_index)
{
	/* get start address of attribute value */
	uint8_t *p = attr->val;
	ssize_t slen;

	BT_ASSERT(p);

	/* start reading stacked UUIDs in analyzed sequences tree */
	while (p - attr->val < attr->len) {
		size_t to_end, left = 0;
		uint8_t dtd;

		/* to_end tells how far to the end of input buffer */
		to_end = attr->len - (p - attr->val);
		/* loop all the SEQ, get the last SEQ len */
		slen = sdp_loop_seqs(&p, to_end);

		if (slen < 0) {
			return slen;
		}

		/* left tells how far is to the end of current UUID */
		left = slen;

		/* check if at least DTD + UUID16 can be read safely */
		if (left < (sizeof(dtd) + BT_UUID_SIZE_16)) {
			return -EMSGSIZE;
		}

		/* check DTD and get stacked UUID value */
		dtd = p[0];
		p++;
		/* include last DTD in p[0] size itself updating left */
		left -= sizeof(dtd);
		switch (dtd) {
		case BT_SDP_UUID16:
			memcpy(&pd->uuid16,
				BT_UUID_DECLARE_16(sys_get_be16(p)),
				sizeof(struct bt_uuid_16));
			p += sizeof(uint16_t);
			left -= sizeof(uint16_t);
			break;
		case BT_SDP_UUID32:
			/* check if valid UUID32 can be read safely */
			if (left < BT_UUID_SIZE_32) {
				return -EMSGSIZE;
			}

			memcpy(&pd->uuid32,
				BT_UUID_DECLARE_32(sys_get_be32(p)),
				sizeof(struct bt_uuid_32));
			p += sizeof(BT_UUID_SIZE_32);
			left -= sizeof(BT_UUID_SIZE_32);
			break;
		default:
			BT_ERR("Invalid/unhandled DTD 0x%02x\n", dtd);
			return -EINVAL;
		}

		/*
			* Check if current UUID value matches input one given by user.
			* If found save it's location and length and return.
			*/
		if ((proto_profile == BT_UUID_16(&pd->uuid)->val) ||
			(proto_profile == BT_UUID_32(&pd->uuid)->val)) {
			pd->params = p;
			pd->params_len = left;

			BT_DBG("UUID 0x%s found", bt_uuid_str(&pd->uuid));
			if (proto_profile_index > 0U) {
				proto_profile_index--;
				p += left;
				continue;
			} else {
				return 0;
			}
		}

		/* skip left octets to point beginning of next UUID in tree */
		p += left;
	}

	BT_DBG("Value 0x%04x index %d not found", proto_profile, proto_profile_index);
	return -ENOENT;
}

/*
 * Helper extracting specific parameters associated with UUID node given in
 * protocol descriptor list or profile descriptor list.
 */
static int sdp_get_param_item(struct bt_sdp_uuid_desc *pd_item, uint16_t *param)
{
	const uint8_t *p = pd_item->params;
	bool len_err = false;

	BT_ASSERT(p);

	BT_DBG("Getting UUID's 0x%s params", bt_uuid_str(&pd_item->uuid));

	switch (p[0]) {
	case BT_SDP_UINT8:
		/* check if 8bits value can be read safely */
		if (pd_item->params_len < 2) {
			len_err = true;
			break;
		}
		*param = (++p)[0];
		p += sizeof(uint8_t);
		break;
	case BT_SDP_UINT16:
		/* check if 16bits value can be read safely */
		if (pd_item->params_len < 3) {
			len_err = true;
			break;
		}
		*param = sys_get_be16(++p);
		p += sizeof(uint16_t);
		break;
	case BT_SDP_UINT32:
		/* check if 32bits value can be read safely */
		if (pd_item->params_len < 5) {
			len_err = true;
			break;
		}
		*param = sys_get_be32(++p);
		p += sizeof(uint32_t);
		break;
	default:
		BT_ERR("Invalid/unhandled DTD 0x%02x\n", p[0]);
		return -EINVAL;
	}
	/*
	 * Check if no more data than already read is associated with UUID. In
	 * valid case after getting parameter we should reach data buf end.
	 */
	if (p - pd_item->params != pd_item->params_len || len_err) {
		BT_DBG("Invalid param buffer length");
		return -EMSGSIZE;
	}

	return 0;
}

int bt_sdp_get_proto_param(const struct net_buf *buf, enum bt_sdp_proto proto,
			   uint16_t *param)
{
	struct bt_sdp_attr_item attr;
	struct bt_sdp_uuid_desc pd;
	int res;

	if (proto != BT_SDP_PROTO_RFCOMM && proto != BT_SDP_PROTO_L2CAP) {
		BT_ERR("Invalid protocol specifier");
		return -EINVAL;
	}

	res = bt_sdp_get_attr(buf, &attr, BT_SDP_ATTR_PROTO_DESC_LIST);
	if (res < 0) {
		BT_WARN("Attribute 0x%04x not found, err %d",
			BT_SDP_ATTR_PROTO_DESC_LIST, res);
		return res;
	}

	res = sdp_get_uuid_data(&attr, &pd, proto, 0U);
	if (res < 0) {
		BT_WARN("Protocol specifier 0x%04x not found, err %d", proto,
			res);
		return res;
	}

	return sdp_get_param_item(&pd, param);
}

int bt_sdp_get_addl_proto_param(const struct net_buf *buf, enum bt_sdp_proto proto,
				uint8_t param_index, uint16_t *param)
{
	struct bt_sdp_attr_item attr;
	struct bt_sdp_uuid_desc pd;
	int res;

	if (proto != BT_SDP_PROTO_RFCOMM && proto != BT_SDP_PROTO_L2CAP) {
		BT_ERR("Invalid protocol specifier");
		return -EINVAL;
	}

	res = bt_sdp_get_attr(buf, &attr, BT_SDP_ATTR_ADD_PROTO_DESC_LIST);
	if (res < 0) {
		BT_WARN("Attribute 0x%04x not found, err %d",
			BT_SDP_ATTR_PROTO_DESC_LIST, res);
		return res;
	}

	res = sdp_get_uuid_data(&attr, &pd, proto, param_index);
	if (res < 0) {
		BT_WARN("Protocol specifier 0x%04x not found, err %d", proto,
			res);
		return res;
	}

	return sdp_get_param_item(&pd, param);
}

int bt_sdp_get_profile_version(const struct net_buf *buf, uint16_t profile,
			       uint16_t *version)
{
	struct bt_sdp_attr_item attr;
	struct bt_sdp_uuid_desc pd;
	int res;

	res = bt_sdp_get_attr(buf, &attr, BT_SDP_ATTR_PROFILE_DESC_LIST);
	if (res < 0) {
		BT_WARN("Attribute 0x%04x not found, err %d",
			BT_SDP_ATTR_PROFILE_DESC_LIST, res);
		return res;
	}

	res = sdp_get_uuid_data(&attr, &pd, profile, 0U);
	if (res < 0) {
		BT_WARN("Profile 0x%04x not found, err %d", profile, res);
		return res;
	}

	return sdp_get_param_item(&pd, version);
}

int bt_sdp_get_features(const struct net_buf *buf, uint16_t *features)
{
	struct bt_sdp_attr_item attr;
	const uint8_t *p;
	int res;

	res = bt_sdp_get_attr(buf, &attr, BT_SDP_ATTR_SUPPORTED_FEATURES);
	if (res < 0) {
		BT_WARN("Attribute 0x%04x not found, err %d",
			BT_SDP_ATTR_SUPPORTED_FEATURES, res);
		return res;
	}

	p = attr.val;
	BT_ASSERT(p);

	if (p[0] != BT_SDP_UINT16) {
		BT_ERR("Invalid DTD 0x%02x", p[0]);
		return -EINVAL;
	}

	/* assert 16bit can be read safely */
	if (attr.len < 3) {
		BT_ERR("Data length too short %u", attr.len);
		return -EMSGSIZE;
	}

	*features = sys_get_be16(++p);
	p += sizeof(uint16_t);

	if (p - attr.val != attr.len) {
		BT_ERR("Invalid data length %u", attr.len);
		return -EMSGSIZE;
	}

	return 0;
}
