/** @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 <zephyr/sys/byteorder.h>
#include <zephyr/sys/__assert.h>

#include <zephyr/bluetooth/buf.h>
#include <zephyr/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 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 instead 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;
}
