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