1 /** @file
2  *  @brief Service Discovery Protocol handling.
3  */
4 
5 /*
6  * Copyright (c) 2016 Intel Corporation
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #include <errno.h>
12 #include <sys/types.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <zephyr/sys/__assert.h>
15 
16 #include <zephyr/bluetooth/buf.h>
17 #include <zephyr/bluetooth/sdp.h>
18 
19 #include "common/bt_str.h"
20 #include "common/assert.h"
21 
22 #include "hci_core.h"
23 #include "conn_internal.h"
24 #include "l2cap_internal.h"
25 #include "sdp_internal.h"
26 
27 #define LOG_LEVEL CONFIG_BT_SDP_LOG_LEVEL
28 #include <zephyr/logging/log.h>
29 LOG_MODULE_REGISTER(bt_sdp);
30 
31 #define SDP_PSM 0x0001
32 
33 #define SDP_CHAN(_ch) CONTAINER_OF(_ch, struct bt_sdp, chan.chan)
34 
35 #define SDP_DATA_MTU 200
36 
37 #define SDP_MTU (SDP_DATA_MTU + sizeof(struct bt_sdp_hdr))
38 
39 #define MAX_NUM_ATT_ID_FILTER 10
40 
41 #define SDP_SERVICE_HANDLE_BASE 0x10000
42 
43 #define SDP_DATA_ELEM_NEST_LEVEL_MAX 5
44 
45 /* Size of Cont state length */
46 #define SDP_CONT_STATE_LEN_SIZE 1
47 
48 /* 1 byte for the no. of services searched till this response */
49 /* 2 bytes for the total no. of matching records */
50 #define SDP_SS_CONT_STATE_SIZE 3
51 
52 /* 1 byte for the no. of attributes searched till this response */
53 #define SDP_SA_CONT_STATE_SIZE 1
54 
55 /* 1 byte for the no. of services searched till this response */
56 /* 1 byte for the no. of attributes searched till this response */
57 #define SDP_SSA_CONT_STATE_SIZE 2
58 
59 #define SDP_INVALID 0xff
60 
61 struct bt_sdp {
62 	struct bt_l2cap_br_chan chan;
63 	struct k_fifo           partial_resp_queue;
64 	/* TODO: Allow more than one pending request */
65 };
66 
67 static struct bt_sdp_record *db;
68 static uint8_t num_services;
69 
70 static struct bt_sdp bt_sdp_pool[CONFIG_BT_MAX_CONN];
71 
72 /* Pool for outgoing SDP packets */
73 NET_BUF_POOL_FIXED_DEFINE(sdp_pool, CONFIG_BT_MAX_CONN,
74 			  BT_L2CAP_BUF_SIZE(SDP_MTU), 8, NULL);
75 
76 #define SDP_CLIENT_CHAN(_ch) CONTAINER_OF(_ch, struct bt_sdp_client, chan.chan)
77 
78 #define SDP_CLIENT_MTU 64
79 
80 struct bt_sdp_client {
81 	struct bt_l2cap_br_chan              chan;
82 	/* list of waiting to be resolved UUID params */
83 	sys_slist_t                          reqs;
84 	/* required SDP transaction ID */
85 	uint16_t                                tid;
86 	/* UUID params holder being now resolved */
87 	const struct bt_sdp_discover_params *param;
88 	/* PDU continuation state object */
89 	struct bt_sdp_pdu_cstate             cstate;
90 	/* buffer for collecting record data */
91 	struct net_buf                      *rec_buf;
92 };
93 
94 static struct bt_sdp_client bt_sdp_client_pool[CONFIG_BT_MAX_CONN];
95 
96 enum {
97 	BT_SDP_ITER_STOP,
98 	BT_SDP_ITER_CONTINUE,
99 };
100 
101 struct search_state {
102 	uint16_t att_list_size;
103 	uint8_t  current_svc;
104 	uint8_t  last_att;
105 	bool     pkt_full;
106 };
107 
108 struct select_attrs_data {
109 	struct bt_sdp_record        *rec;
110 	struct net_buf              *rsp_buf;
111 	struct bt_sdp               *sdp;
112 	struct bt_sdp_data_elem_seq *seq;
113 	struct search_state         *state;
114 	uint32_t                       *filter;
115 	uint16_t                        max_att_len;
116 	uint16_t                        att_list_len;
117 	uint8_t                         cont_state_size;
118 	uint8_t                         num_filters;
119 	bool                         new_service;
120 };
121 
122 /* @typedef bt_sdp_attr_func_t
123  *  @brief SDP attribute iterator callback.
124  *
125  *  @param attr Attribute found.
126  *  @param att_idx Index of the found attribute in the attribute database.
127  *  @param user_data Data given.
128  *
129  *  @return BT_SDP_ITER_CONTINUE if should continue to the next attribute
130  *  or BT_SDP_ITER_STOP to stop.
131  */
132 typedef uint8_t (*bt_sdp_attr_func_t)(struct bt_sdp_attribute *attr,
133 				   uint8_t att_idx, void *user_data);
134 
135 /* @typedef bt_sdp_svc_func_t
136  * @brief SDP service record iterator callback.
137  *
138  * @param rec Service record found.
139  * @param user_data Data given.
140  *
141  * @return BT_SDP_ITER_CONTINUE if should continue to the next service record
142  *  or BT_SDP_ITER_STOP to stop.
143  */
144 typedef uint8_t (*bt_sdp_svc_func_t)(struct bt_sdp_record *rec,
145 				  void *user_data);
146 
147 /* @brief Callback for SDP connection
148  *
149  *  Gets called when an SDP connection is established
150  *
151  *  @param chan L2CAP channel
152  *
153  *  @return None
154  */
bt_sdp_connected(struct bt_l2cap_chan * chan)155 static void bt_sdp_connected(struct bt_l2cap_chan *chan)
156 {
157 	struct bt_l2cap_br_chan *ch = CONTAINER_OF(chan,
158 						   struct bt_l2cap_br_chan,
159 						   chan);
160 
161 	struct bt_sdp *sdp = CONTAINER_OF(ch, struct bt_sdp, chan);
162 
163 	LOG_DBG("chan %p cid 0x%04x", ch, ch->tx.cid);
164 
165 	k_fifo_init(&sdp->partial_resp_queue);
166 }
167 
168 /** @brief Callback for SDP disconnection
169  *
170  *  Gets called when an SDP connection is terminated
171  *
172  *  @param chan L2CAP channel
173  *
174  *  @return None
175  */
bt_sdp_disconnected(struct bt_l2cap_chan * chan)176 static void bt_sdp_disconnected(struct bt_l2cap_chan *chan)
177 {
178 	struct bt_l2cap_br_chan *ch = CONTAINER_OF(chan,
179 						   struct bt_l2cap_br_chan,
180 						   chan);
181 
182 	struct bt_sdp *sdp = CONTAINER_OF(ch, struct bt_sdp, chan);
183 
184 	LOG_DBG("chan %p cid 0x%04x", ch, ch->tx.cid);
185 
186 	(void)memset(sdp, 0, sizeof(*sdp));
187 }
188 
189 /* @brief Creates an SDP PDU
190  *
191  *  Creates an empty SDP PDU and returns the buffer
192  *
193  *  @param None
194  *
195  *  @return Pointer to the net_buf buffer
196  */
bt_sdp_create_pdu(void)197 static struct net_buf *bt_sdp_create_pdu(void)
198 {
199 	return bt_l2cap_create_pdu(&sdp_pool, sizeof(struct bt_sdp_hdr));
200 }
201 
202 /* @brief Sends out an SDP PDU
203  *
204  *  Sends out an SDP PDU after adding the relevant header
205  *
206  *  @param chan L2CAP channel
207  *  @param buf Buffer to be sent out
208  *  @param op Opcode to be used in the packet header
209  *  @param tid Transaction ID to be used in the packet header
210  *
211  *  @return None
212  */
bt_sdp_send(struct bt_l2cap_chan * chan,struct net_buf * buf,uint8_t op,uint16_t tid)213 static int bt_sdp_send(struct bt_l2cap_chan *chan, struct net_buf *buf,
214 		       uint8_t op, uint16_t tid)
215 {
216 	struct bt_sdp_hdr *hdr;
217 	uint16_t param_len = buf->len;
218 	int err;
219 
220 	hdr = net_buf_push(buf, sizeof(struct bt_sdp_hdr));
221 	hdr->op_code = op;
222 	hdr->tid = tid;
223 	hdr->param_len = sys_cpu_to_be16(param_len);
224 
225 	err = bt_l2cap_chan_send(chan, buf);
226 	if (err < 0) {
227 		net_buf_unref(buf);
228 	}
229 
230 	return err;
231 }
232 
233 /* @brief Sends an error response PDU
234  *
235  *  Creates and sends an error response PDU
236  *
237  *  @param chan L2CAP channel
238  *  @param err Error code to be sent in the packet
239  *  @param tid Transaction ID to be used in the packet header
240  *
241  *  @return None
242  */
send_err_rsp(struct bt_l2cap_chan * chan,uint16_t err,uint16_t tid)243 static void send_err_rsp(struct bt_l2cap_chan *chan, uint16_t err,
244 			 uint16_t tid)
245 {
246 	struct net_buf *buf;
247 
248 	LOG_DBG("tid %u, error %u", tid, err);
249 
250 	buf = bt_sdp_create_pdu();
251 
252 	net_buf_add_be16(buf, err);
253 
254 	bt_sdp_send(chan, buf, BT_SDP_ERROR_RSP, tid);
255 }
256 
257 /* @brief Parses data elements from a net_buf
258  *
259  * Parses the first data element from a buffer and splits it into type, size,
260  * data. Used for parsing incoming requests. Net buf is advanced to the data
261  * part of the element.
262  *
263  * @param buf Buffer to be advanced
264  * @param data_elem Pointer to the parsed data element structure
265  *
266  * @return 0 for success, or relevant error code
267  */
parse_data_elem(struct net_buf * buf,struct bt_sdp_data_elem * data_elem)268 static uint16_t parse_data_elem(struct net_buf *buf,
269 				struct bt_sdp_data_elem *data_elem)
270 {
271 	uint8_t size_field_len = 0U; /* Space used to accommodate the size */
272 
273 	if (buf->len < 1) {
274 		LOG_WRN("Malformed packet");
275 		return BT_SDP_INVALID_SYNTAX;
276 	}
277 
278 	data_elem->type = net_buf_pull_u8(buf);
279 
280 	switch (data_elem->type & BT_SDP_TYPE_DESC_MASK) {
281 	case BT_SDP_UINT8:
282 	case BT_SDP_INT8:
283 	case BT_SDP_UUID_UNSPEC:
284 	case BT_SDP_BOOL:
285 		data_elem->data_size = BIT(data_elem->type &
286 					   BT_SDP_SIZE_DESC_MASK);
287 		break;
288 	case BT_SDP_TEXT_STR_UNSPEC:
289 	case BT_SDP_SEQ_UNSPEC:
290 	case BT_SDP_ALT_UNSPEC:
291 	case BT_SDP_URL_STR_UNSPEC:
292 		size_field_len = BIT((data_elem->type & BT_SDP_SIZE_DESC_MASK) -
293 				     BT_SDP_SIZE_INDEX_OFFSET);
294 		if (buf->len < size_field_len) {
295 			LOG_WRN("Malformed packet");
296 			return BT_SDP_INVALID_SYNTAX;
297 		}
298 		switch (size_field_len) {
299 		case 1:
300 			data_elem->data_size = net_buf_pull_u8(buf);
301 			break;
302 		case 2:
303 			data_elem->data_size = net_buf_pull_be16(buf);
304 			break;
305 		case 4:
306 			data_elem->data_size = net_buf_pull_be32(buf);
307 			break;
308 		default:
309 			LOG_WRN("Invalid size in remote request");
310 			return BT_SDP_INVALID_SYNTAX;
311 		}
312 		break;
313 	default:
314 		LOG_WRN("Invalid type in remote request");
315 		return BT_SDP_INVALID_SYNTAX;
316 	}
317 
318 	if (buf->len < data_elem->data_size) {
319 		LOG_WRN("Malformed packet");
320 		return BT_SDP_INVALID_SYNTAX;
321 	}
322 
323 	data_elem->total_size = data_elem->data_size + size_field_len + 1;
324 	data_elem->data = buf->data;
325 
326 	return 0;
327 }
328 
329 /* @brief Searches for an UUID within an attribute
330  *
331  * Searches for an UUID within an attribute. If the attribute has data element
332  * sequences, it recursively searches within them as well. On finding a match
333  * with the UUID, it sets the found flag.
334  *
335  * @param elem Attribute to be used as the search space (haystack)
336  * @param uuid UUID to be looked for (needle)
337  * @param found Flag set to true if the UUID is found (to be returned)
338  * @param nest_level Used to limit the extent of recursion into nested data
339  *  elements, to avoid potential stack overflows
340  *
341  * @return Size of the last data element that has been searched
342  *  (used in recursion)
343  */
search_uuid(struct bt_sdp_data_elem * elem,struct bt_uuid * uuid,bool * found,uint8_t nest_level)344 static uint32_t search_uuid(struct bt_sdp_data_elem *elem, struct bt_uuid *uuid,
345 			 bool *found, uint8_t nest_level)
346 {
347 	const uint8_t *cur_elem;
348 	uint32_t seq_size, size;
349 	union {
350 		struct bt_uuid uuid;
351 		struct bt_uuid_16 u16;
352 		struct bt_uuid_32 u32;
353 		struct bt_uuid_128 u128;
354 	} u;
355 
356 	if (*found) {
357 		return 0;
358 	}
359 
360 	/* Limit recursion depth to avoid stack overflows */
361 	if (nest_level == SDP_DATA_ELEM_NEST_LEVEL_MAX) {
362 		return 0;
363 	}
364 
365 	seq_size = elem->data_size;
366 	cur_elem = elem->data;
367 
368 	if ((elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_UUID_UNSPEC) {
369 		if (seq_size == 2U) {
370 			u.uuid.type = BT_UUID_TYPE_16;
371 			u.u16.val = *((uint16_t *)cur_elem);
372 			if (!bt_uuid_cmp(&u.uuid, uuid)) {
373 				*found = true;
374 			}
375 		} else if (seq_size == 4U) {
376 			u.uuid.type = BT_UUID_TYPE_32;
377 			u.u32.val = *((uint32_t *)cur_elem);
378 			if (!bt_uuid_cmp(&u.uuid, uuid)) {
379 				*found = true;
380 			}
381 		} else if (seq_size == 16U) {
382 			u.uuid.type = BT_UUID_TYPE_128;
383 			memcpy(u.u128.val, cur_elem, seq_size);
384 			if (!bt_uuid_cmp(&u.uuid, uuid)) {
385 				*found = true;
386 			}
387 		} else {
388 			LOG_WRN("Invalid UUID size in local database");
389 			BT_ASSERT(0);
390 		}
391 	}
392 
393 	if ((elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_SEQ_UNSPEC ||
394 	    (elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_ALT_UNSPEC) {
395 		do {
396 			/* Recursively parse data elements */
397 			size = search_uuid((struct bt_sdp_data_elem *)cur_elem,
398 					   uuid, found, nest_level + 1);
399 			if (*found) {
400 				return 0;
401 			}
402 			cur_elem += sizeof(struct bt_sdp_data_elem);
403 			seq_size -= size;
404 		} while (seq_size);
405 	}
406 
407 	return elem->total_size;
408 }
409 
410 /* @brief SDP service record iterator.
411  *
412  * Iterate over service records from a starting point.
413  *
414  * @param func Callback function.
415  * @param user_data Data to pass to the callback.
416  *
417  * @return Pointer to the record where the iterator stopped, or NULL if all
418  *  records are covered
419  */
bt_sdp_foreach_svc(bt_sdp_svc_func_t func,void * user_data)420 static struct bt_sdp_record *bt_sdp_foreach_svc(bt_sdp_svc_func_t func,
421 						void *user_data)
422 {
423 	struct bt_sdp_record *rec = db;
424 
425 	while (rec) {
426 		if (func(rec, user_data) == BT_SDP_ITER_STOP) {
427 			break;
428 		}
429 
430 		rec = rec->next;
431 	}
432 	return rec;
433 }
434 
435 /* @brief Inserts a service record into a record pointer list
436  *
437  * Inserts a service record into a record pointer list
438  *
439  * @param rec The current service record.
440  * @param user_data Pointer to the destination record list.
441  *
442  * @return BT_SDP_ITER_CONTINUE to move on to the next record.
443  */
insert_record(struct bt_sdp_record * rec,void * user_data)444 static uint8_t insert_record(struct bt_sdp_record *rec, void *user_data)
445 {
446 	struct bt_sdp_record **rec_list = user_data;
447 
448 	rec_list[rec->index] = rec;
449 
450 	return BT_SDP_ITER_CONTINUE;
451 }
452 
453 /* @brief Looks for matching UUIDs in a list of service records
454  *
455  * Parses out a sequence of UUIDs from an input buffer, and checks if a record
456  * in the list contains all the UUIDs. If it doesn't, the record is removed
457  * from the list, so the list contains only the records which has all the
458  * input UUIDs in them.
459  *
460  * @param buf Incoming buffer containing all the UUIDs to be matched
461  * @param matching_recs List of service records to use for storing matching
462  * records
463  *
464  * @return 0 for success, or relevant error code
465  */
find_services(struct net_buf * buf,struct bt_sdp_record ** matching_recs)466 static uint16_t find_services(struct net_buf *buf,
467 			      struct bt_sdp_record **matching_recs)
468 {
469 	struct bt_sdp_data_elem data_elem;
470 	struct bt_sdp_record *record;
471 	uint32_t uuid_list_size;
472 	uint16_t res;
473 	uint8_t att_idx, rec_idx = 0U;
474 	bool found;
475 	union {
476 		struct bt_uuid uuid;
477 		struct bt_uuid_16 u16;
478 		struct bt_uuid_32 u32;
479 		struct bt_uuid_128 u128;
480 	} u;
481 
482 	res = parse_data_elem(buf, &data_elem);
483 	if (res) {
484 		return res;
485 	}
486 
487 	if (((data_elem.type & BT_SDP_TYPE_DESC_MASK) != BT_SDP_SEQ_UNSPEC) &&
488 	    ((data_elem.type & BT_SDP_TYPE_DESC_MASK) != BT_SDP_ALT_UNSPEC)) {
489 		LOG_WRN("Invalid type %x in service search pattern", data_elem.type);
490 		return BT_SDP_INVALID_SYNTAX;
491 	}
492 
493 	uuid_list_size = data_elem.data_size;
494 
495 	bt_sdp_foreach_svc(insert_record, matching_recs);
496 
497 	/* Go over the sequence of UUIDs, and match one UUID at a time */
498 	while (uuid_list_size) {
499 		res = parse_data_elem(buf, &data_elem);
500 		if (res) {
501 			return res;
502 		}
503 
504 		if ((data_elem.type & BT_SDP_TYPE_DESC_MASK) !=
505 		    BT_SDP_UUID_UNSPEC) {
506 			LOG_WRN("Invalid type %u in service search pattern", data_elem.type);
507 			return BT_SDP_INVALID_SYNTAX;
508 		}
509 
510 		if (buf->len < data_elem.data_size) {
511 			LOG_WRN("Malformed packet");
512 			return BT_SDP_INVALID_SYNTAX;
513 		}
514 
515 		if (data_elem.data_size == 2U) {
516 			u.uuid.type = BT_UUID_TYPE_16;
517 			u.u16.val = net_buf_pull_be16(buf);
518 		} else if (data_elem.data_size == 4U) {
519 			u.uuid.type = BT_UUID_TYPE_32;
520 			u.u32.val = net_buf_pull_be32(buf);
521 		} else if (data_elem.data_size == 16U) {
522 			u.uuid.type = BT_UUID_TYPE_128;
523 			sys_memcpy_swap(u.u128.val, buf->data,
524 					data_elem.data_size);
525 			net_buf_pull(buf, data_elem.data_size);
526 		} else {
527 			LOG_WRN("Invalid UUID len %u in service search pattern",
528 				data_elem.data_size);
529 			net_buf_pull(buf, data_elem.data_size);
530 		}
531 
532 		uuid_list_size -= data_elem.total_size;
533 
534 		/* Go over the list of services, and look for a service which
535 		 * doesn't have this UUID
536 		 */
537 		for (rec_idx = 0U; rec_idx < num_services; rec_idx++) {
538 			record = matching_recs[rec_idx];
539 
540 			if (!record) {
541 				continue;
542 			}
543 
544 			found = false;
545 
546 			/* Search for the UUID in all the attrs of the svc */
547 			for (att_idx = 0U; att_idx < record->attr_count;
548 			     att_idx++) {
549 				search_uuid(&record->attrs[att_idx].val,
550 					    &u.uuid, &found, 1);
551 				if (found) {
552 					break;
553 				}
554 			}
555 
556 			/* Remove the record from the list if it doesn't have
557 			 * the UUID
558 			 */
559 			if (!found) {
560 				matching_recs[rec_idx] = NULL;
561 			}
562 		}
563 	}
564 
565 	return 0;
566 }
567 
568 /* @brief Handler for Service Search Request
569  *
570  * Parses, processes and responds to a Service Search Request
571  *
572  * @param sdp Pointer to the SDP structure
573  * @param buf Request net buf
574  * @param tid Transaction ID
575  *
576  * @return 0 for success, or relevant error code
577  */
sdp_svc_search_req(struct bt_sdp * sdp,struct net_buf * buf,uint16_t tid)578 static uint16_t sdp_svc_search_req(struct bt_sdp *sdp, struct net_buf *buf,
579 				uint16_t tid)
580 {
581 	struct bt_sdp_svc_rsp *rsp;
582 	struct net_buf *resp_buf;
583 	struct bt_sdp_record *record;
584 	struct bt_sdp_record *matching_recs[BT_SDP_MAX_SERVICES];
585 	uint16_t max_rec_count, total_recs = 0U, current_recs = 0U, res;
586 	uint8_t cont_state_size, cont_state = 0U, idx = 0U, count = 0U;
587 	bool pkt_full = false;
588 
589 	res = find_services(buf, matching_recs);
590 	if (res) {
591 		/* Error in parsing */
592 		return res;
593 	}
594 
595 	if (buf->len < 3) {
596 		LOG_WRN("Malformed packet");
597 		return BT_SDP_INVALID_SYNTAX;
598 	}
599 
600 	max_rec_count = net_buf_pull_be16(buf);
601 	cont_state_size = net_buf_pull_u8(buf);
602 
603 	/* Zero out the matching services beyond max_rec_count */
604 	for (idx = 0U; idx < num_services; idx++) {
605 		if (count == max_rec_count) {
606 			matching_recs[idx] = NULL;
607 			continue;
608 		}
609 
610 		if (matching_recs[idx]) {
611 			count++;
612 		}
613 	}
614 
615 	/* We send out only SDP_SS_CONT_STATE_SIZE bytes continuation state in
616 	 * responses, so expect only SDP_SS_CONT_STATE_SIZE bytes in requests
617 	 */
618 	if (cont_state_size) {
619 		if (cont_state_size != SDP_SS_CONT_STATE_SIZE) {
620 			LOG_WRN("Invalid cont state size %u", cont_state_size);
621 			return BT_SDP_INVALID_CSTATE;
622 		}
623 
624 		if (buf->len < cont_state_size) {
625 			LOG_WRN("Malformed packet");
626 			return BT_SDP_INVALID_SYNTAX;
627 		}
628 
629 		cont_state = net_buf_pull_u8(buf);
630 		/* We include total_recs in the continuation state. We calculate
631 		 * it once and preserve it across all the partial responses
632 		 */
633 		total_recs = net_buf_pull_be16(buf);
634 	}
635 
636 	LOG_DBG("max_rec_count %u, cont_state %u", max_rec_count, cont_state);
637 
638 	resp_buf = bt_sdp_create_pdu();
639 	rsp = net_buf_add(resp_buf, sizeof(*rsp));
640 
641 	for (; cont_state < num_services; cont_state++) {
642 		record = matching_recs[cont_state];
643 
644 		if (!record) {
645 			continue;
646 		}
647 
648 		/* Calculate total recs only if it is first packet */
649 		if (!cont_state_size) {
650 			total_recs++;
651 		}
652 
653 		if (pkt_full) {
654 			continue;
655 		}
656 
657 		/* 4 bytes per Service Record Handle */
658 		/* 4 bytes for ContinuationState */
659 		if ((MIN(SDP_MTU, sdp->chan.tx.mtu) - resp_buf->len) <
660 		    (4 + 4 + sizeof(struct bt_sdp_hdr))) {
661 			pkt_full = true;
662 		}
663 
664 		if (pkt_full) {
665 			/* Packet exhausted: Add continuation state and break */
666 			LOG_DBG("Packet full, num_services_covered %u", cont_state);
667 			net_buf_add_u8(resp_buf, SDP_SS_CONT_STATE_SIZE);
668 			net_buf_add_u8(resp_buf, cont_state);
669 
670 			/* If it is the first packet of a partial response,
671 			 * continue dry-running to calculate total_recs.
672 			 * Else break
673 			 */
674 			if (cont_state_size) {
675 				break;
676 			}
677 
678 			continue;
679 		}
680 
681 		/* Add the service record handle to the packet */
682 		net_buf_add_be32(resp_buf, record->handle);
683 		current_recs++;
684 	}
685 
686 	/* Add 0 continuation state if packet is exhausted */
687 	if (!pkt_full) {
688 		net_buf_add_u8(resp_buf, 0);
689 	} else {
690 		net_buf_add_be16(resp_buf, total_recs);
691 	}
692 
693 	rsp->total_recs = sys_cpu_to_be16(total_recs);
694 	rsp->current_recs = sys_cpu_to_be16(current_recs);
695 
696 	LOG_DBG("Sending response, len %u", resp_buf->len);
697 	bt_sdp_send(&sdp->chan.chan, resp_buf, BT_SDP_SVC_SEARCH_RSP, tid);
698 
699 	return 0;
700 }
701 
702 /* @brief Copies an attribute into an outgoing buffer
703  *
704  *  Copies an attribute into a buffer. Recursively calls itself for complex
705  *  attributes.
706  *
707  *  @param elem Attribute to be copied to the buffer
708  *  @param buf Buffer where the attribute is to be copied
709  *
710  *  @return Size of the last data element that has been searched
711  *  (used in recursion)
712  */
copy_attribute(struct bt_sdp_data_elem * elem,struct net_buf * buf,uint8_t nest_level)713 static uint32_t copy_attribute(struct bt_sdp_data_elem *elem,
714 			    struct net_buf *buf, uint8_t nest_level)
715 {
716 	const uint8_t *cur_elem;
717 	uint32_t size, seq_size, total_size;
718 
719 	/* Limit recursion depth to avoid stack overflows */
720 	if (nest_level == SDP_DATA_ELEM_NEST_LEVEL_MAX) {
721 		return 0;
722 	}
723 
724 	seq_size = elem->data_size;
725 	total_size = elem->total_size;
726 	cur_elem = elem->data;
727 
728 	/* Copy the header */
729 	net_buf_add_u8(buf, elem->type);
730 
731 	switch (total_size - (seq_size + 1U)) {
732 	case 1:
733 		net_buf_add_u8(buf, elem->data_size);
734 		break;
735 	case 2:
736 		net_buf_add_be16(buf, elem->data_size);
737 		break;
738 	case 4:
739 		net_buf_add_be32(buf, elem->data_size);
740 		break;
741 	}
742 
743 	/* Recursively parse (till the last element is not another data element)
744 	 * and then fill the elements
745 	 */
746 	if ((elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_SEQ_UNSPEC ||
747 	    (elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_ALT_UNSPEC) {
748 		do {
749 			size = copy_attribute((struct bt_sdp_data_elem *)
750 					      cur_elem, buf, nest_level + 1);
751 			cur_elem += sizeof(struct bt_sdp_data_elem);
752 			seq_size -= size;
753 		} while (seq_size);
754 	} else if ((elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_UINT8 ||
755 		   (elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_INT8 ||
756 		   (elem->type & BT_SDP_TYPE_DESC_MASK) == BT_SDP_UUID_UNSPEC) {
757 		if (seq_size == 1U) {
758 			net_buf_add_u8(buf, *((uint8_t *)elem->data));
759 		} else if (seq_size == 2U) {
760 			net_buf_add_be16(buf, *((uint16_t *)elem->data));
761 		} else if (seq_size == 4U) {
762 			net_buf_add_be32(buf, *((uint32_t *)elem->data));
763 		} else {
764 			/* TODO: Convert 32bit and 128bit values to big-endian*/
765 			net_buf_add_mem(buf, elem->data, seq_size);
766 		}
767 	} else {
768 		net_buf_add_mem(buf, elem->data, seq_size);
769 	}
770 
771 	return total_size;
772 }
773 
774 /* @brief SDP attribute iterator.
775  *
776  *  Iterate over attributes of a service record from a starting index.
777  *
778  *  @param record Service record whose attributes are to be iterated over.
779  *  @param idx Index in the attribute list from where to start.
780  *  @param func Callback function.
781  *  @param user_data Data to pass to the callback.
782  *
783  *  @return Index of the attribute where the iterator stopped
784  */
bt_sdp_foreach_attr(struct bt_sdp_record * record,uint8_t idx,bt_sdp_attr_func_t func,void * user_data)785 static uint8_t bt_sdp_foreach_attr(struct bt_sdp_record *record, uint8_t idx,
786 				bt_sdp_attr_func_t func, void *user_data)
787 {
788 	for (; idx < record->attr_count; idx++) {
789 		if (func(&record->attrs[idx], idx, user_data) ==
790 		    BT_SDP_ITER_STOP) {
791 			break;
792 		}
793 	}
794 
795 	return idx;
796 }
797 
798 /* @brief Check if an attribute matches a range, and include it in the response
799  *
800  *  Checks if an attribute matches a given attribute ID or range, and if so,
801  *  includes it in the response packet
802  *
803  *  @param attr The current attribute
804  *  @param att_idx Index of the current attribute in the database
805  *  @param user_data Pointer to the structure containing response packet, byte
806  *   count, states, etc
807  *
808  *  @return BT_SDP_ITER_CONTINUE if should continue to the next attribute
809  *   or BT_SDP_ITER_STOP to stop.
810  */
select_attrs(struct bt_sdp_attribute * attr,uint8_t att_idx,void * user_data)811 static uint8_t select_attrs(struct bt_sdp_attribute *attr, uint8_t att_idx,
812 			 void *user_data)
813 {
814 	struct select_attrs_data *sad = user_data;
815 	uint16_t att_id_lower, att_id_upper, att_id_cur, space;
816 	uint32_t attr_size, seq_size;
817 	uint8_t idx_filter;
818 
819 	for (idx_filter = 0U; idx_filter < sad->num_filters; idx_filter++) {
820 
821 		att_id_lower = (sad->filter[idx_filter] >> 16);
822 		att_id_upper = (sad->filter[idx_filter]);
823 		att_id_cur = attr->id;
824 
825 		/* Check for range values */
826 		if (att_id_lower != 0xffff &&
827 		    (!IN_RANGE(att_id_cur, att_id_lower, att_id_upper))) {
828 			continue;
829 		}
830 
831 		/* Check for match values */
832 		if (att_id_lower == 0xffff && att_id_cur != att_id_upper) {
833 			continue;
834 		}
835 
836 		/* Attribute ID matches */
837 
838 		/* 3 bytes for Attribute ID */
839 		attr_size = 3 + attr->val.total_size;
840 
841 		/* If this is the first attribute of the service, then we need
842 		 * to account for the space required to add the per-service
843 		 * data element sequence header as well.
844 		 */
845 		if ((sad->state->current_svc != sad->rec->index) &&
846 		    sad->new_service) {
847 			/* 3 bytes for Per-Service Data Elem Seq declaration */
848 			seq_size = attr_size + 3;
849 		} else {
850 			seq_size = attr_size;
851 		}
852 
853 		if (sad->rsp_buf) {
854 			space = MIN(SDP_MTU, sad->sdp->chan.tx.mtu) -
855 				sad->rsp_buf->len - sizeof(struct bt_sdp_hdr);
856 
857 			if ((!sad->state->pkt_full) &&
858 			    ((seq_size > sad->max_att_len) ||
859 			     (space < seq_size + sad->cont_state_size))) {
860 				/* Packet exhausted */
861 				sad->state->pkt_full = true;
862 			}
863 		}
864 
865 		/* Keep filling data only if packet is not exhausted */
866 		if (!sad->state->pkt_full && sad->rsp_buf) {
867 			/* Add Per-Service Data Element Seq declaration once
868 			 * only when we are starting from the first attribute
869 			 */
870 			if (!sad->seq &&
871 			    (sad->state->current_svc != sad->rec->index)) {
872 				sad->seq = net_buf_add(sad->rsp_buf,
873 						       sizeof(*sad->seq));
874 				sad->seq->type = BT_SDP_SEQ16;
875 				sad->seq->size = 0U;
876 			}
877 
878 			/* Add attribute ID */
879 			net_buf_add_u8(sad->rsp_buf, BT_SDP_UINT16);
880 			net_buf_add_be16(sad->rsp_buf, att_id_cur);
881 
882 			/* Add attribute value */
883 			copy_attribute(&attr->val, sad->rsp_buf, 1);
884 
885 			sad->max_att_len -= seq_size;
886 			sad->att_list_len += seq_size;
887 			sad->state->last_att = att_idx;
888 			sad->state->current_svc = sad->rec->index;
889 		}
890 
891 		if (sad->seq) {
892 			/* Keep adding the sequence size if this packet contains
893 			 * the Per-Service Data Element Seq declaration header
894 			 */
895 			sad->seq->size += attr_size;
896 			sad->state->att_list_size += seq_size;
897 		} else {
898 			/* Keep adding the total attr lists size if:
899 			 * It's a dry-run, calculating the total attr lists size
900 			 */
901 			sad->state->att_list_size += seq_size;
902 		}
903 
904 		sad->new_service = false;
905 		break;
906 	}
907 
908 	/* End the search if:
909 	 * 1. We have exhausted the packet
910 	 * AND
911 	 * 2. This packet doesn't contain the service element declaration header
912 	 * AND
913 	 * 3. This is not a dry-run (then we look for other attrs that match)
914 	 */
915 	if (sad->state->pkt_full && !sad->seq && sad->rsp_buf) {
916 		return BT_SDP_ITER_STOP;
917 	}
918 
919 	return BT_SDP_ITER_CONTINUE;
920 }
921 
922 /* @brief Creates attribute list in the given buffer
923  *
924  *  Populates the attribute list of a service record in the buffer. To be used
925  *  for responding to Service Attribute and Service Search Attribute requests
926  *
927  *  @param sdp Pointer to the SDP structure
928  *  @param record Service record whose attributes are to be included in the
929  *   response
930  *  @param filter Attribute values/ranges to be used as a filter
931  *  @param num_filters Number of elements in the attribute filter
932  *  @param max_att_len Maximum size of attributes to be included in the response
933  *  @param cont_state_size No. of additional continuation state bytes to keep
934  *   space for in the packet. This will vary based on the type of the request
935  *  @param next_att Starting position of the search in the service's attr list
936  *  @param state State of the overall search
937  *  @param rsp_buf Response buffer which is filled in
938  *
939  *  @return len Length of the attribute list created
940  */
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)941 static uint16_t create_attr_list(struct bt_sdp *sdp, struct bt_sdp_record *record,
942 			      uint32_t *filter, uint8_t num_filters,
943 			      uint16_t max_att_len, uint8_t cont_state_size,
944 			      uint8_t next_att, struct search_state *state,
945 			      struct net_buf *rsp_buf)
946 {
947 	struct select_attrs_data sad;
948 	uint8_t idx_att;
949 
950 	sad.num_filters = num_filters;
951 	sad.rec = record;
952 	sad.rsp_buf = rsp_buf;
953 	sad.sdp = sdp;
954 	sad.max_att_len = max_att_len;
955 	sad.cont_state_size = cont_state_size;
956 	sad.seq = NULL;
957 	sad.filter = filter;
958 	sad.state = state;
959 	sad.att_list_len = 0U;
960 	sad.new_service = true;
961 
962 	idx_att = bt_sdp_foreach_attr(sad.rec, next_att, select_attrs, &sad);
963 
964 	if (sad.seq) {
965 		sad.seq->size = sys_cpu_to_be16(sad.seq->size);
966 	}
967 
968 	return sad.att_list_len;
969 }
970 
971 /* @brief Extracts the attribute search list from a buffer
972  *
973  *  Parses a buffer to extract the attribute search list (list of attribute IDs
974  *  and ranges) which are to be used to filter attributes.
975  *
976  *  @param buf Buffer to be parsed for extracting the attribute search list
977  *  @param filter Empty list of 4byte filters that are filled in. For attribute
978  *   IDs, the lower 2 bytes contain the ID and the upper 2 bytes are set to
979  *   0xFFFF. For attribute ranges, the lower 2bytes indicate the start ID and
980  *   the upper 2bytes indicate the end ID
981  *  @param num_filters No. of filter elements filled in (to be returned)
982  *
983  *  @return 0 for success, or relevant error code
984  */
get_att_search_list(struct net_buf * buf,uint32_t * filter,uint8_t * num_filters)985 static uint16_t get_att_search_list(struct net_buf *buf, uint32_t *filter,
986 				 uint8_t *num_filters)
987 {
988 	struct bt_sdp_data_elem data_elem;
989 	uint16_t res;
990 	uint32_t size;
991 
992 	*num_filters = 0U;
993 	res = parse_data_elem(buf, &data_elem);
994 	if (res) {
995 		return res;
996 	}
997 
998 	size = data_elem.data_size;
999 
1000 	while (size) {
1001 		res = parse_data_elem(buf, &data_elem);
1002 		if (res) {
1003 			return res;
1004 		}
1005 
1006 		if ((data_elem.type & BT_SDP_TYPE_DESC_MASK) != BT_SDP_UINT8) {
1007 			LOG_WRN("Invalid type %u in attribute ID list", data_elem.type);
1008 			return BT_SDP_INVALID_SYNTAX;
1009 		}
1010 
1011 		if (buf->len < data_elem.data_size) {
1012 			LOG_WRN("Malformed packet");
1013 			return BT_SDP_INVALID_SYNTAX;
1014 		}
1015 
1016 		/* This is an attribute ID */
1017 		if (data_elem.data_size == 2U) {
1018 			filter[(*num_filters)++] = 0xffff0000 |
1019 							net_buf_pull_be16(buf);
1020 		}
1021 
1022 		/* This is an attribute ID range */
1023 		if (data_elem.data_size == 4U) {
1024 			filter[(*num_filters)++] = net_buf_pull_be32(buf);
1025 		}
1026 
1027 		size -= data_elem.total_size;
1028 	}
1029 
1030 	return 0;
1031 }
1032 
1033 /* @brief Check if a given handle matches that of the current service
1034  *
1035  *  Checks if a given handle matches that of the current service
1036  *
1037  *  @param rec The current service record
1038  *  @param user_data Pointer to the service record handle to be matched
1039  *
1040  *  @return BT_SDP_ITER_CONTINUE if should continue to the next record
1041  *   or BT_SDP_ITER_STOP to stop.
1042  */
find_handle(struct bt_sdp_record * rec,void * user_data)1043 static uint8_t find_handle(struct bt_sdp_record *rec, void *user_data)
1044 {
1045 	uint32_t *svc_rec_hdl = user_data;
1046 
1047 	if (rec->handle == *svc_rec_hdl) {
1048 		return BT_SDP_ITER_STOP;
1049 	}
1050 
1051 	return BT_SDP_ITER_CONTINUE;
1052 }
1053 
1054 /* @brief Handler for Service Attribute Request
1055  *
1056  *  Parses, processes and responds to a Service Attribute Request
1057  *
1058  *  @param sdp Pointer to the SDP structure
1059  *  @param buf Request buffer
1060  *  @param tid Transaction ID
1061  *
1062  *  @return 0 for success, or relevant error code
1063  */
sdp_svc_att_req(struct bt_sdp * sdp,struct net_buf * buf,uint16_t tid)1064 static uint16_t sdp_svc_att_req(struct bt_sdp *sdp, struct net_buf *buf,
1065 			     uint16_t tid)
1066 {
1067 	uint32_t filter[MAX_NUM_ATT_ID_FILTER];
1068 	struct search_state state = {
1069 		.current_svc = SDP_INVALID,
1070 		.last_att = SDP_INVALID,
1071 		.pkt_full = false
1072 	};
1073 	struct bt_sdp_record *record;
1074 	struct bt_sdp_att_rsp *rsp;
1075 	struct net_buf *rsp_buf;
1076 	uint32_t svc_rec_hdl;
1077 	uint16_t max_att_len, res, att_list_len;
1078 	uint8_t num_filters, cont_state_size, next_att = 0U;
1079 
1080 	if (buf->len < 6) {
1081 		LOG_WRN("Malformed packet");
1082 		return BT_SDP_INVALID_SYNTAX;
1083 	}
1084 
1085 	svc_rec_hdl = net_buf_pull_be32(buf);
1086 	max_att_len = net_buf_pull_be16(buf);
1087 
1088 	/* Set up the filters */
1089 	res = get_att_search_list(buf, filter, &num_filters);
1090 	if (res) {
1091 		/* Error in parsing */
1092 		return res;
1093 	}
1094 
1095 	if (buf->len < 1) {
1096 		LOG_WRN("Malformed packet");
1097 		return BT_SDP_INVALID_SYNTAX;
1098 	}
1099 
1100 	cont_state_size = net_buf_pull_u8(buf);
1101 
1102 	/* We only send out 1 byte continuation state in responses,
1103 	 * so expect only 1 byte in requests
1104 	 */
1105 	if (cont_state_size) {
1106 		if (cont_state_size != SDP_SA_CONT_STATE_SIZE) {
1107 			LOG_WRN("Invalid cont state size %u", cont_state_size);
1108 			return BT_SDP_INVALID_CSTATE;
1109 		}
1110 
1111 		if (buf->len < cont_state_size) {
1112 			LOG_WRN("Malformed packet");
1113 			return BT_SDP_INVALID_SYNTAX;
1114 		}
1115 
1116 		state.last_att = net_buf_pull_u8(buf) + 1;
1117 		next_att = state.last_att;
1118 	}
1119 
1120 	LOG_DBG("svc_rec_hdl %u, max_att_len 0x%04x, cont_state %u", svc_rec_hdl, max_att_len,
1121 		next_att);
1122 
1123 	/* Find the service */
1124 	record = bt_sdp_foreach_svc(find_handle, &svc_rec_hdl);
1125 
1126 	if (!record) {
1127 		LOG_WRN("Handle %u not found", svc_rec_hdl);
1128 		return BT_SDP_INVALID_RECORD_HANDLE;
1129 	}
1130 
1131 	/* For partial responses, restore the search state */
1132 	if (cont_state_size) {
1133 		state.current_svc = record->index;
1134 	}
1135 
1136 	rsp_buf = bt_sdp_create_pdu();
1137 	rsp = net_buf_add(rsp_buf, sizeof(*rsp));
1138 
1139 	/* cont_state_size should include 1 byte header */
1140 	att_list_len = create_attr_list(sdp, record, filter, num_filters,
1141 					max_att_len, SDP_SA_CONT_STATE_SIZE + 1,
1142 					next_att, &state, rsp_buf);
1143 
1144 	if (!att_list_len) {
1145 		/* For empty responses, add an empty data element sequence */
1146 		net_buf_add_u8(rsp_buf, BT_SDP_SEQ8);
1147 		net_buf_add_u8(rsp_buf, 0);
1148 		att_list_len = 2U;
1149 	}
1150 
1151 	/* Add continuation state */
1152 	if (state.pkt_full) {
1153 		LOG_DBG("Packet full, state.last_att %u", state.last_att);
1154 		net_buf_add_u8(rsp_buf, 1);
1155 		net_buf_add_u8(rsp_buf, state.last_att);
1156 	} else {
1157 		net_buf_add_u8(rsp_buf, 0);
1158 	}
1159 
1160 	rsp->att_list_len = sys_cpu_to_be16(att_list_len);
1161 
1162 	LOG_DBG("Sending response, len %u", rsp_buf->len);
1163 	bt_sdp_send(&sdp->chan.chan, rsp_buf, BT_SDP_SVC_ATTR_RSP, tid);
1164 
1165 	return 0;
1166 }
1167 
1168 /* @brief Handler for Service Search Attribute Request
1169  *
1170  *  Parses, processes and responds to a Service Search Attribute Request
1171  *
1172  *  @param sdp Pointer to the SDP structure
1173  *  @param buf Request buffer
1174  *  @param tid Transaction ID
1175  *
1176  *  @return 0 for success, or relevant error code
1177  */
sdp_svc_search_att_req(struct bt_sdp * sdp,struct net_buf * buf,uint16_t tid)1178 static uint16_t sdp_svc_search_att_req(struct bt_sdp *sdp, struct net_buf *buf,
1179 				    uint16_t tid)
1180 {
1181 	uint32_t filter[MAX_NUM_ATT_ID_FILTER];
1182 	struct bt_sdp_record *matching_recs[BT_SDP_MAX_SERVICES];
1183 	struct search_state state = {
1184 		.att_list_size = 0,
1185 		.current_svc = SDP_INVALID,
1186 		.last_att = SDP_INVALID,
1187 		.pkt_full = false
1188 	};
1189 	struct net_buf *rsp_buf, *rsp_buf_cpy;
1190 	struct bt_sdp_record *record;
1191 	struct bt_sdp_att_rsp *rsp;
1192 	struct bt_sdp_data_elem_seq *seq = NULL;
1193 	uint16_t max_att_len, res, att_list_len = 0U;
1194 	uint8_t num_filters, cont_state_size, next_svc = 0U, next_att = 0U;
1195 	bool dry_run = false;
1196 
1197 	res = find_services(buf, matching_recs);
1198 	if (res) {
1199 		return res;
1200 	}
1201 
1202 	if (buf->len < 2) {
1203 		LOG_WRN("Malformed packet");
1204 		return BT_SDP_INVALID_SYNTAX;
1205 	}
1206 
1207 	max_att_len = net_buf_pull_be16(buf);
1208 
1209 	/* Set up the filters */
1210 	res = get_att_search_list(buf, filter, &num_filters);
1211 
1212 	if (res) {
1213 		/* Error in parsing */
1214 		return res;
1215 	}
1216 
1217 	if (buf->len < 1) {
1218 		LOG_WRN("Malformed packet");
1219 		return BT_SDP_INVALID_SYNTAX;
1220 	}
1221 
1222 	cont_state_size = net_buf_pull_u8(buf);
1223 
1224 	/* We only send out 2 bytes continuation state in responses,
1225 	 * so expect only 2 bytes in requests
1226 	 */
1227 	if (cont_state_size) {
1228 		if (cont_state_size != SDP_SSA_CONT_STATE_SIZE) {
1229 			LOG_WRN("Invalid cont state size %u", cont_state_size);
1230 			return BT_SDP_INVALID_CSTATE;
1231 		}
1232 
1233 		if (buf->len < cont_state_size) {
1234 			LOG_WRN("Malformed packet");
1235 			return BT_SDP_INVALID_SYNTAX;
1236 		}
1237 
1238 		state.current_svc = net_buf_pull_u8(buf);
1239 		state.last_att = net_buf_pull_u8(buf) + 1;
1240 		next_svc = state.current_svc;
1241 		next_att = state.last_att;
1242 	}
1243 
1244 	LOG_DBG("max_att_len 0x%04x, state.current_svc %u, state.last_att %u", max_att_len,
1245 		state.current_svc, state.last_att);
1246 
1247 	rsp_buf = bt_sdp_create_pdu();
1248 
1249 	rsp = net_buf_add(rsp_buf, sizeof(*rsp));
1250 
1251 	/* Add headers only if this is not a partial response */
1252 	if (!cont_state_size) {
1253 		seq = net_buf_add(rsp_buf, sizeof(*seq));
1254 		seq->type = BT_SDP_SEQ16;
1255 		seq->size = 0U;
1256 
1257 		/* 3 bytes for Outer Data Element Sequence declaration */
1258 		att_list_len = 3U;
1259 	}
1260 
1261 	rsp_buf_cpy = rsp_buf;
1262 
1263 	for (; next_svc < num_services; next_svc++) {
1264 		record = matching_recs[next_svc];
1265 
1266 		if (!record) {
1267 			continue;
1268 		}
1269 
1270 		att_list_len += create_attr_list(sdp, record, filter,
1271 						 num_filters, max_att_len,
1272 						 SDP_SSA_CONT_STATE_SIZE + 1,
1273 						 next_att, &state, rsp_buf_cpy);
1274 
1275 		/* Check if packet is full and not dry run */
1276 		if (state.pkt_full && !dry_run) {
1277 			LOG_DBG("Packet full, state.last_att %u", state.last_att);
1278 			dry_run = true;
1279 
1280 			/* Add continuation state */
1281 			net_buf_add_u8(rsp_buf, 2);
1282 			net_buf_add_u8(rsp_buf, state.current_svc);
1283 			net_buf_add_u8(rsp_buf, state.last_att);
1284 
1285 			/* Break if it's not a partial response, else dry-run
1286 			 * Dry run: Look for other services that match
1287 			 */
1288 			if (cont_state_size) {
1289 				break;
1290 			}
1291 
1292 			rsp_buf_cpy = NULL;
1293 		}
1294 
1295 		next_att = 0U;
1296 	}
1297 
1298 	if (!dry_run) {
1299 		if (!att_list_len) {
1300 			/* For empty responses, add an empty data elem seq */
1301 			net_buf_add_u8(rsp_buf, BT_SDP_SEQ8);
1302 			net_buf_add_u8(rsp_buf, 0);
1303 			att_list_len = 2U;
1304 		}
1305 		/* Search exhausted */
1306 		net_buf_add_u8(rsp_buf, 0);
1307 	}
1308 
1309 	rsp->att_list_len = sys_cpu_to_be16(att_list_len);
1310 	if (seq) {
1311 		seq->size = sys_cpu_to_be16(state.att_list_size);
1312 	}
1313 
1314 	LOG_DBG("Sending response, len %u", rsp_buf->len);
1315 	bt_sdp_send(&sdp->chan.chan, rsp_buf, BT_SDP_SVC_SEARCH_ATTR_RSP,
1316 		    tid);
1317 
1318 	return 0;
1319 }
1320 
1321 static const struct {
1322 	uint8_t  op_code;
1323 	uint16_t  (*func)(struct bt_sdp *sdp, struct net_buf *buf, uint16_t tid);
1324 } handlers[] = {
1325 	{ BT_SDP_SVC_SEARCH_REQ, sdp_svc_search_req },
1326 	{ BT_SDP_SVC_ATTR_REQ, sdp_svc_att_req },
1327 	{ BT_SDP_SVC_SEARCH_ATTR_REQ, sdp_svc_search_att_req },
1328 };
1329 
1330 /* @brief Callback for SDP data receive
1331  *
1332  *  Gets called when an SDP PDU is received. Calls the corresponding handler
1333  *  based on the op code of the PDU.
1334  *
1335  *  @param chan L2CAP channel
1336  *  @param buf Received PDU
1337  *
1338  *  @return None
1339  */
bt_sdp_recv(struct bt_l2cap_chan * chan,struct net_buf * buf)1340 static int bt_sdp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
1341 {
1342 	struct bt_l2cap_br_chan *ch = CONTAINER_OF(chan,
1343 			struct bt_l2cap_br_chan, chan);
1344 	struct bt_sdp *sdp = CONTAINER_OF(ch, struct bt_sdp, chan);
1345 	struct bt_sdp_hdr *hdr;
1346 	uint16_t err = BT_SDP_INVALID_SYNTAX;
1347 	size_t i;
1348 
1349 	LOG_DBG("chan %p, ch %p, cid 0x%04x", chan, ch, ch->tx.cid);
1350 
1351 	BT_ASSERT(sdp);
1352 
1353 	if (buf->len < sizeof(*hdr)) {
1354 		LOG_ERR("Too small SDP PDU received");
1355 		return 0;
1356 	}
1357 
1358 	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
1359 	LOG_DBG("Received SDP code 0x%02x len %u", hdr->op_code, buf->len);
1360 
1361 	if (sys_cpu_to_be16(hdr->param_len) != buf->len) {
1362 		err = BT_SDP_INVALID_PDU_SIZE;
1363 	} else {
1364 		for (i = 0; i < ARRAY_SIZE(handlers); i++) {
1365 			if (hdr->op_code != handlers[i].op_code) {
1366 				continue;
1367 			}
1368 
1369 			err = handlers[i].func(sdp, buf, hdr->tid);
1370 			break;
1371 		}
1372 	}
1373 
1374 	if (err) {
1375 		LOG_WRN("SDP error 0x%02x", err);
1376 		send_err_rsp(chan, err, hdr->tid);
1377 	}
1378 
1379 	return 0;
1380 }
1381 
1382 /* @brief Callback for SDP connection accept
1383  *
1384  *  Gets called when an incoming SDP connection needs to be authorized.
1385  *  Registers the L2CAP callbacks and allocates an SDP context to the connection
1386  *
1387  *  @param conn BT connection object
1388  *  @param chan L2CAP channel structure (to be returned)
1389  *
1390  *  @return 0 for success, or relevant error code
1391  */
bt_sdp_accept(struct bt_conn * conn,struct bt_l2cap_server * server,struct bt_l2cap_chan ** chan)1392 static int bt_sdp_accept(struct bt_conn *conn, struct bt_l2cap_server *server,
1393 			 struct bt_l2cap_chan **chan)
1394 {
1395 	static const struct bt_l2cap_chan_ops ops = {
1396 		.connected = bt_sdp_connected,
1397 		.disconnected = bt_sdp_disconnected,
1398 		.recv = bt_sdp_recv,
1399 	};
1400 	int i;
1401 
1402 	LOG_DBG("conn %p", conn);
1403 
1404 	for (i = 0; i < ARRAY_SIZE(bt_sdp_pool); i++) {
1405 		struct bt_sdp *sdp = &bt_sdp_pool[i];
1406 
1407 		if (sdp->chan.chan.conn) {
1408 			continue;
1409 		}
1410 
1411 		sdp->chan.chan.ops = &ops;
1412 		sdp->chan.rx.mtu = SDP_MTU;
1413 
1414 		*chan = &sdp->chan.chan;
1415 
1416 		return 0;
1417 	}
1418 
1419 	LOG_ERR("No available SDP context for conn %p", conn);
1420 
1421 	return -ENOMEM;
1422 }
1423 
bt_sdp_init(void)1424 void bt_sdp_init(void)
1425 {
1426 	static struct bt_l2cap_server server = {
1427 		.psm = SDP_PSM,
1428 		.accept = bt_sdp_accept,
1429 		.sec_level = BT_SECURITY_L0,
1430 	};
1431 	int res;
1432 
1433 	res = bt_l2cap_br_server_register(&server);
1434 	if (res) {
1435 		LOG_ERR("L2CAP server registration failed with error %d", res);
1436 	}
1437 }
1438 
bt_sdp_register_service(struct bt_sdp_record * service)1439 int bt_sdp_register_service(struct bt_sdp_record *service)
1440 {
1441 	uint32_t handle = SDP_SERVICE_HANDLE_BASE;
1442 
1443 	if (!service) {
1444 		LOG_ERR("No service record specified");
1445 		return 0;
1446 	}
1447 
1448 	if (num_services == BT_SDP_MAX_SERVICES) {
1449 		LOG_ERR("Reached max allowed registrations");
1450 		return -ENOMEM;
1451 	}
1452 
1453 	if (db) {
1454 		handle = db->handle + 1;
1455 	}
1456 
1457 	service->next = db;
1458 	service->index = num_services++;
1459 	service->handle = handle;
1460 	*((uint32_t *)(service->attrs[0].val.data)) = handle;
1461 	db = service;
1462 
1463 	LOG_DBG("Service registered at %u", handle);
1464 
1465 	return 0;
1466 }
1467 
1468 #define GET_PARAM(__node) \
1469 	CONTAINER_OF(__node, struct bt_sdp_discover_params, _node)
1470 
1471 /* ServiceSearchAttribute PDU, ref to BT Core 4.2, Vol 3, part B, 4.7.1 */
sdp_client_ssa_search(struct bt_sdp_client * session)1472 static int sdp_client_ssa_search(struct bt_sdp_client *session)
1473 {
1474 	const struct bt_sdp_discover_params *param;
1475 	struct net_buf *buf;
1476 
1477 	/*
1478 	 * Select proper user params, if session->param is invalid it means
1479 	 * getting new UUID from top of to be resolved params list. Otherwise
1480 	 * the context is in a middle of partial SDP PDU responses and cached
1481 	 * value from context can be used.
1482 	 */
1483 	if (!session->param) {
1484 		param = GET_PARAM(sys_slist_peek_head(&session->reqs));
1485 	} else {
1486 		param = session->param;
1487 	}
1488 
1489 	if (!param) {
1490 		LOG_WRN("No UUIDs to be resolved on remote");
1491 		return -EINVAL;
1492 	}
1493 
1494 	buf = bt_sdp_create_pdu();
1495 
1496 	/* BT_SDP_SEQ8 means length of sequence is on additional next byte */
1497 	net_buf_add_u8(buf, BT_SDP_SEQ8);
1498 
1499 	switch (param->uuid->type) {
1500 	case BT_UUID_TYPE_16:
1501 		/* Seq length */
1502 		net_buf_add_u8(buf, 0x03);
1503 		/* Seq type */
1504 		net_buf_add_u8(buf, BT_SDP_UUID16);
1505 		/* Seq value */
1506 		net_buf_add_be16(buf, BT_UUID_16(param->uuid)->val);
1507 		break;
1508 	case BT_UUID_TYPE_32:
1509 		net_buf_add_u8(buf, 0x05);
1510 		net_buf_add_u8(buf, BT_SDP_UUID32);
1511 		net_buf_add_be32(buf, BT_UUID_32(param->uuid)->val);
1512 		break;
1513 	case BT_UUID_TYPE_128:
1514 		net_buf_add_u8(buf, 0x11);
1515 		net_buf_add_u8(buf, BT_SDP_UUID128);
1516 		net_buf_add_mem(buf, BT_UUID_128(param->uuid)->val,
1517 				ARRAY_SIZE(BT_UUID_128(param->uuid)->val));
1518 		break;
1519 	default:
1520 		LOG_ERR("Unknown UUID type %u", param->uuid->type);
1521 		return -EINVAL;
1522 	}
1523 
1524 	/* Set attribute max bytes count to be returned from server */
1525 	net_buf_add_be16(buf, BT_SDP_MAX_ATTR_LEN);
1526 	/*
1527 	 * Sequence definition where data is sequence of elements and where
1528 	 * additional next byte points the size of elements within
1529 	 */
1530 	net_buf_add_u8(buf, BT_SDP_SEQ8);
1531 	net_buf_add_u8(buf, 0x05);
1532 	/* Data element definition for two following 16bits range elements */
1533 	net_buf_add_u8(buf, BT_SDP_UINT32);
1534 	/* Get all attributes. It enables filter out wanted only attributes */
1535 	net_buf_add_be16(buf, 0x0000);
1536 	net_buf_add_be16(buf, 0xffff);
1537 
1538 	/*
1539 	 * Update and validate PDU ContinuationState. Initial SSA Request has
1540 	 * zero length continuation state since no interaction has place with
1541 	 * server so far, otherwise use the original state taken from remote's
1542 	 * last response PDU that is cached by SDP client context.
1543 	 */
1544 	if (session->cstate.length == 0U) {
1545 		net_buf_add_u8(buf, 0x00);
1546 	} else {
1547 		net_buf_add_u8(buf, session->cstate.length);
1548 		net_buf_add_mem(buf, session->cstate.data,
1549 				session->cstate.length);
1550 	}
1551 
1552 	/* Update context param to the one being resolving now */
1553 	session->param = param;
1554 	session->tid++;
1555 
1556 	return bt_sdp_send(&session->chan.chan, buf, BT_SDP_SVC_SEARCH_ATTR_REQ,
1557 			   session->tid);
1558 }
1559 
sdp_client_params_iterator(struct bt_sdp_client * session)1560 static void sdp_client_params_iterator(struct bt_sdp_client *session)
1561 {
1562 	struct bt_l2cap_chan *chan = &session->chan.chan;
1563 	struct bt_sdp_discover_params *param, *tmp;
1564 
1565 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&session->reqs, param, tmp, _node) {
1566 		if (param != session->param) {
1567 			continue;
1568 		}
1569 
1570 		LOG_DBG("");
1571 
1572 		/* Remove already checked UUID node */
1573 		sys_slist_remove(&session->reqs, NULL, &param->_node);
1574 		/* Invalidate cached param in context */
1575 		session->param = NULL;
1576 		/* Reset continuation state in current context */
1577 		(void)memset(&session->cstate, 0, sizeof(session->cstate));
1578 
1579 		/* Check if there's valid next UUID */
1580 		if (!sys_slist_is_empty(&session->reqs)) {
1581 			sdp_client_ssa_search(session);
1582 			return;
1583 		}
1584 
1585 		/* No UUID items, disconnect channel */
1586 		bt_l2cap_chan_disconnect(chan);
1587 		break;
1588 	}
1589 }
1590 
sdp_client_get_total(struct bt_sdp_client * session,struct net_buf * buf,uint16_t * total)1591 static uint16_t sdp_client_get_total(struct bt_sdp_client *session,
1592 				  struct net_buf *buf, uint16_t *total)
1593 {
1594 	uint16_t pulled;
1595 	uint8_t seq;
1596 
1597 	/*
1598 	 * Pull value of total octets of all attributes available to be
1599 	 * collected when response gets completed for given UUID. Such info can
1600 	 * be get from the very first response frame after initial SSA request
1601 	 * was sent. For subsequent calls related to the same SSA request input
1602 	 * buf and in/out function parameters stays neutral.
1603 	 */
1604 	if (session->cstate.length == 0U) {
1605 		seq = net_buf_pull_u8(buf);
1606 		pulled = 1U;
1607 		switch (seq) {
1608 		case BT_SDP_SEQ8:
1609 			*total = net_buf_pull_u8(buf);
1610 			pulled += 1U;
1611 			break;
1612 		case BT_SDP_SEQ16:
1613 			*total = net_buf_pull_be16(buf);
1614 			pulled += 2U;
1615 			break;
1616 		default:
1617 			LOG_WRN("Sequence type 0x%02x not handled", seq);
1618 			*total = 0U;
1619 			break;
1620 		}
1621 
1622 		LOG_DBG("Total %u octets of all attributes", *total);
1623 	} else {
1624 		pulled = 0U;
1625 		*total = 0U;
1626 	}
1627 
1628 	return pulled;
1629 }
1630 
get_record_len(struct net_buf * buf)1631 static uint16_t get_record_len(struct net_buf *buf)
1632 {
1633 	uint16_t len;
1634 	uint8_t seq;
1635 
1636 	seq = net_buf_pull_u8(buf);
1637 
1638 	switch (seq) {
1639 	case BT_SDP_SEQ8:
1640 		len = net_buf_pull_u8(buf);
1641 		break;
1642 	case BT_SDP_SEQ16:
1643 		len = net_buf_pull_be16(buf);
1644 		break;
1645 	default:
1646 		LOG_WRN("Sequence type 0x%02x not handled", seq);
1647 		len = 0U;
1648 		break;
1649 	}
1650 
1651 	LOG_DBG("Record len %u", len);
1652 
1653 	return len;
1654 }
1655 
1656 enum uuid_state {
1657 	UUID_NOT_RESOLVED,
1658 	UUID_RESOLVED,
1659 };
1660 
sdp_client_notify_result(struct bt_sdp_client * session,enum uuid_state state)1661 static void sdp_client_notify_result(struct bt_sdp_client *session,
1662 				     enum uuid_state state)
1663 {
1664 	struct bt_conn *conn = session->chan.chan.conn;
1665 	struct bt_sdp_client_result result;
1666 	uint16_t rec_len;
1667 	uint8_t user_ret;
1668 
1669 	result.uuid = session->param->uuid;
1670 
1671 	if (state == UUID_NOT_RESOLVED) {
1672 		result.resp_buf = NULL;
1673 		result.next_record_hint = false;
1674 		session->param->func(conn, &result);
1675 		return;
1676 	}
1677 
1678 	while (session->rec_buf->len) {
1679 		struct net_buf_simple_state buf_state;
1680 
1681 		rec_len = get_record_len(session->rec_buf);
1682 		/* tell the user about multi record resolution */
1683 		if (session->rec_buf->len > rec_len) {
1684 			result.next_record_hint = true;
1685 		} else {
1686 			result.next_record_hint = false;
1687 		}
1688 
1689 		/* save the original session buffer */
1690 		net_buf_simple_save(&session->rec_buf->b, &buf_state);
1691 		/* initialize internal result buffer instead of memcpy */
1692 		result.resp_buf = session->rec_buf;
1693 		/*
1694 		 * Set user internal result buffer length as same as record
1695 		 * length to fake user. User will see the individual record
1696 		 * length as rec_len instead of whole session rec_buf length.
1697 		 */
1698 		result.resp_buf->len = rec_len;
1699 
1700 		user_ret = session->param->func(conn, &result);
1701 
1702 		/* restore original session buffer */
1703 		net_buf_simple_restore(&session->rec_buf->b, &buf_state);
1704 		/*
1705 		 * sync session buffer data length with next record chunk not
1706 		 * send to user so far
1707 		 */
1708 		net_buf_pull(session->rec_buf, rec_len);
1709 		if (user_ret == BT_SDP_DISCOVER_UUID_STOP) {
1710 			break;
1711 		}
1712 	}
1713 }
1714 
sdp_client_receive(struct bt_l2cap_chan * chan,struct net_buf * buf)1715 static int sdp_client_receive(struct bt_l2cap_chan *chan, struct net_buf *buf)
1716 {
1717 	struct bt_sdp_client *session = SDP_CLIENT_CHAN(chan);
1718 	struct bt_sdp_hdr *hdr;
1719 	struct bt_sdp_pdu_cstate *cstate;
1720 	uint16_t len, tid, frame_len;
1721 	uint16_t total;
1722 
1723 	LOG_DBG("session %p buf %p", session, buf);
1724 
1725 	if (buf->len < sizeof(*hdr)) {
1726 		LOG_ERR("Too small SDP PDU");
1727 		return 0;
1728 	}
1729 
1730 	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
1731 	if (hdr->op_code == BT_SDP_ERROR_RSP) {
1732 		LOG_INF("Error SDP PDU response");
1733 		return 0;
1734 	}
1735 
1736 	len = sys_be16_to_cpu(hdr->param_len);
1737 	tid = sys_be16_to_cpu(hdr->tid);
1738 
1739 	LOG_DBG("SDP PDU tid %u len %u", tid, len);
1740 
1741 	if (buf->len != len) {
1742 		LOG_ERR("SDP PDU length mismatch (%u != %u)", buf->len, len);
1743 		return 0;
1744 	}
1745 
1746 	if (tid != session->tid) {
1747 		LOG_ERR("Mismatch transaction ID value in SDP PDU");
1748 		return 0;
1749 	}
1750 
1751 	switch (hdr->op_code) {
1752 	case BT_SDP_SVC_SEARCH_ATTR_RSP:
1753 		/* Get number of attributes in this frame. */
1754 		frame_len = net_buf_pull_be16(buf);
1755 		/* Check valid buf len for attribute list and cont state */
1756 		if (buf->len < frame_len + SDP_CONT_STATE_LEN_SIZE) {
1757 			LOG_ERR("Invalid frame payload length");
1758 			return 0;
1759 		}
1760 		/* Check valid range of attributes length */
1761 		if (frame_len < 2) {
1762 			LOG_ERR("Invalid attributes data length");
1763 			return 0;
1764 		}
1765 
1766 		/* Get PDU continuation state */
1767 		cstate = (struct bt_sdp_pdu_cstate *)(buf->data + frame_len);
1768 
1769 		if (cstate->length > BT_SDP_MAX_PDU_CSTATE_LEN) {
1770 			LOG_ERR("Invalid SDP PDU Continuation State length %u", cstate->length);
1771 			return 0;
1772 		}
1773 
1774 		if ((frame_len + SDP_CONT_STATE_LEN_SIZE + cstate->length) >
1775 		     buf->len) {
1776 			LOG_ERR("Invalid frame payload length");
1777 			return 0;
1778 		}
1779 
1780 		/*
1781 		 * No record found for given UUID. The check catches case when
1782 		 * current response frame has Continuation State shortest and
1783 		 * valid and this is the first response frame as well.
1784 		 */
1785 		if (frame_len == 2U && cstate->length == 0U &&
1786 		    session->cstate.length == 0U) {
1787 			LOG_DBG("record for UUID 0x%s not found",
1788 				bt_uuid_str(session->param->uuid));
1789 			/* Call user UUID handler */
1790 			sdp_client_notify_result(session, UUID_NOT_RESOLVED);
1791 			net_buf_pull(buf, frame_len + sizeof(cstate->length));
1792 			goto iterate;
1793 		}
1794 
1795 		/* Get total value of all attributes to be collected */
1796 		frame_len -= sdp_client_get_total(session, buf, &total);
1797 
1798 		if (total > net_buf_tailroom(session->rec_buf)) {
1799 			LOG_WRN("Not enough room for getting records data");
1800 			goto iterate;
1801 		}
1802 
1803 		net_buf_add_mem(session->rec_buf, buf->data, frame_len);
1804 		net_buf_pull(buf, frame_len);
1805 
1806 		/*
1807 		 * check if current response says there's next portion to be
1808 		 * fetched
1809 		 */
1810 		if (cstate->length) {
1811 			/* Cache original Continuation State in context */
1812 			memcpy(&session->cstate, cstate,
1813 			       sizeof(struct bt_sdp_pdu_cstate));
1814 
1815 			net_buf_pull(buf, cstate->length +
1816 				     sizeof(cstate->length));
1817 
1818 			/* Request for next portion of attributes data */
1819 			sdp_client_ssa_search(session);
1820 			break;
1821 		}
1822 
1823 		net_buf_pull(buf, sizeof(cstate->length));
1824 
1825 		LOG_DBG("UUID 0x%s resolved", bt_uuid_str(session->param->uuid));
1826 		sdp_client_notify_result(session, UUID_RESOLVED);
1827 iterate:
1828 		/* Get next UUID and start resolving it */
1829 		sdp_client_params_iterator(session);
1830 		break;
1831 	default:
1832 		LOG_DBG("PDU 0x%0x response not handled", hdr->op_code);
1833 		break;
1834 	}
1835 
1836 	return 0;
1837 }
1838 
sdp_client_chan_connect(struct bt_sdp_client * session)1839 static int sdp_client_chan_connect(struct bt_sdp_client *session)
1840 {
1841 	return bt_l2cap_br_chan_connect(session->chan.chan.conn,
1842 					&session->chan.chan, SDP_PSM);
1843 }
1844 
sdp_client_alloc_buf(struct bt_l2cap_chan * chan)1845 static struct net_buf *sdp_client_alloc_buf(struct bt_l2cap_chan *chan)
1846 {
1847 	struct bt_sdp_client *session = SDP_CLIENT_CHAN(chan);
1848 	struct net_buf *buf;
1849 
1850 	LOG_DBG("session %p chan %p", session, chan);
1851 
1852 	session->param = GET_PARAM(sys_slist_peek_head(&session->reqs));
1853 
1854 	buf = net_buf_alloc(session->param->pool, K_FOREVER);
1855 	__ASSERT_NO_MSG(buf);
1856 
1857 	return buf;
1858 }
1859 
sdp_client_connected(struct bt_l2cap_chan * chan)1860 static void sdp_client_connected(struct bt_l2cap_chan *chan)
1861 {
1862 	struct bt_sdp_client *session = SDP_CLIENT_CHAN(chan);
1863 
1864 	LOG_DBG("session %p chan %p connected", session, chan);
1865 
1866 	session->rec_buf = chan->ops->alloc_buf(chan);
1867 
1868 	sdp_client_ssa_search(session);
1869 }
1870 
sdp_client_disconnected(struct bt_l2cap_chan * chan)1871 static void sdp_client_disconnected(struct bt_l2cap_chan *chan)
1872 {
1873 	struct bt_sdp_client *session = SDP_CLIENT_CHAN(chan);
1874 
1875 	LOG_DBG("session %p chan %p disconnected", session, chan);
1876 
1877 	net_buf_unref(session->rec_buf);
1878 
1879 	/*
1880 	 * Reset session excluding L2CAP channel member. Let's the channel
1881 	 * resets autonomous.
1882 	 */
1883 	(void)memset(&session->reqs, 0,
1884 		     sizeof(*session) - sizeof(session->chan));
1885 }
1886 
1887 static const struct bt_l2cap_chan_ops sdp_client_chan_ops = {
1888 		.connected = sdp_client_connected,
1889 		.disconnected = sdp_client_disconnected,
1890 		.recv = sdp_client_receive,
1891 		.alloc_buf = sdp_client_alloc_buf,
1892 };
1893 
sdp_client_new_session(struct bt_conn * conn)1894 static struct bt_sdp_client *sdp_client_new_session(struct bt_conn *conn)
1895 {
1896 	int i;
1897 
1898 	for (i = 0; i < ARRAY_SIZE(bt_sdp_client_pool); i++) {
1899 		struct bt_sdp_client *session = &bt_sdp_client_pool[i];
1900 		int err;
1901 
1902 		if (session->chan.chan.conn) {
1903 			continue;
1904 		}
1905 
1906 		sys_slist_init(&session->reqs);
1907 
1908 		session->chan.chan.ops = &sdp_client_chan_ops;
1909 		session->chan.chan.conn = conn;
1910 		session->chan.rx.mtu = SDP_CLIENT_MTU;
1911 
1912 		err = sdp_client_chan_connect(session);
1913 		if (err) {
1914 			(void)memset(session, 0, sizeof(*session));
1915 			LOG_ERR("Cannot connect %d", err);
1916 			return NULL;
1917 		}
1918 
1919 		return session;
1920 	}
1921 
1922 	LOG_ERR("No available SDP client context");
1923 
1924 	return NULL;
1925 }
1926 
sdp_client_get_session(struct bt_conn * conn)1927 static struct bt_sdp_client *sdp_client_get_session(struct bt_conn *conn)
1928 {
1929 	int i;
1930 
1931 	for (i = 0; i < ARRAY_SIZE(bt_sdp_client_pool); i++) {
1932 		if (bt_sdp_client_pool[i].chan.chan.conn == conn) {
1933 			return &bt_sdp_client_pool[i];
1934 		}
1935 	}
1936 
1937 	/*
1938 	 * Try to allocate session context since not found in pool and attempt
1939 	 * connect to remote SDP endpoint.
1940 	 */
1941 	return sdp_client_new_session(conn);
1942 }
1943 
bt_sdp_discover(struct bt_conn * conn,const struct bt_sdp_discover_params * params)1944 int bt_sdp_discover(struct bt_conn *conn,
1945 		    const struct bt_sdp_discover_params *params)
1946 {
1947 	struct bt_sdp_client *session;
1948 
1949 	if (!params || !params->uuid || !params->func || !params->pool) {
1950 		LOG_WRN("Invalid user params");
1951 		return -EINVAL;
1952 	}
1953 
1954 	session = sdp_client_get_session(conn);
1955 	if (!session) {
1956 		return -ENOMEM;
1957 	}
1958 
1959 	sys_slist_append(&session->reqs, (sys_snode_t *)&params->_node);
1960 
1961 	return 0;
1962 }
1963 
1964 /* Helper getting length of data determined by DTD for integers */
sdp_get_int_len(const uint8_t * data,size_t len)1965 static inline ssize_t sdp_get_int_len(const uint8_t *data, size_t len)
1966 {
1967 	BT_ASSERT(data);
1968 
1969 	switch (data[0]) {
1970 	case BT_SDP_DATA_NIL:
1971 		return 1;
1972 	case BT_SDP_BOOL:
1973 	case BT_SDP_INT8:
1974 	case BT_SDP_UINT8:
1975 		if (len < 2) {
1976 			break;
1977 		}
1978 
1979 		return 2;
1980 	case BT_SDP_INT16:
1981 	case BT_SDP_UINT16:
1982 		if (len < 3) {
1983 			break;
1984 		}
1985 
1986 		return 3;
1987 	case BT_SDP_INT32:
1988 	case BT_SDP_UINT32:
1989 		if (len < 5) {
1990 			break;
1991 		}
1992 
1993 		return 5;
1994 	case BT_SDP_INT64:
1995 	case BT_SDP_UINT64:
1996 		if (len < 9) {
1997 			break;
1998 		}
1999 
2000 		return 9;
2001 	case BT_SDP_INT128:
2002 	case BT_SDP_UINT128:
2003 	default:
2004 		LOG_ERR("Invalid/unhandled DTD 0x%02x", data[0]);
2005 		return -EINVAL;
2006 	}
2007 
2008 	LOG_ERR("Too short buffer length %zu", len);
2009 	return -EMSGSIZE;
2010 }
2011 
2012 /* Helper getting length of data determined by DTD for UUID */
sdp_get_uuid_len(const uint8_t * data,size_t len)2013 static inline ssize_t sdp_get_uuid_len(const uint8_t *data, size_t len)
2014 {
2015 	BT_ASSERT(data);
2016 
2017 	switch (data[0]) {
2018 	case BT_SDP_UUID16:
2019 		if (len < 3) {
2020 			break;
2021 		}
2022 
2023 		return 3;
2024 	case BT_SDP_UUID32:
2025 		if (len < 5) {
2026 			break;
2027 		}
2028 
2029 		return 5;
2030 	case BT_SDP_UUID128:
2031 	default:
2032 		LOG_ERR("Invalid/unhandled DTD 0x%02x", data[0]);
2033 		return -EINVAL;
2034 	}
2035 
2036 	LOG_ERR("Too short buffer length %zu", len);
2037 	return -EMSGSIZE;
2038 }
2039 
2040 /* Helper getting length of data determined by DTD for strings */
sdp_get_str_len(const uint8_t * data,size_t len)2041 static inline ssize_t sdp_get_str_len(const uint8_t *data, size_t len)
2042 {
2043 	const uint8_t *pnext;
2044 
2045 	BT_ASSERT(data);
2046 
2047 	/* validate len for pnext safe use to read next 8bit value */
2048 	if (len < 2) {
2049 		goto err;
2050 	}
2051 
2052 	pnext = data + sizeof(uint8_t);
2053 
2054 	switch (data[0]) {
2055 	case BT_SDP_TEXT_STR8:
2056 	case BT_SDP_URL_STR8:
2057 		if (len < (2 + pnext[0])) {
2058 			break;
2059 		}
2060 
2061 		return 2 + pnext[0];
2062 	case BT_SDP_TEXT_STR16:
2063 	case BT_SDP_URL_STR16:
2064 		/* validate len for pnext safe use to read 16bit value */
2065 		if (len < 3) {
2066 			break;
2067 		}
2068 
2069 		if (len < (3 + sys_get_be16(pnext))) {
2070 			break;
2071 		}
2072 
2073 		return 3 + sys_get_be16(pnext);
2074 	case BT_SDP_TEXT_STR32:
2075 	case BT_SDP_URL_STR32:
2076 	default:
2077 		LOG_ERR("Invalid/unhandled DTD 0x%02x", data[0]);
2078 		return -EINVAL;
2079 	}
2080 err:
2081 	LOG_ERR("Too short buffer length %zu", len);
2082 	return -EMSGSIZE;
2083 }
2084 
2085 /* Helper getting length of data determined by DTD for sequences */
sdp_get_seq_len(const uint8_t * data,size_t len)2086 static inline ssize_t sdp_get_seq_len(const uint8_t *data, size_t len)
2087 {
2088 	const uint8_t *pnext;
2089 
2090 	BT_ASSERT(data);
2091 
2092 	/* validate len for pnext safe use to read 8bit bit value */
2093 	if (len < 2) {
2094 		goto err;
2095 	}
2096 
2097 	pnext = data + sizeof(uint8_t);
2098 
2099 	switch (data[0]) {
2100 	case BT_SDP_SEQ8:
2101 	case BT_SDP_ALT8:
2102 		if (len < (2 + pnext[0])) {
2103 			break;
2104 		}
2105 
2106 		return 2 + pnext[0];
2107 	case BT_SDP_SEQ16:
2108 	case BT_SDP_ALT16:
2109 		/* validate len for pnext safe use to read 16bit value */
2110 		if (len < 3) {
2111 			break;
2112 		}
2113 
2114 		if (len < (3 + sys_get_be16(pnext))) {
2115 			break;
2116 		}
2117 
2118 		return 3 + sys_get_be16(pnext);
2119 	case BT_SDP_SEQ32:
2120 	case BT_SDP_ALT32:
2121 	default:
2122 		LOG_ERR("Invalid/unhandled DTD 0x%02x", data[0]);
2123 		return -EINVAL;
2124 	}
2125 err:
2126 	LOG_ERR("Too short buffer length %zu", len);
2127 	return -EMSGSIZE;
2128 }
2129 
2130 /* Helper getting length of attribute value data */
sdp_get_attr_value_len(const uint8_t * data,size_t len)2131 static ssize_t sdp_get_attr_value_len(const uint8_t *data, size_t len)
2132 {
2133 	BT_ASSERT(data);
2134 
2135 	LOG_DBG("Attr val DTD 0x%02x", data[0]);
2136 
2137 	if (len < 1) {
2138 		goto err;
2139 	}
2140 
2141 	switch (data[0]) {
2142 	case BT_SDP_DATA_NIL:
2143 	case BT_SDP_BOOL:
2144 	case BT_SDP_UINT8:
2145 	case BT_SDP_UINT16:
2146 	case BT_SDP_UINT32:
2147 	case BT_SDP_UINT64:
2148 	case BT_SDP_UINT128:
2149 	case BT_SDP_INT8:
2150 	case BT_SDP_INT16:
2151 	case BT_SDP_INT32:
2152 	case BT_SDP_INT64:
2153 	case BT_SDP_INT128:
2154 		return sdp_get_int_len(data, len);
2155 	case BT_SDP_UUID16:
2156 	case BT_SDP_UUID32:
2157 	case BT_SDP_UUID128:
2158 		return sdp_get_uuid_len(data, len);
2159 	case BT_SDP_TEXT_STR8:
2160 	case BT_SDP_TEXT_STR16:
2161 	case BT_SDP_TEXT_STR32:
2162 	case BT_SDP_URL_STR8:
2163 	case BT_SDP_URL_STR16:
2164 	case BT_SDP_URL_STR32:
2165 		return sdp_get_str_len(data, len);
2166 	case BT_SDP_SEQ8:
2167 	case BT_SDP_SEQ16:
2168 	case BT_SDP_SEQ32:
2169 	case BT_SDP_ALT8:
2170 	case BT_SDP_ALT16:
2171 	case BT_SDP_ALT32:
2172 		return sdp_get_seq_len(data, len);
2173 	default:
2174 		LOG_ERR("Unknown DTD 0x%02x", data[0]);
2175 		return -EINVAL;
2176 	}
2177 err:
2178 	LOG_ERR("Too short buffer length %zu", len);
2179 	return -EMSGSIZE;
2180 
2181 }
2182 
2183 /* Type holding UUID item and related to it specific information. */
2184 struct bt_sdp_uuid_desc {
2185 	union {
2186 		struct bt_uuid    uuid;
2187 		struct bt_uuid_16 uuid16;
2188 		struct bt_uuid_32 uuid32;
2189 	      };
2190 	uint16_t                     attr_id;
2191 	uint8_t                     *params;
2192 	uint16_t                     params_len;
2193 };
2194 
2195 /* Generic attribute item collector. */
2196 struct bt_sdp_attr_item {
2197 	/*  Attribute identifier. */
2198 	uint16_t                  attr_id;
2199 	/*  Address of beginning attribute value taken from original buffer
2200 	 *  holding response from server.
2201 	 */
2202 	uint8_t                  *val;
2203 	/*  Says about the length of attribute value. */
2204 	uint16_t                  len;
2205 };
2206 
bt_sdp_get_attr(const struct net_buf * buf,struct bt_sdp_attr_item * attr,uint16_t attr_id)2207 static int bt_sdp_get_attr(const struct net_buf *buf,
2208 			   struct bt_sdp_attr_item *attr, uint16_t attr_id)
2209 {
2210 	uint8_t *data;
2211 	uint16_t id;
2212 
2213 	data = buf->data;
2214 	while (data - buf->data < buf->len) {
2215 		ssize_t dlen;
2216 
2217 		/* data need to point to attribute id descriptor field (DTD)*/
2218 		if (data[0] != BT_SDP_UINT16) {
2219 			LOG_ERR("Invalid descriptor 0x%02x", data[0]);
2220 			return -EINVAL;
2221 		}
2222 
2223 		data += sizeof(uint8_t);
2224 		if ((data + sizeof(id) - buf->data) > buf->len) {
2225 			return -EINVAL;
2226 		}
2227 		id = sys_get_be16(data);
2228 		LOG_DBG("Attribute ID 0x%04x", id);
2229 		data += sizeof(uint16_t);
2230 
2231 		dlen = sdp_get_attr_value_len(data,
2232 					      buf->len - (data - buf->data));
2233 		if (dlen < 0) {
2234 			LOG_ERR("Invalid attribute value data");
2235 			return -EINVAL;
2236 		}
2237 
2238 		if (id == attr_id) {
2239 			LOG_DBG("Attribute ID 0x%04x Value found", id);
2240 			/*
2241 			 * Initialize attribute value buffer data using selected
2242 			 * data slice from original buffer.
2243 			 */
2244 			attr->val = data;
2245 			attr->len = dlen;
2246 			attr->attr_id = id;
2247 			return 0;
2248 		}
2249 
2250 		data += dlen;
2251 	}
2252 
2253 	return -ENOENT;
2254 }
2255 
2256 /* reads SEQ item length, moves input buffer data reader forward */
sdp_get_seq_len_item(uint8_t ** data,size_t len)2257 static ssize_t sdp_get_seq_len_item(uint8_t **data, size_t len)
2258 {
2259 	const uint8_t *pnext;
2260 
2261 	BT_ASSERT(data);
2262 	BT_ASSERT(*data);
2263 
2264 	/* validate len for pnext safe use to read 8bit bit value */
2265 	if (len < 2) {
2266 		goto err;
2267 	}
2268 
2269 	pnext = *data + sizeof(uint8_t);
2270 
2271 	switch (*data[0]) {
2272 	case BT_SDP_SEQ8:
2273 		if (len < (2 + pnext[0])) {
2274 			break;
2275 		}
2276 
2277 		*data += 2;
2278 		return pnext[0];
2279 	case BT_SDP_SEQ16:
2280 		/* validate len for pnext safe use to read 16bit value */
2281 		if (len < 3) {
2282 			break;
2283 		}
2284 
2285 		if (len < (3 + sys_get_be16(pnext))) {
2286 			break;
2287 		}
2288 
2289 		*data += 3;
2290 		return sys_get_be16(pnext);
2291 	case BT_SDP_SEQ32:
2292 		/* validate len for pnext safe use to read 32bit value */
2293 		if (len < 5) {
2294 			break;
2295 		}
2296 
2297 		if (len < (5 + sys_get_be32(pnext))) {
2298 			break;
2299 		}
2300 
2301 		*data += 5;
2302 		return sys_get_be32(pnext);
2303 	default:
2304 		LOG_ERR("Invalid/unhandled DTD 0x%02x", *data[0]);
2305 		return -EINVAL;
2306 	}
2307 err:
2308 	LOG_ERR("Too short buffer length %zu", len);
2309 	return -EMSGSIZE;
2310 }
2311 
sdp_loop_seqs(uint8_t ** data,size_t len)2312 static int sdp_loop_seqs(uint8_t **data, size_t len)
2313 {
2314 	ssize_t slen;
2315 	ssize_t pre_slen;
2316 	uint8_t *end;
2317 
2318 	if (len <= 0) {
2319 		return -EMSGSIZE;
2320 	}
2321 
2322 	pre_slen = -EINVAL;
2323 	slen = -EINVAL;
2324 	end = *data + len;
2325 	/* loop all the SEQ */
2326 	while (*data < end) {
2327 		/* how long is current UUID's item data associated to */
2328 		slen = sdp_get_seq_len_item(data, end - *data);
2329 		if (slen < 0) {
2330 			break;
2331 		}
2332 		pre_slen = slen;
2333 	}
2334 
2335 	/* return the last seq len */
2336 	if (pre_slen < 0) {
2337 		return slen;
2338 	}
2339 
2340 	return pre_slen;
2341 }
2342 
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)2343 static int sdp_get_uuid_data(const struct bt_sdp_attr_item *attr,
2344 			     struct bt_sdp_uuid_desc *pd,
2345 			     uint16_t proto_profile,
2346 			     uint8_t proto_profile_index)
2347 {
2348 	/* get start address of attribute value */
2349 	uint8_t *p = attr->val;
2350 	ssize_t slen;
2351 
2352 	BT_ASSERT(p);
2353 
2354 	/* start reading stacked UUIDs in analyzed sequences tree */
2355 	while (p - attr->val < attr->len) {
2356 		size_t to_end, left = 0;
2357 		uint8_t dtd;
2358 
2359 		/* to_end tells how far to the end of input buffer */
2360 		to_end = attr->len - (p - attr->val);
2361 		/* loop all the SEQ, get the last SEQ len */
2362 		slen = sdp_loop_seqs(&p, to_end);
2363 
2364 		if (slen < 0) {
2365 			return slen;
2366 		}
2367 
2368 		/* left tells how far is to the end of current UUID */
2369 		left = slen;
2370 
2371 		/* check if at least DTD + UUID16 can be read safely */
2372 		if (left < (sizeof(dtd) + BT_UUID_SIZE_16)) {
2373 			return -EMSGSIZE;
2374 		}
2375 
2376 		/* check DTD and get stacked UUID value */
2377 		dtd = p[0];
2378 		p++;
2379 		/* include last DTD in p[0] size itself updating left */
2380 		left -= sizeof(dtd);
2381 		switch (dtd) {
2382 		case BT_SDP_UUID16:
2383 			memcpy(&pd->uuid16,
2384 				BT_UUID_DECLARE_16(sys_get_be16(p)),
2385 				sizeof(struct bt_uuid_16));
2386 			p += sizeof(uint16_t);
2387 			left -= sizeof(uint16_t);
2388 			break;
2389 		case BT_SDP_UUID32:
2390 			/* check if valid UUID32 can be read safely */
2391 			if (left < BT_UUID_SIZE_32) {
2392 				return -EMSGSIZE;
2393 			}
2394 
2395 			memcpy(&pd->uuid32,
2396 				BT_UUID_DECLARE_32(sys_get_be32(p)),
2397 				sizeof(struct bt_uuid_32));
2398 			p += sizeof(BT_UUID_SIZE_32);
2399 			left -= sizeof(BT_UUID_SIZE_32);
2400 			break;
2401 		default:
2402 			LOG_ERR("Invalid/unhandled DTD 0x%02x\n", dtd);
2403 			return -EINVAL;
2404 		}
2405 
2406 		/*
2407 			* Check if current UUID value matches input one given by user.
2408 			* If found save it's location and length and return.
2409 			*/
2410 		if ((proto_profile == BT_UUID_16(&pd->uuid)->val) ||
2411 			(proto_profile == BT_UUID_32(&pd->uuid)->val)) {
2412 			pd->params = p;
2413 			pd->params_len = left;
2414 
2415 			LOG_DBG("UUID 0x%s found", bt_uuid_str(&pd->uuid));
2416 			if (proto_profile_index > 0U) {
2417 				proto_profile_index--;
2418 				p += left;
2419 				continue;
2420 			} else {
2421 				return 0;
2422 			}
2423 		}
2424 
2425 		/* skip left octets to point beginning of next UUID in tree */
2426 		p += left;
2427 	}
2428 
2429 	LOG_DBG("Value 0x%04x index %d not found", proto_profile, proto_profile_index);
2430 	return -ENOENT;
2431 }
2432 
2433 /*
2434  * Helper extracting specific parameters associated with UUID node given in
2435  * protocol descriptor list or profile descriptor list.
2436  */
sdp_get_param_item(struct bt_sdp_uuid_desc * pd_item,uint16_t * param)2437 static int sdp_get_param_item(struct bt_sdp_uuid_desc *pd_item, uint16_t *param)
2438 {
2439 	const uint8_t *p = pd_item->params;
2440 	bool len_err = false;
2441 
2442 	BT_ASSERT(p);
2443 
2444 	LOG_DBG("Getting UUID's 0x%s params", bt_uuid_str(&pd_item->uuid));
2445 
2446 	switch (p[0]) {
2447 	case BT_SDP_UINT8:
2448 		/* check if 8bits value can be read safely */
2449 		if (pd_item->params_len < 2) {
2450 			len_err = true;
2451 			break;
2452 		}
2453 		*param = (++p)[0];
2454 		p += sizeof(uint8_t);
2455 		break;
2456 	case BT_SDP_UINT16:
2457 		/* check if 16bits value can be read safely */
2458 		if (pd_item->params_len < 3) {
2459 			len_err = true;
2460 			break;
2461 		}
2462 		*param = sys_get_be16(++p);
2463 		p += sizeof(uint16_t);
2464 		break;
2465 	case BT_SDP_UINT32:
2466 		/* check if 32bits value can be read safely */
2467 		if (pd_item->params_len < 5) {
2468 			len_err = true;
2469 			break;
2470 		}
2471 		*param = sys_get_be32(++p);
2472 		p += sizeof(uint32_t);
2473 		break;
2474 	default:
2475 		LOG_ERR("Invalid/unhandled DTD 0x%02x\n", p[0]);
2476 		return -EINVAL;
2477 	}
2478 	/*
2479 	 * Check if no more data than already read is associated with UUID. In
2480 	 * valid case after getting parameter we should reach data buf end.
2481 	 */
2482 	if (p - pd_item->params != pd_item->params_len || len_err) {
2483 		LOG_DBG("Invalid param buffer length");
2484 		return -EMSGSIZE;
2485 	}
2486 
2487 	return 0;
2488 }
2489 
bt_sdp_get_proto_param(const struct net_buf * buf,enum bt_sdp_proto proto,uint16_t * param)2490 int bt_sdp_get_proto_param(const struct net_buf *buf, enum bt_sdp_proto proto,
2491 			   uint16_t *param)
2492 {
2493 	struct bt_sdp_attr_item attr;
2494 	struct bt_sdp_uuid_desc pd;
2495 	int res;
2496 
2497 	if (proto != BT_SDP_PROTO_RFCOMM && proto != BT_SDP_PROTO_L2CAP) {
2498 		LOG_ERR("Invalid protocol specifier");
2499 		return -EINVAL;
2500 	}
2501 
2502 	res = bt_sdp_get_attr(buf, &attr, BT_SDP_ATTR_PROTO_DESC_LIST);
2503 	if (res < 0) {
2504 		LOG_WRN("Attribute 0x%04x not found, err %d", BT_SDP_ATTR_PROTO_DESC_LIST, res);
2505 		return res;
2506 	}
2507 
2508 	res = sdp_get_uuid_data(&attr, &pd, proto, 0U);
2509 	if (res < 0) {
2510 		LOG_WRN("Protocol specifier 0x%04x not found, err %d", proto, res);
2511 		return res;
2512 	}
2513 
2514 	return sdp_get_param_item(&pd, param);
2515 }
2516 
bt_sdp_get_addl_proto_param(const struct net_buf * buf,enum bt_sdp_proto proto,uint8_t param_index,uint16_t * param)2517 int bt_sdp_get_addl_proto_param(const struct net_buf *buf, enum bt_sdp_proto proto,
2518 				uint8_t param_index, uint16_t *param)
2519 {
2520 	struct bt_sdp_attr_item attr;
2521 	struct bt_sdp_uuid_desc pd;
2522 	int res;
2523 
2524 	if (proto != BT_SDP_PROTO_RFCOMM && proto != BT_SDP_PROTO_L2CAP) {
2525 		LOG_ERR("Invalid protocol specifier");
2526 		return -EINVAL;
2527 	}
2528 
2529 	res = bt_sdp_get_attr(buf, &attr, BT_SDP_ATTR_ADD_PROTO_DESC_LIST);
2530 	if (res < 0) {
2531 		LOG_WRN("Attribute 0x%04x not found, err %d", BT_SDP_ATTR_PROTO_DESC_LIST, res);
2532 		return res;
2533 	}
2534 
2535 	res = sdp_get_uuid_data(&attr, &pd, proto, param_index);
2536 	if (res < 0) {
2537 		LOG_WRN("Protocol specifier 0x%04x not found, err %d", proto, res);
2538 		return res;
2539 	}
2540 
2541 	return sdp_get_param_item(&pd, param);
2542 }
2543 
bt_sdp_get_profile_version(const struct net_buf * buf,uint16_t profile,uint16_t * version)2544 int bt_sdp_get_profile_version(const struct net_buf *buf, uint16_t profile,
2545 			       uint16_t *version)
2546 {
2547 	struct bt_sdp_attr_item attr;
2548 	struct bt_sdp_uuid_desc pd;
2549 	int res;
2550 
2551 	res = bt_sdp_get_attr(buf, &attr, BT_SDP_ATTR_PROFILE_DESC_LIST);
2552 	if (res < 0) {
2553 		LOG_WRN("Attribute 0x%04x not found, err %d", BT_SDP_ATTR_PROFILE_DESC_LIST, res);
2554 		return res;
2555 	}
2556 
2557 	res = sdp_get_uuid_data(&attr, &pd, profile, 0U);
2558 	if (res < 0) {
2559 		LOG_WRN("Profile 0x%04x not found, err %d", profile, res);
2560 		return res;
2561 	}
2562 
2563 	return sdp_get_param_item(&pd, version);
2564 }
2565 
bt_sdp_get_features(const struct net_buf * buf,uint16_t * features)2566 int bt_sdp_get_features(const struct net_buf *buf, uint16_t *features)
2567 {
2568 	struct bt_sdp_attr_item attr;
2569 	const uint8_t *p;
2570 	int res;
2571 
2572 	res = bt_sdp_get_attr(buf, &attr, BT_SDP_ATTR_SUPPORTED_FEATURES);
2573 	if (res < 0) {
2574 		LOG_WRN("Attribute 0x%04x not found, err %d", BT_SDP_ATTR_SUPPORTED_FEATURES, res);
2575 		return res;
2576 	}
2577 
2578 	p = attr.val;
2579 	BT_ASSERT(p);
2580 
2581 	if (p[0] != BT_SDP_UINT16) {
2582 		LOG_ERR("Invalid DTD 0x%02x", p[0]);
2583 		return -EINVAL;
2584 	}
2585 
2586 	/* assert 16bit can be read safely */
2587 	if (attr.len < 3) {
2588 		LOG_ERR("Data length too short %u", attr.len);
2589 		return -EMSGSIZE;
2590 	}
2591 
2592 	*features = sys_get_be16(++p);
2593 	p += sizeof(uint16_t);
2594 
2595 	if (p - attr.val != attr.len) {
2596 		LOG_ERR("Invalid data length %u", attr.len);
2597 		return -EMSGSIZE;
2598 	}
2599 
2600 	return 0;
2601 }
2602