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