• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2001-2002  Nokia Corporation
6  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
7  *  Copyright (C) 2002-2008  Marcel Holtmann <marcel@holtmann.org>
8  *  Copyright (C) 2002-2003  Stephen Crane <steve.crane@rococosoft.com>
9  *
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24  *
25  */
26 
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 
31 #include <stdio.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <limits.h>
37 #include <string.h>
38 #include <syslog.h>
39 #include <sys/socket.h>
40 #include <sys/un.h>
41 #include <sys/time.h>
42 #include <sys/types.h>
43 
44 #include <bluetooth/bluetooth.h>
45 #include <bluetooth/hci.h>
46 #include <bluetooth/hci_lib.h>
47 #include <bluetooth/l2cap.h>
48 #include <bluetooth/sdp.h>
49 #include <bluetooth/sdp_lib.h>
50 
51 #include <netinet/in.h>
52 
53 #define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg)
54 #define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg)
55 
56 #ifdef SDP_DEBUG
57 #define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg)
58 #else
59 #define SDPDBG(fmt...)
60 #endif
61 
62 #if __BYTE_ORDER == __BIG_ENDIAN
63 #define ntoh64(x) (x)
ntoh128(uint128_t * src,uint128_t * dst)64 static inline void ntoh128(uint128_t *src, uint128_t *dst)
65 {
66 	int i;
67 	for (i = 0; i < 16; i++)
68 		dst->data[i] = src->data[i];
69 }
70 #else
ntoh64(uint64_t n)71 static inline uint64_t ntoh64(uint64_t n)
72 {
73 	uint64_t h;
74 	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
75 	h = ntohl(n >> 32);
76 	h |= tmp << 32;
77 	return h;
78 }
ntoh128(uint128_t * src,uint128_t * dst)79 static inline void ntoh128(uint128_t *src, uint128_t *dst)
80 {
81 	int i;
82 	for (i = 0; i < 16; i++)
83 		dst->data[15 - i] = src->data[i];
84 }
85 #endif
86 
87 #define hton64(x)     ntoh64(x)
88 #define hton128(x, y) ntoh128(x, y)
89 
90 #define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB"
91 
92 static uint128_t bluetooth_base_uuid = {
93 	.data = {	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
94 			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
95 };
96 
97 #define SDP_MAX_ATTR_LEN 65535
98 
99 /* Message structure. */
100 struct tupla {
101 	int index;
102 	char *str;
103 };
104 
105 static struct tupla Protocol[] = {
106 	{ SDP_UUID,		"SDP"		},
107 	{ UDP_UUID,		"UDP"		},
108 	{ RFCOMM_UUID,		"RFCOMM"	},
109 	{ TCP_UUID,		"TCP"		},
110 	{ TCS_BIN_UUID,		"TCS-BIN"	},
111 	{ TCS_AT_UUID,		"TCS-AT"	},
112 	{ OBEX_UUID,		"OBEX"		},
113 	{ IP_UUID,		"IP"		},
114 	{ FTP_UUID,		"FTP"		},
115 	{ HTTP_UUID,		"HTTP"		},
116 	{ WSP_UUID,		"WSP"		},
117 	{ BNEP_UUID,		"BNEP"		},
118 	{ UPNP_UUID,		"UPNP"		},
119 	{ HIDP_UUID,		"HIDP"		},
120 	{ HCRP_CTRL_UUID,	"HCRP-Ctrl"	},
121 	{ HCRP_DATA_UUID,	"HCRP-Data"	},
122 	{ HCRP_NOTE_UUID,	"HCRP-Notify"	},
123 	{ AVCTP_UUID,		"AVCTP"		},
124 	{ AVDTP_UUID,		"AVDTP"		},
125 	{ CMTP_UUID,		"CMTP"		},
126 	{ UDI_UUID,		"UDI"		},
127 	{ MCAP_CTRL_UUID,	"MCAP-Ctrl"	},
128 	{ MCAP_DATA_UUID,	"MCAP-Data"	},
129 	{ L2CAP_UUID,		"L2CAP"		},
130 	{ 0 }
131 };
132 
133 static struct tupla ServiceClass[] = {
134 	{ SDP_SERVER_SVCLASS_ID,		"SDP Server"			},
135 	{ BROWSE_GRP_DESC_SVCLASS_ID,		"Browse Group Descriptor"	},
136 	{ PUBLIC_BROWSE_GROUP,			"Public Browse Group"		},
137 	{ SERIAL_PORT_SVCLASS_ID,		"Serial Port"			},
138 	{ LAN_ACCESS_SVCLASS_ID,		"LAN Access Using PPP"		},
139 	{ DIALUP_NET_SVCLASS_ID,		"Dialup Networking"		},
140 	{ IRMC_SYNC_SVCLASS_ID,			"IrMC Sync"			},
141 	{ OBEX_OBJPUSH_SVCLASS_ID,		"OBEX Object Push"		},
142 	{ OBEX_FILETRANS_SVCLASS_ID,		"OBEX File Transfer"		},
143 	{ IRMC_SYNC_CMD_SVCLASS_ID,		"IrMC Sync Command"		},
144 	{ HEADSET_SVCLASS_ID,			"Headset"			},
145 	{ CORDLESS_TELEPHONY_SVCLASS_ID,	"Cordless Telephony"		},
146 	{ AUDIO_SOURCE_SVCLASS_ID,		"Audio Source"			},
147 	{ AUDIO_SINK_SVCLASS_ID,		"Audio Sink"			},
148 	{ AV_REMOTE_TARGET_SVCLASS_ID,		"AV Remote Target"		},
149 	{ ADVANCED_AUDIO_SVCLASS_ID,		"Advanced Audio"		},
150 	{ AV_REMOTE_SVCLASS_ID,			"AV Remote"			},
151 	{ VIDEO_CONF_SVCLASS_ID,		"Video Conferencing"		},
152 	{ INTERCOM_SVCLASS_ID,			"Intercom"			},
153 	{ FAX_SVCLASS_ID,			"Fax"				},
154 	{ HEADSET_AGW_SVCLASS_ID,		"Headset Audio Gateway"		},
155 	{ WAP_SVCLASS_ID,			"WAP"				},
156 	{ WAP_CLIENT_SVCLASS_ID,		"WAP Client"			},
157 	{ PANU_SVCLASS_ID,			"PAN User"			},
158 	{ NAP_SVCLASS_ID,			"Network Access Point"		},
159 	{ GN_SVCLASS_ID,			"PAN Group Network"		},
160 	{ DIRECT_PRINTING_SVCLASS_ID,		"Direct Printing"		},
161 	{ REFERENCE_PRINTING_SVCLASS_ID,	"Reference Printing"		},
162 	{ IMAGING_SVCLASS_ID,			"Imaging"			},
163 	{ IMAGING_RESPONDER_SVCLASS_ID,		"Imaging Responder"		},
164 	{ IMAGING_ARCHIVE_SVCLASS_ID,		"Imaging Automatic Archive"	},
165 	{ IMAGING_REFOBJS_SVCLASS_ID,		"Imaging Referenced Objects"	},
166 	{ HANDSFREE_SVCLASS_ID,			"Handsfree"			},
167 	{ HANDSFREE_AGW_SVCLASS_ID,		"Handsfree Audio Gateway"	},
168 	{ DIRECT_PRT_REFOBJS_SVCLASS_ID,	"Direct Printing Ref. Objects"	},
169 	{ REFLECTED_UI_SVCLASS_ID,		"Reflected UI"			},
170 	{ BASIC_PRINTING_SVCLASS_ID,		"Basic Printing"		},
171 	{ PRINTING_STATUS_SVCLASS_ID,		"Printing Status"		},
172 	{ HID_SVCLASS_ID,			"Human Interface Device"	},
173 	{ HCR_SVCLASS_ID,			"Hardcopy Cable Replacement"	},
174 	{ HCR_PRINT_SVCLASS_ID,			"HCR Print"			},
175 	{ HCR_SCAN_SVCLASS_ID,			"HCR Scan"			},
176 	{ CIP_SVCLASS_ID,			"Common ISDN Access"		},
177 	{ VIDEO_CONF_GW_SVCLASS_ID,		"Video Conferencing Gateway"	},
178 	{ UDI_MT_SVCLASS_ID,			"UDI MT"			},
179 	{ UDI_TA_SVCLASS_ID,			"UDI TA"			},
180 	{ AV_SVCLASS_ID,			"Audio/Video"			},
181 	{ SAP_SVCLASS_ID,			"SIM Access"			},
182 	{ PBAP_PCE_SVCLASS_ID,			"Phonebook Access - PCE"	},
183 	{ PBAP_PSE_SVCLASS_ID,			"Phonebook Access - PSE"	},
184 	{ PBAP_SVCLASS_ID,			"Phonebook Access"		},
185 	{ PNP_INFO_SVCLASS_ID,			"PnP Information"		},
186 	{ GENERIC_NETWORKING_SVCLASS_ID,	"Generic Networking"		},
187 	{ GENERIC_FILETRANS_SVCLASS_ID,		"Generic File Transfer"		},
188 	{ GENERIC_AUDIO_SVCLASS_ID,		"Generic Audio"			},
189 	{ GENERIC_TELEPHONY_SVCLASS_ID,		"Generic Telephony"		},
190 	{ UPNP_SVCLASS_ID,			"UPnP"				},
191 	{ UPNP_IP_SVCLASS_ID,			"UPnP IP"			},
192 	{ UPNP_PAN_SVCLASS_ID,			"UPnP PAN"			},
193 	{ UPNP_LAP_SVCLASS_ID,			"UPnP LAP"			},
194 	{ UPNP_L2CAP_SVCLASS_ID,		"UPnP L2CAP"			},
195 	{ VIDEO_SOURCE_SVCLASS_ID,		"Video Source"			},
196 	{ VIDEO_SINK_SVCLASS_ID,		"Video Sink"			},
197 	{ VIDEO_DISTRIBUTION_SVCLASS_ID,	"Video Distribution"		},
198 	{ MDP_SVCLASS_ID,			"MDP"				},
199 	{ MDP_SOURCE_SVCLASS_ID,		"MDP Source"			},
200 	{ MDP_SINK_SVCLASS_ID,			"MDP Sink"			},
201 	{ APPLE_AGENT_SVCLASS_ID,		"Apple Agent"			},
202 	{ 0 }
203 };
204 
205 #define Profile ServiceClass
206 
string_lookup(struct tupla * pt0,int index)207 static char *string_lookup(struct tupla *pt0, int index)
208 {
209 	struct tupla *pt;
210 
211 	for (pt = pt0; pt->index; pt++)
212 		if (pt->index == index)
213 			return pt->str;
214 
215 	return "";
216 }
217 
string_lookup_uuid(struct tupla * pt0,const uuid_t * uuid)218 static char *string_lookup_uuid(struct tupla *pt0, const uuid_t* uuid)
219 {
220 	uuid_t tmp_uuid;
221 
222 	memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid));
223 
224 	if (sdp_uuid128_to_uuid(&tmp_uuid)) {
225 		switch (tmp_uuid.type) {
226 		case SDP_UUID16:
227 			return string_lookup(pt0, tmp_uuid.value.uuid16);
228 		case SDP_UUID32:
229 			return string_lookup(pt0, tmp_uuid.value.uuid32);
230 		}
231 	}
232 
233 	return "";
234 }
235 
236 /*
237  * Prints into a string the Protocol UUID
238  * coping a maximum of n characters.
239  */
uuid2str(struct tupla * message,const uuid_t * uuid,char * str,size_t n)240 static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n)
241 {
242 	char *str2;
243 
244 	if (!uuid) {
245 		snprintf(str, n, "NULL");
246 		return -2;
247 	}
248 
249 	switch (uuid->type) {
250 	case SDP_UUID16:
251 		str2 = string_lookup(message, uuid->value.uuid16);
252 		snprintf(str, n, str2);
253 		break;
254 	case SDP_UUID32:
255 		str2 = string_lookup(message, uuid->value.uuid32);
256 		snprintf(str, n, str2);
257 		break;
258 	case SDP_UUID128:
259 		str2 = string_lookup_uuid(message, uuid);
260 		snprintf(str, n, str2);
261 		break;
262 	default:
263 		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
264 		return -1;
265 	}
266 
267 	return 0;
268 }
269 
sdp_proto_uuid2strn(const uuid_t * uuid,char * str,size_t n)270 int sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n)
271 {
272 	return uuid2str(Protocol, uuid, str, n);
273 }
274 
sdp_svclass_uuid2strn(const uuid_t * uuid,char * str,size_t n)275 int sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n)
276 {
277 	return uuid2str(ServiceClass, uuid, str, n);
278 }
279 
sdp_profile_uuid2strn(const uuid_t * uuid,char * str,size_t n)280 int sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n)
281 {
282 	return uuid2str(Profile, uuid, str, n);
283 }
284 
285 /*
286  * convert the UUID to string, copying a maximum of n characters.
287  */
sdp_uuid2strn(const uuid_t * uuid,char * str,size_t n)288 int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n)
289 {
290 	if (!uuid) {
291 		snprintf(str, n, "NULL");
292 		return -2;
293 	}
294 	switch (uuid->type) {
295 	case SDP_UUID16:
296 		snprintf(str, n, "%.4x", uuid->value.uuid16);
297 		break;
298 	case SDP_UUID32:
299 		snprintf(str, n, "%.8x", uuid->value.uuid32);
300 		break;
301 	case SDP_UUID128:{
302 		unsigned int   data0;
303 		unsigned short data1;
304 		unsigned short data2;
305 		unsigned short data3;
306 		unsigned int   data4;
307 		unsigned short data5;
308 
309 		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
310 		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
311 		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
312 		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
313 		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
314 		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
315 
316 		snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
317 				ntohl(data0), ntohs(data1),
318 				ntohs(data2), ntohs(data3),
319 				ntohl(data4), ntohs(data5));
320 		}
321 		break;
322 	default:
323 		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
324 		return -1;	// Enum type of UUID not set
325 	}
326 	return 0;
327 }
328 
329 #ifdef SDP_DEBUG
330 /*
331  * Function prints the UUID in hex as per defined syntax -
332  *
333  * 4bytes-2bytes-2bytes-2bytes-6bytes
334  *
335  * There is some ugly code, including hardcoding, but
336  * that is just the way it is converting 16 and 32 bit
337  * UUIDs to 128 bit as defined in the SDP doc
338  */
sdp_uuid_print(const uuid_t * uuid)339 void sdp_uuid_print(const uuid_t *uuid)
340 {
341 	if (uuid == NULL) {
342 		SDPERR("Null passed to print UUID\n");
343 		return;
344 	}
345 	if (uuid->type == SDP_UUID16) {
346 		SDPDBG("  uint16_t : 0x%.4x\n", uuid->value.uuid16);
347 	} else if (uuid->type == SDP_UUID32) {
348 		SDPDBG("  uint32_t : 0x%.8x\n", uuid->value.uuid32);
349 	} else if (uuid->type == SDP_UUID128) {
350 		unsigned int data0;
351 		unsigned short data1;
352 		unsigned short data2;
353 		unsigned short data3;
354 		unsigned int data4;
355 		unsigned short data5;
356 
357 		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
358 		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
359 		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
360 		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
361 		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
362 		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
363 
364 		SDPDBG("  uint128_t : 0x%.8x-", ntohl(data0));
365 		SDPDBG("%.4x-", ntohs(data1));
366 		SDPDBG("%.4x-", ntohs(data2));
367 		SDPDBG("%.4x-", ntohs(data3));
368 		SDPDBG("%.8x", ntohl(data4));
369 		SDPDBG("%.4x\n", ntohs(data5));
370 	} else
371 		SDPERR("Enum type of UUID not set\n");
372 }
373 #endif
374 
sdp_data_alloc_with_length(uint8_t dtd,const void * value,uint32_t length)375 sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, uint32_t length)
376 {
377 	sdp_data_t *seq;
378 	sdp_data_t *d = malloc(sizeof(sdp_data_t));
379 
380 	if (!d)
381 		return NULL;
382 
383 	memset(d, 0, sizeof(sdp_data_t));
384 	d->dtd = dtd;
385 	d->unitSize = sizeof(uint8_t);
386 
387 	switch (dtd) {
388 	case SDP_DATA_NIL:
389 		break;
390 	case SDP_UINT8:
391 		d->val.uint8 = *(uint8_t *) value;
392 		d->unitSize += sizeof(uint8_t);
393 		break;
394 	case SDP_INT8:
395 	case SDP_BOOL:
396 		d->val.int8 = *(int8_t *) value;
397 		d->unitSize += sizeof(int8_t);
398 		break;
399 	case SDP_UINT16:
400 		d->val.uint16 = bt_get_unaligned((uint16_t *) value);
401 		d->unitSize += sizeof(uint16_t);
402 		break;
403 	case SDP_INT16:
404 		d->val.int16 = bt_get_unaligned((int16_t *) value);
405 		d->unitSize += sizeof(int16_t);
406 		break;
407 	case SDP_UINT32:
408 		d->val.uint32 = bt_get_unaligned((uint32_t *) value);
409 		d->unitSize += sizeof(uint32_t);
410 		break;
411 	case SDP_INT32:
412 		d->val.int32 = bt_get_unaligned((int32_t *) value);
413 		d->unitSize += sizeof(int32_t);
414 		break;
415 	case SDP_INT64:
416 		d->val.int64 = bt_get_unaligned((int64_t *) value);
417 		d->unitSize += sizeof(int64_t);
418 		break;
419 	case SDP_UINT64:
420 		d->val.uint64 = bt_get_unaligned((uint64_t *) value);
421 		d->unitSize += sizeof(uint64_t);
422 		break;
423 	case SDP_UINT128:
424 		memcpy(&d->val.uint128.data, value, sizeof(uint128_t));
425 		d->unitSize += sizeof(uint128_t);
426 		break;
427 	case SDP_INT128:
428 		memcpy(&d->val.int128.data, value, sizeof(uint128_t));
429 		d->unitSize += sizeof(uint128_t);
430 		break;
431 	case SDP_UUID16:
432 		sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value));
433 		d->unitSize += sizeof(uint16_t);
434 		break;
435 	case SDP_UUID32:
436 		sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value));
437 		d->unitSize += sizeof(uint32_t);
438 		break;
439 	case SDP_UUID128:
440 		sdp_uuid128_create(&d->val.uuid, value);
441 		d->unitSize += sizeof(uint128_t);
442 		break;
443 	case SDP_URL_STR8:
444 	case SDP_URL_STR16:
445 	case SDP_TEXT_STR8:
446 	case SDP_TEXT_STR16:
447 		if (!value) {
448 			free(d);
449 			return NULL;
450 		}
451 
452 		d->unitSize += length;
453 		if (length <= USHRT_MAX) {
454 			d->val.str = malloc(length);
455 			if (!d->val.str) {
456 				free(d);
457 				return NULL;
458 			}
459 
460 			memcpy(d->val.str, value, length);
461 		} else {
462 			SDPERR("Strings of size > USHRT_MAX not supported\n");
463 			free(d);
464 			d = NULL;
465 		}
466 		break;
467 	case SDP_URL_STR32:
468 	case SDP_TEXT_STR32:
469 		SDPERR("Strings of size > USHRT_MAX not supported\n");
470 		break;
471 	case SDP_ALT8:
472 	case SDP_ALT16:
473 	case SDP_ALT32:
474 	case SDP_SEQ8:
475 	case SDP_SEQ16:
476 	case SDP_SEQ32:
477 		if (dtd == SDP_ALT8 || dtd == SDP_SEQ8)
478 			d->unitSize += sizeof(uint8_t);
479 		else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16)
480 			d->unitSize += sizeof(uint16_t);
481 		else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32)
482 			d->unitSize += sizeof(uint32_t);
483 		seq = (sdp_data_t *)value;
484 		d->val.dataseq = seq;
485 		for (; seq; seq = seq->next)
486 			d->unitSize += seq->unitSize;
487 		break;
488 	default:
489 		free(d);
490 		d = NULL;
491 	}
492 
493 	return d;
494 }
495 
sdp_data_alloc(uint8_t dtd,const void * value)496 sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value)
497 {
498 	uint32_t length;
499 
500 	switch (dtd) {
501 	case SDP_URL_STR8:
502 	case SDP_URL_STR16:
503 	case SDP_TEXT_STR8:
504 	case SDP_TEXT_STR16:
505 		if (!value)
506 			return NULL;
507 
508 		length = strlen((char *) value);
509 		break;
510 	default:
511 		length = 0;
512 		break;
513 	}
514 
515 	return sdp_data_alloc_with_length(dtd, value, length);
516 }
517 
sdp_seq_append(sdp_data_t * seq,sdp_data_t * d)518 sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d)
519 {
520 	if (seq) {
521 		sdp_data_t *p;
522 		for (p = seq; p->next; p = p->next);
523 		p->next = d;
524 	} else
525 		seq = d;
526 	d->next = NULL;
527 	return seq;
528 }
529 
sdp_seq_alloc_with_length(void ** dtds,void ** values,int * length,int len)530 sdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length, int len)
531 {
532 	sdp_data_t *curr = NULL, *seq = NULL;
533 	int i;
534 
535 	for (i = 0; i < len; i++) {
536 		sdp_data_t *data;
537 		int8_t dtd = *(uint8_t *) dtds[i];
538 
539 		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
540 			data = (sdp_data_t *) values[i];
541 		else
542 			data = sdp_data_alloc_with_length(dtd, values[i], length[i]);
543 
544 		if (!data)
545 			return NULL;
546 
547 		if (curr)
548 			curr->next = data;
549 		else
550 			seq = data;
551 
552 		curr = data;
553 	}
554 
555 	return sdp_data_alloc_with_length(SDP_SEQ8, seq, length[i]);
556 }
557 
sdp_seq_alloc(void ** dtds,void ** values,int len)558 sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len)
559 {
560 	sdp_data_t *curr = NULL, *seq = NULL;
561 	int i;
562 
563 	for (i = 0; i < len; i++) {
564 		sdp_data_t *data;
565 		uint8_t dtd = *(uint8_t *) dtds[i];
566 
567 		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
568 			data = (sdp_data_t *) values[i];
569 		else
570 			data = sdp_data_alloc(dtd, values[i]);
571 
572 		if (!data)
573 			return NULL;
574 
575 		if (curr)
576 			curr->next = data;
577 		else
578 			seq = data;
579 
580 		curr = data;
581 	}
582 
583 	return sdp_data_alloc(SDP_SEQ8, seq);
584 }
585 
extract_svclass_uuid(sdp_data_t * data,uuid_t * uuid)586 static void extract_svclass_uuid(sdp_data_t *data, uuid_t *uuid)
587 {
588 	sdp_data_t *d;
589 
590 	if (!data || data->dtd < SDP_SEQ8 || data->dtd > SDP_SEQ32)
591 		return;
592 
593 	d = data->val.dataseq;
594 	if (!d)
595 		return;
596 
597 	if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128)
598 		return;
599 
600 	*uuid = d->val.uuid;
601 }
602 
sdp_attr_add(sdp_record_t * rec,uint16_t attr,sdp_data_t * d)603 int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
604 {
605 	sdp_data_t *p = sdp_data_get(rec, attr);
606 
607 	if (p)
608 		return -1;
609 
610 	d->attrId = attr;
611 	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
612 
613 	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
614 		extract_svclass_uuid(d, &rec->svclass);
615 
616 	return 0;
617 }
618 
sdp_attr_remove(sdp_record_t * rec,uint16_t attr)619 void sdp_attr_remove(sdp_record_t *rec, uint16_t attr)
620 {
621 	sdp_data_t *d = sdp_data_get(rec, attr);
622 
623 	if (d)
624 		rec->attrlist = sdp_list_remove(rec->attrlist, d);
625 
626 	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
627 		memset(&rec->svclass, 0, sizeof(rec->svclass));
628 }
629 
sdp_set_seq_len(uint8_t * ptr,uint32_t length)630 void sdp_set_seq_len(uint8_t *ptr, uint32_t length)
631 {
632 	uint8_t dtd = *(uint8_t *) ptr++;
633 
634 	switch (dtd) {
635 	case SDP_SEQ8:
636 	case SDP_ALT8:
637 	case SDP_TEXT_STR8:
638 	case SDP_URL_STR8:
639 		*(uint8_t *)ptr = (uint8_t) length;
640 		break;
641 	case SDP_SEQ16:
642 	case SDP_ALT16:
643 	case SDP_TEXT_STR16:
644 	case SDP_URL_STR16:
645 		bt_put_unaligned(htons(length), (uint16_t *) ptr);
646 		break;
647 	case SDP_SEQ32:
648 	case SDP_ALT32:
649 	case SDP_TEXT_STR32:
650 	case SDP_URL_STR32:
651 		bt_put_unaligned(htonl(length), (uint32_t *) ptr);
652 		break;
653 	}
654 }
655 
sdp_set_data_type(sdp_buf_t * buf,uint8_t dtd)656 int sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd)
657 {
658 	int orig = buf->data_size;
659 	uint8_t *p = buf->data + buf->data_size;
660 
661 	*p++ = dtd;
662 	buf->data_size += sizeof(uint8_t);
663 
664 	switch (dtd) {
665 	case SDP_SEQ8:
666 	case SDP_TEXT_STR8:
667 	case SDP_URL_STR8:
668 	case SDP_ALT8:
669 		buf->data_size += sizeof(uint8_t);
670 		break;
671 	case SDP_SEQ16:
672 	case SDP_TEXT_STR16:
673 	case SDP_URL_STR16:
674 	case SDP_ALT16:
675 		buf->data_size += sizeof(uint16_t);
676 		break;
677 	case SDP_SEQ32:
678 	case SDP_TEXT_STR32:
679 	case SDP_URL_STR32:
680 	case SDP_ALT32:
681 		buf->data_size += sizeof(uint32_t);
682 		break;
683 	}
684 
685 	return buf->data_size - orig;
686 }
687 
sdp_set_attrid(sdp_buf_t * buf,uint16_t attr)688 void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr)
689 {
690 	uint8_t *p = buf->data;
691 
692 	// data type for attr
693 	*p++ = SDP_UINT16;
694 	buf->data_size = sizeof(uint8_t);
695 	bt_put_unaligned(htons(attr), (uint16_t *) p);
696 	p += sizeof(uint16_t);
697 	buf->data_size += sizeof(uint16_t);
698 }
699 
get_data_size(sdp_buf_t * buf,sdp_data_t * sdpdata)700 static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata)
701 {
702 	sdp_data_t *d;
703 	int n = 0;
704 
705 	for (d = sdpdata->val.dataseq; d; d = d->next)
706 		n += sdp_gen_pdu(buf, d);
707 
708 	return n;
709 }
710 
sdp_gen_pdu(sdp_buf_t * buf,sdp_data_t * d)711 int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
712 {
713 	uint32_t pdu_size = 0, data_size = 0;
714 	unsigned char *src = NULL, is_seq = 0, is_alt = 0;
715 	uint8_t dtd = d->dtd;
716 	uint16_t u16;
717 	uint32_t u32;
718 	uint64_t u64;
719 	uint128_t u128;
720 	uint8_t *seqp = buf->data + buf->data_size;
721 
722 	pdu_size = sdp_set_data_type(buf, dtd);
723 
724 	switch (dtd) {
725 	case SDP_DATA_NIL:
726 		break;
727 	case SDP_UINT8:
728 		src = &d->val.uint8;
729 		data_size = sizeof(uint8_t);
730 		break;
731 	case SDP_UINT16:
732 		u16 = htons(d->val.uint16);
733 		src = (unsigned char *) &u16;
734 		data_size = sizeof(uint16_t);
735 		break;
736 	case SDP_UINT32:
737 		u32 = htonl(d->val.uint32);
738 		src = (unsigned char *) &u32;
739 		data_size = sizeof(uint32_t);
740 		break;
741 	case SDP_UINT64:
742 		u64 = hton64(d->val.uint64);
743 		src = (unsigned char *) &u64;
744 		data_size = sizeof(uint64_t);
745 		break;
746 	case SDP_UINT128:
747 		hton128(&d->val.uint128, &u128);
748 		src = (unsigned char *) &u128;
749 		data_size = sizeof(uint128_t);
750 		break;
751 	case SDP_INT8:
752 	case SDP_BOOL:
753 		src = (unsigned char *) &d->val.int8;
754 		data_size = sizeof(int8_t);
755 		break;
756 	case SDP_INT16:
757 		u16 = htons(d->val.int16);
758 		src = (unsigned char *) &u16;
759 		data_size = sizeof(int16_t);
760 		break;
761 	case SDP_INT32:
762 		u32 = htonl(d->val.int32);
763 		src = (unsigned char *) &u32;
764 		data_size = sizeof(int32_t);
765 		break;
766 	case SDP_INT64:
767 		u64 = hton64(d->val.int64);
768 		src = (unsigned char *) &u64;
769 		data_size = sizeof(int64_t);
770 		break;
771 	case SDP_INT128:
772 		hton128(&d->val.int128, &u128);
773 		src = (unsigned char *) &u128;
774 		data_size = sizeof(uint128_t);
775 		break;
776 	case SDP_TEXT_STR8:
777 	case SDP_TEXT_STR16:
778 	case SDP_TEXT_STR32:
779 	case SDP_URL_STR8:
780 	case SDP_URL_STR16:
781 	case SDP_URL_STR32:
782 		src = (unsigned char *) d->val.str;
783 		data_size = d->unitSize - sizeof(uint8_t);
784 		sdp_set_seq_len(seqp, data_size);
785 		break;
786 	case SDP_SEQ8:
787 	case SDP_SEQ16:
788 	case SDP_SEQ32:
789 		is_seq = 1;
790 		data_size = get_data_size(buf, d);
791 		sdp_set_seq_len(seqp, data_size);
792 		break;
793 	case SDP_ALT8:
794 	case SDP_ALT16:
795 	case SDP_ALT32:
796 		is_alt = 1;
797 		data_size = get_data_size(buf, d);
798 		sdp_set_seq_len(seqp, data_size);
799 		break;
800 	case SDP_UUID16:
801 		u16 = htons(d->val.uuid.value.uuid16);
802 		src = (unsigned char *) &u16;
803 		data_size = sizeof(uint16_t);
804 		break;
805 	case SDP_UUID32:
806 		u32 = htonl(d->val.uuid.value.uuid32);
807 		src = (unsigned char *) &u32;
808 		data_size = sizeof(uint32_t);
809 		break;
810 	case SDP_UUID128:
811 		src = (unsigned char *) &d->val.uuid.value.uuid128;
812 		data_size = sizeof(uint128_t);
813 		break;
814 	default:
815 		break;
816 	}
817 
818 	if (!is_seq && !is_alt) {
819 		if (src && buf) {
820 			memcpy(buf->data + buf->data_size, src, data_size);
821 			buf->data_size += data_size;
822 		} else if (dtd != SDP_DATA_NIL)
823 			SDPDBG("Gen PDU : Cant copy from NULL source or dest\n");
824 	}
825 
826 	pdu_size += data_size;
827 
828 	return pdu_size;
829 }
830 
sdp_attr_pdu(void * value,void * udata)831 static void sdp_attr_pdu(void *value, void *udata)
832 {
833 	sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);
834 }
835 
sdp_gen_record_pdu(const sdp_record_t * rec,sdp_buf_t * buf)836 int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf)
837 {
838 	buf->data = malloc(SDP_PDU_CHUNK_SIZE);
839 	if (!buf->data)
840 		return -ENOMEM;
841 
842 	buf->buf_size = SDP_PDU_CHUNK_SIZE;
843 	buf->data_size = 0;
844 	memset(buf->data, 0, buf->buf_size);
845 	sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf);
846 
847 	return 0;
848 }
849 
sdp_attr_replace(sdp_record_t * rec,uint16_t attr,sdp_data_t * d)850 void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
851 {
852 	sdp_data_t *p = sdp_data_get(rec, attr);
853 
854 	if (p) {
855 		rec->attrlist = sdp_list_remove(rec->attrlist, p);
856 		sdp_data_free(p);
857 	}
858 
859 	d->attrId = attr;
860 	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
861 
862 	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
863 		extract_svclass_uuid(d, &rec->svclass);
864 }
865 
sdp_attrid_comp_func(const void * key1,const void * key2)866 int sdp_attrid_comp_func(const void *key1, const void *key2)
867 {
868 	const sdp_data_t *d1 = (const sdp_data_t *)key1;
869 	const sdp_data_t *d2 = (const sdp_data_t *)key2;
870 
871 	if (d1 && d2)
872 		return d1->attrId - d2->attrId;
873 	return 0;
874 }
875 
data_seq_free(sdp_data_t * seq)876 static void data_seq_free(sdp_data_t *seq)
877 {
878 	sdp_data_t *d = seq->val.dataseq;
879 
880 	while (d) {
881 		sdp_data_t *next = d->next;
882 		sdp_data_free(d);
883 		d = next;
884 	}
885 }
886 
sdp_data_free(sdp_data_t * d)887 void sdp_data_free(sdp_data_t *d)
888 {
889 	switch (d->dtd) {
890 	case SDP_SEQ8:
891 	case SDP_SEQ16:
892 	case SDP_SEQ32:
893 		data_seq_free(d);
894 		break;
895 	case SDP_URL_STR8:
896 	case SDP_URL_STR16:
897 	case SDP_URL_STR32:
898 	case SDP_TEXT_STR8:
899 	case SDP_TEXT_STR16:
900 	case SDP_TEXT_STR32:
901 		free(d->val.str);
902 		break;
903 	}
904 	free(d);
905 }
906 
sdp_uuid_extract_safe(const uint8_t * p,int bufsize,uuid_t * uuid,int * scanned)907 int sdp_uuid_extract_safe(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned)
908 {
909 	uint8_t type;
910 
911 	if (bufsize < sizeof(uint8_t)) {
912 		SDPERR("Unexpected end of packet");
913 		return -1;
914 	}
915 
916 	type = *(const uint8_t *) p;
917 
918 	if (!SDP_IS_UUID(type)) {
919 		SDPERR("Unknown data type : %d expecting a svc UUID\n", type);
920 		return -1;
921 	}
922 	p += sizeof(uint8_t);
923 	*scanned += sizeof(uint8_t);
924 	bufsize -= sizeof(uint8_t);
925 	if (type == SDP_UUID16) {
926 		if (bufsize < sizeof(uint16_t)) {
927 			SDPERR("Not enough room for 16-bit UUID");
928 			return -1;
929 		}
930 		sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p)));
931 		*scanned += sizeof(uint16_t);
932 		p += sizeof(uint16_t);
933 	} else if (type == SDP_UUID32) {
934 		if (bufsize < sizeof(uint32_t)) {
935 			SDPERR("Not enough room for 32-bit UUID");
936 			return -1;
937 		}
938 		sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p)));
939 		*scanned += sizeof(uint32_t);
940 		p += sizeof(uint32_t);
941 	} else {
942 		if (bufsize < sizeof(uint128_t)) {
943 			SDPERR("Not enough room for 128-bit UUID");
944 			return -1;
945 		}
946 		sdp_uuid128_create(uuid, p);
947 		*scanned += sizeof(uint128_t);
948 		p += sizeof(uint128_t);
949 	}
950 	return 0;
951 }
952 
sdp_uuid_extract(const uint8_t * p,uuid_t * uuid,int * scanned)953 int sdp_uuid_extract(const uint8_t *p, uuid_t *uuid, int *scanned)
954 {
955 	/* Assume p points to a buffer of size at least SDP_MAX_ATTR_LEN,
956 	   because we don't have any better information */
957 	return sdp_uuid_extract_safe(p, SDP_MAX_ATTR_LEN, uuid, scanned);
958 }
959 
extract_int(const void * p,int bufsize,int * len)960 static sdp_data_t *extract_int(const void *p, int bufsize, int *len)
961 {
962 	sdp_data_t *d;
963 
964 	if (bufsize < sizeof(uint8_t)) {
965 		SDPERR("Unexpected end of packet");
966 		return NULL;
967 	}
968 
969 	d = malloc(sizeof(sdp_data_t));
970 
971 	SDPDBG("Extracting integer\n");
972 	memset(d, 0, sizeof(sdp_data_t));
973 	d->dtd = *(uint8_t *) p;
974 	p += sizeof(uint8_t);
975 	*len += sizeof(uint8_t);
976 	bufsize -= sizeof(uint8_t);
977 
978 	switch (d->dtd) {
979 	case SDP_DATA_NIL:
980 		break;
981 	case SDP_BOOL:
982 	case SDP_INT8:
983 	case SDP_UINT8:
984 		if (bufsize < sizeof(uint8_t)) {
985 			SDPERR("Unexpected end of packet");
986 			free(d);
987 			return NULL;
988 		}
989 		*len += sizeof(uint8_t);
990 		d->val.uint8 = *(uint8_t *) p;
991 		break;
992 	case SDP_INT16:
993 	case SDP_UINT16:
994 		if (bufsize < sizeof(uint16_t)) {
995 			SDPERR("Unexpected end of packet");
996 			free(d);
997 			return NULL;
998 		}
999 		*len += sizeof(uint16_t);
1000 		d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p));
1001 		break;
1002 	case SDP_INT32:
1003 	case SDP_UINT32:
1004 		if (bufsize < sizeof(uint32_t)) {
1005 			SDPERR("Unexpected end of packet");
1006 			free(d);
1007 			return NULL;
1008 		}
1009 		*len += sizeof(uint32_t);
1010 		d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p));
1011 		break;
1012 	case SDP_INT64:
1013 	case SDP_UINT64:
1014 		if (bufsize < sizeof(uint64_t)) {
1015 			SDPERR("Unexpected end of packet");
1016 			free(d);
1017 			return NULL;
1018 		}
1019 		*len += sizeof(uint64_t);
1020 		d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p));
1021 		break;
1022 	case SDP_INT128:
1023 	case SDP_UINT128:
1024 		if (bufsize < sizeof(uint128_t)) {
1025 			SDPERR("Unexpected end of packet");
1026 			free(d);
1027 			return NULL;
1028 		}
1029 		*len += sizeof(uint128_t);
1030 		ntoh128((uint128_t *) p, &d->val.uint128);
1031 		break;
1032 	default:
1033 		free(d);
1034 		d = NULL;
1035 	}
1036 	return d;
1037 }
1038 
extract_uuid(const uint8_t * p,int bufsize,int * len,sdp_record_t * rec)1039 static sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len, sdp_record_t *rec)
1040 {
1041 	sdp_data_t *d = malloc(sizeof(sdp_data_t));
1042 
1043 	SDPDBG("Extracting UUID");
1044 	memset(d, 0, sizeof(sdp_data_t));
1045 	if (sdp_uuid_extract_safe(p, bufsize, &d->val.uuid, len) < 0) {
1046 		free(d);
1047 		return NULL;
1048 	}
1049 	d->dtd = *(uint8_t *) p;
1050 	if (rec)
1051 		sdp_pattern_add_uuid(rec, &d->val.uuid);
1052 	return d;
1053 }
1054 
1055 /*
1056  * Extract strings from the PDU (could be service description and similar info)
1057  */
extract_str(const void * p,int bufsize,int * len)1058 static sdp_data_t *extract_str(const void *p, int bufsize, int *len)
1059 {
1060 	char *s;
1061 	int n;
1062 	sdp_data_t *d;
1063 
1064 	if (bufsize < sizeof(uint8_t)) {
1065 		SDPERR("Unexpected end of packet");
1066 		return NULL;
1067 	}
1068 
1069 	d = malloc(sizeof(sdp_data_t));
1070 
1071 	memset(d, 0, sizeof(sdp_data_t));
1072 	d->dtd = *(uint8_t *) p;
1073 	p += sizeof(uint8_t);
1074 	*len += sizeof(uint8_t);
1075 	bufsize -= sizeof(uint8_t);
1076 
1077 	switch (d->dtd) {
1078 	case SDP_TEXT_STR8:
1079 	case SDP_URL_STR8:
1080 		if (bufsize < sizeof(uint8_t)) {
1081 			SDPERR("Unexpected end of packet");
1082 			free(d);
1083 			return NULL;
1084 		}
1085 		n = *(uint8_t *) p;
1086 		p += sizeof(uint8_t);
1087 		*len += sizeof(uint8_t);
1088 		bufsize -= sizeof(uint8_t);
1089 		break;
1090 	case SDP_TEXT_STR16:
1091 	case SDP_URL_STR16:
1092 		if (bufsize < sizeof(uint16_t)) {
1093 			SDPERR("Unexpected end of packet");
1094 			free(d);
1095 			return NULL;
1096 		}
1097 		n = ntohs(bt_get_unaligned((uint16_t *) p));
1098 		p += sizeof(uint16_t);
1099 		*len += sizeof(uint16_t) + n;
1100 		bufsize -= sizeof(uint16_t);
1101 		break;
1102 	default:
1103 		SDPERR("Sizeof text string > UINT16_MAX\n");
1104 		free(d);
1105 		return 0;
1106 	}
1107 
1108 	if (bufsize < n) {
1109 		SDPERR("String too long to fit in packet");
1110 		free(d);
1111 		return NULL;
1112 	}
1113 
1114 	s = malloc(n + 1);
1115 	if (!s) {
1116 		SDPERR("Not enough memory for incoming string");
1117 		free(d);
1118 		return NULL;
1119 	}
1120 	memset(s, 0, n + 1);
1121 	memcpy(s, p, n);
1122 
1123 	*len += n;
1124 
1125 	SDPDBG("Len : %d\n", n);
1126 	SDPDBG("Str : %s\n", s);
1127 
1128 	d->val.str = s;
1129 	d->unitSize = n + sizeof(uint8_t);
1130 	return d;
1131 }
1132 
1133 /*
1134  * Extract the sequence type and its length, and return offset into buf
1135  * or 0 on failure.
1136  */
sdp_extract_seqtype_safe(const uint8_t * buf,int bufsize,uint8_t * dtdp,int * size)1137 int sdp_extract_seqtype_safe(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size)
1138 {
1139 	uint8_t dtd;
1140 	int scanned = sizeof(uint8_t);
1141 
1142 	if (bufsize < sizeof(uint8_t)) {
1143 		SDPERR("Unexpected end of packet");
1144 		return 0;
1145 	}
1146 
1147 	dtd = *(uint8_t *) buf;
1148 	buf += sizeof(uint8_t);
1149 	bufsize -= sizeof(uint8_t);
1150 	*dtdp = dtd;
1151 	switch (dtd) {
1152 	case SDP_SEQ8:
1153 	case SDP_ALT8:
1154 		if (bufsize < sizeof(uint8_t)) {
1155 			SDPERR("Unexpected end of packet");
1156 			return 0;
1157 		}
1158 		*size = *(uint8_t *) buf;
1159 		scanned += sizeof(uint8_t);
1160 		break;
1161 	case SDP_SEQ16:
1162 	case SDP_ALT16:
1163 		if (bufsize < sizeof(uint16_t)) {
1164 			SDPERR("Unexpected end of packet");
1165 			return 0;
1166 		}
1167 		*size = ntohs(bt_get_unaligned((uint16_t *) buf));
1168 		scanned += sizeof(uint16_t);
1169 		break;
1170 	case SDP_SEQ32:
1171 	case SDP_ALT32:
1172 		if (bufsize < sizeof(uint32_t)) {
1173 			SDPERR("Unexpected end of packet");
1174 			return 0;
1175 		}
1176 		*size = ntohl(bt_get_unaligned((uint32_t *) buf));
1177 		scanned += sizeof(uint32_t);
1178 		break;
1179 	default:
1180 		SDPERR("Unknown sequence type, aborting\n");
1181 		return 0;
1182 	}
1183 	return scanned;
1184 }
1185 
sdp_extract_seqtype(const uint8_t * buf,uint8_t * dtdp,int * size)1186 int sdp_extract_seqtype(const uint8_t *buf, uint8_t *dtdp, int *size)
1187 {
1188 	/* Assume buf points to a buffer of size at least SDP_MAX_ATTR_LEN,
1189 	   because we don't have any better information */
1190 	return sdp_extract_seqtype_safe(buf, SDP_MAX_ATTR_LEN, dtdp, size);
1191 }
1192 
extract_seq(const void * p,int bufsize,int * len,sdp_record_t * rec)1193 static sdp_data_t *extract_seq(const void *p, int bufsize, int *len, sdp_record_t *rec)
1194 {
1195 	int seqlen, n = 0;
1196 	sdp_data_t *curr, *prev;
1197 	sdp_data_t *d = malloc(sizeof(sdp_data_t));
1198 
1199 	SDPDBG("Extracting SEQ");
1200 	memset(d, 0, sizeof(sdp_data_t));
1201 	*len = sdp_extract_seqtype_safe(p, bufsize, &d->dtd, &seqlen);
1202 	SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen);
1203 
1204 	if (*len == 0)
1205 		return d;
1206 
1207 	if (*len > bufsize) {
1208 		SDPERR("Packet not big enough to hold sequence.");
1209 		free(d);
1210 		return NULL;
1211 	}
1212 
1213 	p += *len;
1214 	bufsize -= *len;
1215 	curr = prev = NULL;
1216 	while (n < seqlen) {
1217 		int attrlen = 0;
1218 		curr = sdp_extract_attr_safe(p, bufsize, &attrlen, rec);
1219 		if (curr == NULL)
1220 			break;
1221 
1222 		if (prev)
1223 			prev->next = curr;
1224 		else
1225 			d->val.dataseq = curr;
1226 		prev = curr;
1227 		p += attrlen;
1228 		n += attrlen;
1229 		bufsize -= attrlen;
1230 
1231 		SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen);
1232 	}
1233 
1234 	*len += n;
1235 	return d;
1236 }
1237 
sdp_extract_attr_safe(const uint8_t * p,int bufsize,int * size,sdp_record_t * rec)1238 sdp_data_t *sdp_extract_attr_safe(const uint8_t *p, int bufsize, int *size, sdp_record_t *rec)
1239 {
1240 	sdp_data_t *elem;
1241 	int n = 0;
1242 	uint8_t dtd;
1243 
1244 	if (bufsize < sizeof(uint8_t)) {
1245 		SDPERR("Unexpected end of packet");
1246 		return NULL;
1247 	}
1248 
1249 	dtd = *(const uint8_t *)p;
1250 
1251 	SDPDBG("extract_attr: dtd=0x%x", dtd);
1252 	switch (dtd) {
1253 	case SDP_DATA_NIL:
1254 	case SDP_BOOL:
1255 	case SDP_UINT8:
1256 	case SDP_UINT16:
1257 	case SDP_UINT32:
1258 	case SDP_UINT64:
1259 	case SDP_UINT128:
1260 	case SDP_INT8:
1261 	case SDP_INT16:
1262 	case SDP_INT32:
1263 	case SDP_INT64:
1264 	case SDP_INT128:
1265 		elem = extract_int(p, bufsize, &n);
1266 		break;
1267 	case SDP_UUID16:
1268 	case SDP_UUID32:
1269 	case SDP_UUID128:
1270 		elem = extract_uuid(p, bufsize, &n, rec);
1271 		break;
1272 	case SDP_TEXT_STR8:
1273 	case SDP_TEXT_STR16:
1274 	case SDP_TEXT_STR32:
1275 	case SDP_URL_STR8:
1276 	case SDP_URL_STR16:
1277 	case SDP_URL_STR32:
1278 		elem = extract_str(p, bufsize, &n);
1279 		break;
1280 	case SDP_SEQ8:
1281 	case SDP_SEQ16:
1282 	case SDP_SEQ32:
1283 	case SDP_ALT8:
1284 	case SDP_ALT16:
1285 	case SDP_ALT32:
1286 		elem = extract_seq(p, bufsize, &n, rec);
1287 		break;
1288 	default:
1289 		SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd);
1290 		return NULL;
1291 	}
1292 	*size += n;
1293 	return elem;
1294 }
1295 
sdp_extract_attr(const uint8_t * p,int * size,sdp_record_t * rec)1296 sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec)
1297 {
1298 	/* Assume p points to a buffer of size at least SDP_MAX_ATTR_LEN,
1299 	   because we don't have any better information */
1300 	return sdp_extract_attr_safe(p, SDP_MAX_ATTR_LEN, size, rec);
1301 }
1302 
1303 #ifdef SDP_DEBUG
attr_print_func(void * value,void * userData)1304 static void attr_print_func(void *value, void *userData)
1305 {
1306 	sdp_data_t *d = (sdp_data_t *)value;
1307 
1308 	SDPDBG("=====================================\n");
1309 	SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n",  d->attrId);
1310 	SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value);
1311 	if (d)
1312 		sdp_data_print(d);
1313 	else
1314 		SDPDBG("NULL value\n");
1315 	SDPDBG("=====================================\n");
1316 }
1317 
sdp_print_service_attr(sdp_list_t * svcAttrList)1318 void sdp_print_service_attr(sdp_list_t *svcAttrList)
1319 {
1320 	SDPDBG("Printing service attr list %p\n", svcAttrList);
1321 	sdp_list_foreach(svcAttrList, attr_print_func, NULL);
1322 	SDPDBG("Printed service attr list %p\n", svcAttrList);
1323 }
1324 #endif
1325 
sdp_extract_pdu_safe(const uint8_t * buf,int bufsize,int * scanned)1326 sdp_record_t *sdp_extract_pdu_safe(const uint8_t *buf, int bufsize, int *scanned)
1327 {
1328 	int extracted = 0, seqlen = 0;
1329 	uint8_t dtd;
1330 	uint16_t attr;
1331 	sdp_record_t *rec = sdp_record_alloc();
1332 	const uint8_t *p = buf;
1333 
1334 	*scanned = sdp_extract_seqtype_safe(buf, bufsize, &dtd, &seqlen);
1335 	p += *scanned;
1336 	bufsize -= *scanned;
1337 	rec->attrlist = NULL;
1338 
1339 	while (extracted < seqlen && bufsize > 0) {
1340 		int n = sizeof(uint8_t), attrlen = 0;
1341 		sdp_data_t *data = NULL;
1342 
1343 		SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d",
1344 							seqlen, extracted);
1345 
1346 		if (bufsize < n + sizeof(uint16_t)) {
1347 			SDPERR("Unexpected end of packet");
1348 			break;
1349 		}
1350 
1351 		dtd = *(uint8_t *) p;
1352 		attr = ntohs(bt_get_unaligned((uint16_t *) (p + n)));
1353 		n += sizeof(uint16_t);
1354 
1355 		SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr);
1356 
1357 		data = sdp_extract_attr_safe(p + n, bufsize - n, &attrlen, rec);
1358 
1359 		SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen);
1360 
1361 		n += attrlen;
1362 		if (data == NULL) {
1363 			SDPDBG("Terminating extraction of attributes");
1364 			break;
1365 		}
1366 
1367 		if (attr == SDP_ATTR_RECORD_HANDLE)
1368 			rec->handle = data->val.uint32;
1369 
1370 		if (attr == SDP_ATTR_SVCLASS_ID_LIST)
1371 			extract_svclass_uuid(data, &rec->svclass);
1372 
1373 		extracted += n;
1374 		p += n;
1375 		bufsize -= n;
1376 		sdp_attr_replace(rec, attr, data);
1377 
1378 		SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",
1379 							seqlen, extracted);
1380 	}
1381 #ifdef SDP_DEBUG
1382 	SDPDBG("Successful extracting of Svc Rec attributes\n");
1383 	sdp_print_service_attr(rec->attrlist);
1384 #endif
1385 	*scanned += seqlen;
1386 	return rec;
1387 }
1388 
sdp_extract_pdu(const uint8_t * buf,int * scanned)1389 sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned)
1390 {
1391 	/* Assume buf points to a buffer of size at least SDP_MAX_ATTR_LEN,
1392 	   because we don't have any better information */
1393 	return sdp_extract_pdu_safe(buf, SDP_MAX_ATTR_LEN, scanned);
1394 }
1395 
1396 #ifdef SDP_DEBUG
print_dataseq(sdp_data_t * p)1397 static void print_dataseq(sdp_data_t *p)
1398 {
1399 	sdp_data_t *d;
1400 
1401 	for (d = p; d; d = d->next)
1402 		sdp_data_print(d);
1403 }
1404 #endif
1405 
sdp_record_print(const sdp_record_t * rec)1406 void sdp_record_print(const sdp_record_t *rec)
1407 {
1408 	sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
1409 	if (d)
1410 		printf("Service Name: %.*s\n", d->unitSize, d->val.str);
1411 	d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
1412 	if (d)
1413 		printf("Service Description: %.*s\n", d->unitSize, d->val.str);
1414 	d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
1415 	if (d)
1416 		printf("Service Provider: %.*s\n", d->unitSize, d->val.str);
1417 }
1418 
1419 #ifdef SDP_DEBUG
sdp_data_print(sdp_data_t * d)1420 void sdp_data_print(sdp_data_t *d)
1421 {
1422 	switch (d->dtd) {
1423 	case SDP_DATA_NIL:
1424 		SDPDBG("NIL\n");
1425 		break;
1426 	case SDP_BOOL:
1427 	case SDP_UINT8:
1428 	case SDP_UINT16:
1429 	case SDP_UINT32:
1430 	case SDP_UINT64:
1431 	case SDP_UINT128:
1432 	case SDP_INT8:
1433 	case SDP_INT16:
1434 	case SDP_INT32:
1435 	case SDP_INT64:
1436 	case SDP_INT128:
1437 		SDPDBG("Integer : 0x%x\n", d->val.uint32);
1438 		break;
1439 	case SDP_UUID16:
1440 	case SDP_UUID32:
1441 	case SDP_UUID128:
1442 		SDPDBG("UUID\n");
1443 		sdp_uuid_print(&d->val.uuid);
1444 		break;
1445 	case SDP_TEXT_STR8:
1446 	case SDP_TEXT_STR16:
1447 	case SDP_TEXT_STR32:
1448 		SDPDBG("Text : %s\n", d->val.str);
1449 		break;
1450 	case SDP_URL_STR8:
1451 	case SDP_URL_STR16:
1452 	case SDP_URL_STR32:
1453 		SDPDBG("URL : %s\n", d->val.str);
1454 		break;
1455 	case SDP_SEQ8:
1456 	case SDP_SEQ16:
1457 	case SDP_SEQ32:
1458 		print_dataseq(d->val.dataseq);
1459 		break;
1460 	case SDP_ALT8:
1461 	case SDP_ALT16:
1462 	case SDP_ALT32:
1463 		SDPDBG("Data Sequence Alternates\n");
1464 		print_dataseq(d->val.dataseq);
1465 		break;
1466 	}
1467 }
1468 #endif
1469 
sdp_data_get(const sdp_record_t * rec,uint16_t attrId)1470 sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId)
1471 {
1472 	if (rec->attrlist) {
1473 		sdp_data_t sdpTemplate;
1474 		sdp_list_t *p;
1475 
1476 		sdpTemplate.attrId = attrId;
1477 		p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func);
1478 		if (p)
1479 			return (sdp_data_t *)p->data;
1480 	}
1481 	return NULL;
1482 }
1483 
sdp_send_req(sdp_session_t * session,uint8_t * buf,uint32_t size)1484 int sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size)
1485 {
1486 	uint32_t sent = 0;
1487 
1488 	while (sent < size) {
1489 		int n = send(session->sock, buf + sent, size - sent, 0);
1490 		if (n < 0)
1491 			return -1;
1492 		sent += n;
1493 	}
1494 	return 0;
1495 }
1496 
sdp_read_rsp(sdp_session_t * session,uint8_t * buf,uint32_t size)1497 int sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size)
1498 {
1499 	fd_set readFds;
1500 	struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 };
1501 
1502 	FD_ZERO(&readFds);
1503 	FD_SET(session->sock, &readFds);
1504 	SDPDBG("Waiting for response\n");
1505 	if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) {
1506 		SDPERR("Client timed out\n");
1507 		errno = ETIMEDOUT;
1508 		return -1;
1509 	}
1510 	return recv(session->sock, buf, size, 0);
1511 }
1512 
1513 /*
1514  * generic send request, wait for response method.
1515  */
sdp_send_req_w4_rsp(sdp_session_t * session,uint8_t * reqbuf,uint8_t * rspbuf,uint32_t reqsize,uint32_t * rspsize)1516 int sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf, uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize)
1517 {
1518 	int n;
1519 	sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)reqbuf;
1520 	sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *)rspbuf;
1521 
1522 	SDPDBG("");
1523 	if (0 > sdp_send_req(session, reqbuf, reqsize)) {
1524 		SDPERR("Error sending data:%s", strerror(errno));
1525 		return -1;
1526 	}
1527 	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
1528 	if (0 > n)
1529 		return -1;
1530 	SDPDBG("Read : %d\n", n);
1531 	if (n == 0 || reqhdr->tid != rsphdr->tid) {
1532 		errno = EPROTO;
1533 		return -1;
1534 	}
1535 	*rspsize = n;
1536 	return 0;
1537 }
1538 
1539 /*
1540  * singly-linked lists (after openobex implementation)
1541  */
sdp_list_append(sdp_list_t * p,void * d)1542 sdp_list_t *sdp_list_append(sdp_list_t *p, void *d)
1543 {
1544 	sdp_list_t *q, *n = malloc(sizeof(sdp_list_t));
1545 
1546 	if (!n)
1547 		return 0;
1548 
1549 	n->data = d;
1550 	n->next = 0;
1551 
1552 	if (!p)
1553 		return n;
1554 
1555 	for (q = p; q->next; q = q->next);
1556 	q->next = n;
1557 
1558 	return p;
1559 }
1560 
sdp_list_remove(sdp_list_t * list,void * d)1561 sdp_list_t *sdp_list_remove(sdp_list_t *list, void *d)
1562 {
1563 	sdp_list_t *p, *q;
1564 
1565 	for (q = 0, p = list; p; q = p, p = p->next)
1566 		if (p->data == d) {
1567 			if (q)
1568 				q->next = p->next;
1569 			else
1570 				list = p->next;
1571 			free(p);
1572 			break;
1573 		}
1574 
1575 	return list;
1576 }
1577 
sdp_list_insert_sorted(sdp_list_t * list,void * d,sdp_comp_func_t f)1578 sdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d, sdp_comp_func_t f)
1579 {
1580 	sdp_list_t *q, *p, *n;
1581 
1582 	n = malloc(sizeof(sdp_list_t));
1583 	if (!n)
1584 		return 0;
1585 	n->data = d;
1586 	for (q = 0, p = list; p; q = p, p = p->next)
1587 		if (f(p->data, d) >= 0)
1588 			break;
1589 	// insert between q and p; if !q insert at head
1590 	if (q)
1591 		q->next = n;
1592 	else
1593 		list = n;
1594 	n->next = p;
1595 	return list;
1596 }
1597 
1598 /*
1599  * Every element of the list points to things which need
1600  * to be free()'d. This method frees the list's contents
1601  */
sdp_list_free(sdp_list_t * list,sdp_free_func_t f)1602 void sdp_list_free(sdp_list_t *list, sdp_free_func_t f)
1603 {
1604 	sdp_list_t *next;
1605 	while (list) {
1606 		next = list->next;
1607 		if (f)
1608 			f(list->data);
1609 		free(list);
1610 		list = next;
1611 	}
1612 }
1613 
__find_port(sdp_data_t * seq,int proto)1614 static inline int __find_port(sdp_data_t *seq, int proto)
1615 {
1616 	if (!seq || !seq->next)
1617 		return 0;
1618 
1619 	if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) {
1620 		seq = seq->next;
1621 		switch (seq->dtd) {
1622 		case SDP_UINT8:
1623 			return seq->val.uint8;
1624 		case SDP_UINT16:
1625 			return seq->val.uint16;
1626 		}
1627 	}
1628 	return 0;
1629 }
1630 
sdp_get_proto_port(const sdp_list_t * list,int proto)1631 int sdp_get_proto_port(const sdp_list_t *list, int proto)
1632 {
1633 	if (proto != L2CAP_UUID && proto != RFCOMM_UUID) {
1634 		errno = EINVAL;
1635 		return -1;
1636 	}
1637 
1638 	for (; list; list = list->next) {
1639 		sdp_list_t *p;
1640 		for (p = list->data; p; p = p->next) {
1641 			sdp_data_t *seq = (sdp_data_t *) p->data;
1642 			int port = __find_port(seq, proto);
1643 			if (port)
1644 				return port;
1645 		}
1646 	}
1647 	return 0;
1648 }
1649 
sdp_get_proto_desc(sdp_list_t * list,int proto)1650 sdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto)
1651 {
1652 	for (; list; list = list->next) {
1653 		sdp_list_t *p;
1654 		for (p = list->data; p; p = p->next) {
1655 			sdp_data_t *seq = (sdp_data_t *) p->data;
1656 			if (SDP_IS_UUID(seq->dtd) &&
1657 					sdp_uuid_to_proto(&seq->val.uuid) == proto)
1658 				return seq->next;
1659 		}
1660 	}
1661 	return NULL;
1662 }
1663 
sdp_get_access_protos(const sdp_record_t * rec,sdp_list_t ** pap)1664 int sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1665 {
1666 	sdp_data_t *pdlist, *curr;
1667 	sdp_list_t *ap = 0;
1668 
1669 	pdlist = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
1670 	if (pdlist == NULL) {
1671 		errno = ENODATA;
1672 		return -1;
1673 	}
1674 	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1675 
1676 	for (; pdlist; pdlist = pdlist->next) {
1677 		sdp_list_t *pds = 0;
1678 		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1679 			pds = sdp_list_append(pds, curr->val.dataseq);
1680 		ap = sdp_list_append(ap, pds);
1681 	}
1682 	*pap = ap;
1683 	return 0;
1684 }
1685 
sdp_get_add_access_protos(const sdp_record_t * rec,sdp_list_t ** pap)1686 int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1687 {
1688 	sdp_data_t *pdlist, *curr;
1689 	sdp_list_t *ap = 0;
1690 
1691 	pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
1692 	if (pdlist == NULL) {
1693 		errno = ENODATA;
1694 		return -1;
1695 	}
1696 	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1697 
1698 	pdlist = pdlist->val.dataseq;
1699 
1700 	for (; pdlist; pdlist = pdlist->next) {
1701 		sdp_list_t *pds = 0;
1702 		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1703 			pds = sdp_list_append(pds, curr->val.dataseq);
1704 		ap = sdp_list_append(ap, pds);
1705 	}
1706 	*pap = ap;
1707 	return 0;
1708 }
1709 
sdp_get_uuidseq_attr(const sdp_record_t * rec,uint16_t attr,sdp_list_t ** seqp)1710 int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **seqp)
1711 {
1712 	sdp_data_t *sdpdata = sdp_data_get(rec, attr);
1713 
1714 	*seqp = NULL;
1715 	if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) {
1716 		sdp_data_t *d;
1717 		for (d = sdpdata->val.dataseq; d; d = d->next) {
1718 			uuid_t *u;
1719 			if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128)
1720 				goto fail;
1721 
1722 			u = malloc(sizeof(uuid_t));
1723 			memset(u, 0, sizeof(uuid_t));
1724 			*u = d->val.uuid;
1725 			*seqp = sdp_list_append(*seqp, u);
1726 		}
1727 		return 0;
1728 	}
1729 fail:
1730 	sdp_list_free(*seqp, free);
1731 	errno = EINVAL;
1732 	return -1;
1733 }
1734 
sdp_set_uuidseq_attr(sdp_record_t * rec,uint16_t aid,sdp_list_t * seq)1735 int sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq)
1736 {
1737 	int status = 0, i, len;
1738 	void **dtds, **values;
1739 	uint8_t uuid16 = SDP_UUID16;
1740 	uint8_t uuid32 = SDP_UUID32;
1741 	uint8_t uuid128 = SDP_UUID128;
1742 	sdp_list_t *p;
1743 
1744 	len = sdp_list_len(seq);
1745 	if (!seq || len == 0)
1746 		return -1;
1747 	dtds = (void **)malloc(len * sizeof(void *));
1748 	values = (void **)malloc(len * sizeof(void *));
1749 	for (p = seq, i = 0; i < len; i++, p = p->next) {
1750 		uuid_t *uuid = (uuid_t *)p->data;
1751 		if (uuid)
1752 			switch (uuid->type) {
1753 			case SDP_UUID16:
1754 				dtds[i] = &uuid16;
1755 				values[i] = &uuid->value.uuid16;
1756 				break;
1757 			case SDP_UUID32:
1758 				dtds[i] = &uuid32;
1759 				values[i] = &uuid->value.uuid32;
1760 				break;
1761 			case SDP_UUID128:
1762 				dtds[i] = &uuid128;
1763 				values[i] = &uuid->value.uuid128;
1764 				break;
1765 			default:
1766 				status = -1;
1767 				break;
1768 			}
1769 		else {
1770 			status = -1;
1771 			break;
1772 		}
1773 	}
1774 	if (status == 0) {
1775 		sdp_data_t *data = sdp_seq_alloc(dtds, values, len);
1776 		sdp_attr_replace(rec, aid, data);
1777 		sdp_pattern_add_uuidseq(rec, seq);
1778 	}
1779 	free(dtds);
1780 	free(values);
1781 	return status;
1782 }
1783 
sdp_get_lang_attr(const sdp_record_t * rec,sdp_list_t ** langSeq)1784 int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq)
1785 {
1786 	sdp_lang_attr_t *lang;
1787 	sdp_data_t *sdpdata, *curr_data;
1788 
1789 	*langSeq = NULL;
1790 	sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST);
1791 	if (sdpdata == NULL) {
1792 		errno = ENODATA;
1793 		return -1;
1794 	}
1795 	curr_data = sdpdata->val.dataseq;
1796 	while (curr_data) {
1797 		sdp_data_t *pCode = curr_data;
1798 		sdp_data_t *pEncoding = pCode->next;
1799 		sdp_data_t *pOffset = pEncoding->next;
1800 		if (pCode && pEncoding && pOffset) {
1801 			lang = malloc(sizeof(sdp_lang_attr_t));
1802 			lang->code_ISO639 = pCode->val.uint16;
1803 			lang->encoding = pEncoding->val.uint16;
1804 			lang->base_offset = pOffset->val.uint16;
1805 			SDPDBG("code_ISO639 :  0x%02x\n", lang->code_ISO639);
1806 			SDPDBG("encoding :     0x%02x\n", lang->encoding);
1807 			SDPDBG("base_offfset : 0x%02x\n", lang->base_offset);
1808 			*langSeq = sdp_list_append(*langSeq, lang);
1809 		}
1810 		curr_data = pOffset->next;
1811 	}
1812 	return 0;
1813 }
1814 
sdp_get_profile_descs(const sdp_record_t * rec,sdp_list_t ** profDescSeq)1815 int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq)
1816 {
1817 	sdp_profile_desc_t *profDesc;
1818 	sdp_data_t *sdpdata, *seq;
1819 
1820 	*profDescSeq = NULL;
1821 	sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST);
1822 	if (!sdpdata || !sdpdata->val.dataseq) {
1823 		errno = ENODATA;
1824 		return -1;
1825 	}
1826 	for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) {
1827 		uuid_t *uuid = NULL;
1828 		uint16_t version = 0x100;
1829 
1830 		if (SDP_IS_UUID(seq->dtd)) {
1831 			uuid = &seq->val.uuid;
1832 		} else {
1833 			sdp_data_t *puuid = seq->val.dataseq;
1834 			sdp_data_t *pVnum = seq->val.dataseq->next;
1835 			if (puuid && pVnum) {
1836 				uuid = &puuid->val.uuid;
1837 				version = pVnum->val.uint16;
1838 			}
1839 		}
1840 
1841 		if (uuid != NULL) {
1842 			profDesc = malloc(sizeof(sdp_profile_desc_t));
1843 			profDesc->uuid = *uuid;
1844 			profDesc->version = version;
1845 #ifdef SDP_DEBUG
1846 			sdp_uuid_print(&profDesc->uuid);
1847 			SDPDBG("Vnum : 0x%04x\n", profDesc->version);
1848 #endif
1849 			*profDescSeq = sdp_list_append(*profDescSeq, profDesc);
1850 		}
1851 	}
1852 	return 0;
1853 }
1854 
sdp_get_server_ver(const sdp_record_t * rec,sdp_list_t ** u16)1855 int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16)
1856 {
1857 	sdp_data_t *d, *curr;
1858 
1859 	*u16 = NULL;
1860 	d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST);
1861 	if (d == NULL) {
1862 		errno = ENODATA;
1863 		return -1;
1864 	}
1865 	for (curr = d->val.dataseq; curr; curr = curr->next)
1866 		*u16 = sdp_list_append(*u16, &curr->val.uint16);
1867 	return 0;
1868 }
1869 
1870 /* flexible extraction of basic attributes - Jean II */
1871 /* How do we expect caller to extract predefined data sequences? */
sdp_get_int_attr(const sdp_record_t * rec,uint16_t attrid,int * value)1872 int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value)
1873 {
1874 	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
1875 
1876 	if (sdpdata)
1877 		/* Verify that it is what the caller expects */
1878 		if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 ||
1879 		sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 ||
1880 		sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 ||
1881 		sdpdata->dtd == SDP_INT32) {
1882 			*value = sdpdata->val.uint32;
1883 			return 0;
1884 		}
1885 	errno = EINVAL;
1886 	return -1;
1887 }
1888 
sdp_get_string_attr(const sdp_record_t * rec,uint16_t attrid,char * value,int valuelen)1889 int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value, int valuelen)
1890 {
1891 	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
1892 	if (sdpdata)
1893 		/* Verify that it is what the caller expects */
1894 		if (sdpdata->dtd == SDP_TEXT_STR8 || sdpdata->dtd == SDP_TEXT_STR16 || sdpdata->dtd == SDP_TEXT_STR32)
1895 			if (strlen(sdpdata->val.str) < valuelen) {
1896 				strcpy(value, sdpdata->val.str);
1897 				return 0;
1898 			}
1899 	errno = EINVAL;
1900 	return -1;
1901 }
1902 
1903 #define get_basic_attr(attrID, pAttrValue, fieldName)		\
1904 	sdp_data_t *data = sdp_data_get(rec, attrID);		\
1905 	if (data) {						\
1906 		*pAttrValue = data->val.fieldName;		\
1907 		return 0;					\
1908 	}							\
1909 	errno = EINVAL;						\
1910 	return -1;
1911 
sdp_get_service_id(const sdp_record_t * rec,uuid_t * uuid)1912 int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid)
1913 {
1914 	get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);
1915 }
1916 
sdp_get_group_id(const sdp_record_t * rec,uuid_t * uuid)1917 int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid)
1918 {
1919 	get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);
1920 }
1921 
sdp_get_record_state(const sdp_record_t * rec,uint32_t * svcRecState)1922 int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState)
1923 {
1924 	get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);
1925 }
1926 
sdp_get_service_avail(const sdp_record_t * rec,uint8_t * svcAvail)1927 int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail)
1928 {
1929 	get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);
1930 }
1931 
sdp_get_service_ttl(const sdp_record_t * rec,uint32_t * svcTTLInfo)1932 int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo)
1933 {
1934 	get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);
1935 }
1936 
sdp_get_database_state(const sdp_record_t * rec,uint32_t * svcDBState)1937 int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState)
1938 {
1939 	get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);
1940 }
1941 
1942 /*
1943  * NOTE that none of the setXXX() functions below will
1944  * actually update the SDP server, unless the
1945  * {register, update}sdp_record_t() function is invoked.
1946  */
1947 
sdp_attr_add_new(sdp_record_t * rec,uint16_t attr,uint8_t dtd,const void * value)1948 int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd, const void *value)
1949 {
1950 	sdp_data_t *d = sdp_data_alloc(dtd, value);
1951 	if (d) {
1952 		sdp_attr_replace(rec, attr, d);
1953 		return 0;
1954 	}
1955 	return -1;
1956 }
1957 
1958 /*
1959  * Set the information attributes of the service
1960  * pointed to by rec. The attributes are
1961  * service name, description and provider name
1962  */
sdp_set_info_attr(sdp_record_t * rec,const char * name,const char * prov,const char * desc)1963 void sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov, const char *desc)
1964 {
1965 	if (name)
1966 		sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY, SDP_TEXT_STR8, (void *)name);
1967 	if (prov)
1968 		sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY, SDP_TEXT_STR8, (void *)prov);
1969 	if (desc)
1970 		sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY, SDP_TEXT_STR8, (void *)desc);
1971 }
1972 
access_proto_to_dataseq(sdp_record_t * rec,sdp_list_t * proto)1973 static sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto)
1974 {
1975 	sdp_data_t *seq = NULL;
1976 	void *dtds[10], *values[10];
1977 	void **seqDTDs, **seqs;
1978 	int i, seqlen;
1979 	sdp_list_t *p;
1980 
1981 	seqlen = sdp_list_len(proto);
1982 	seqDTDs = (void **)malloc(seqlen * sizeof(void *));
1983 	seqs = (void **)malloc(seqlen * sizeof(void *));
1984 	for (i = 0, p = proto; p; p = p->next, i++) {
1985 		sdp_list_t *elt = (sdp_list_t *)p->data;
1986 		sdp_data_t *s;
1987 		int pslen = 0;
1988 		for (; elt && pslen < sizeof(dtds); elt = elt->next, pslen++) {
1989 			sdp_data_t *d = (sdp_data_t *)elt->data;
1990 			dtds[pslen] = &d->dtd;
1991 			switch (d->dtd) {
1992 			case SDP_UUID16:
1993 				values[pslen] = &((uuid_t *)d)->value.uuid16;
1994 				break;
1995 			case SDP_UUID32:
1996 				values[pslen] = &((uuid_t *)d)->value.uuid32;
1997 				break;
1998 			case SDP_UUID128:
1999 				values[pslen] = &((uuid_t *)d)->value.uuid128;
2000 				break;
2001 			case SDP_UINT8:
2002 				values[pslen] = &d->val.uint8;
2003 				break;
2004 			case SDP_UINT16:
2005 				values[pslen] = &d->val.uint16;
2006 				break;
2007 			case SDP_SEQ8:
2008 			case SDP_SEQ16:
2009 			case SDP_SEQ32:
2010 				values[pslen] = d;
2011 				break;
2012 			// FIXME: more
2013 			}
2014 		}
2015 		s = sdp_seq_alloc(dtds, values, pslen);
2016 		if (s) {
2017 			seqDTDs[i] = &s->dtd;
2018 			seqs[i] = s;
2019 		}
2020 	}
2021 	seq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2022 	free(seqDTDs);
2023 	free(seqs);
2024 	return seq;
2025 }
2026 
2027 /*
2028  * sets the access protocols of the service specified
2029  * to the value specified in "access_proto"
2030  *
2031  * Note that if there are alternate mechanisms by
2032  * which the service is accessed, then they should
2033  * be specified as sequences
2034  *
2035  * Using a value of NULL for accessProtocols has
2036  * effect of removing this attribute (if previously set)
2037  *
2038  * This function replaces the existing sdp_access_proto_t
2039  * structure (if any) with the new one specified.
2040  *
2041  * returns 0 if successful or -1 if there is a failure.
2042  */
sdp_set_access_protos(sdp_record_t * rec,const sdp_list_t * ap)2043 int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
2044 {
2045 	const sdp_list_t *p;
2046 	sdp_data_t *protos = NULL;
2047 
2048 	for (p = ap; p; p = p->next) {
2049 		sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data);
2050 		protos = sdp_seq_append(protos, seq);
2051 	}
2052 
2053 	sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos);
2054 
2055 	return 0;
2056 }
2057 
sdp_set_add_access_protos(sdp_record_t * rec,const sdp_list_t * ap)2058 int sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
2059 {
2060 	const sdp_list_t *p;
2061 	sdp_data_t *protos = NULL;
2062 
2063 	for (p = ap; p; p = p->next) {
2064 		sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data);
2065 		protos = sdp_seq_append(protos, seq);
2066 	}
2067 
2068 	sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST,
2069 			protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL);
2070 
2071 	return 0;
2072 }
2073 
2074 /*
2075  * set the "LanguageBase" attributes of the service record
2076  * record to the value specified in "langAttrList".
2077  *
2078  * "langAttrList" is a linked list of "sdp_lang_attr_t"
2079  * objects, one for each language in which user visible
2080  * attributes are present in the service record.
2081  *
2082  * Using a value of NULL for langAttrList has
2083  * effect of removing this attribute (if previously set)
2084  *
2085  * This function replaces the exisiting sdp_lang_attr_t
2086  * structure (if any) with the new one specified.
2087  *
2088  * returns 0 if successful or -1 if there is a failure.
2089  */
sdp_set_lang_attr(sdp_record_t * rec,const sdp_list_t * seq)2090 int sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq)
2091 {
2092 	uint8_t uint16 = SDP_UINT16;
2093 	int status = 0, i = 0, seqlen = sdp_list_len(seq);
2094 	void **dtds = (void **)malloc(3 * seqlen * sizeof(void *));
2095 	void **values = (void **)malloc(3 * seqlen * sizeof(void *));
2096 	const sdp_list_t *p;
2097 
2098 	for (p = seq; p; p = p->next) {
2099 		sdp_lang_attr_t *lang = (sdp_lang_attr_t *)p->data;
2100 		if (!lang) {
2101 			status = -1;
2102 			break;
2103 		}
2104 		dtds[i] = &uint16;
2105 		values[i] = &lang->code_ISO639;
2106 		i++;
2107 		dtds[i] = &uint16;
2108 		values[i] = &lang->encoding;
2109 		i++;
2110 		dtds[i] = &uint16;
2111 		values[i] = &lang->base_offset;
2112 		i++;
2113 	}
2114 	if (status == 0) {
2115 		sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen);
2116 		sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq);
2117 	}
2118 	free(dtds);
2119 	free(values);
2120 	return status;
2121 }
2122 
2123 /*
2124  * set the "ServiceID" attribute of the service.
2125  *
2126  * This is the UUID of the service.
2127  *
2128  * returns 0 if successful or -1 if there is a failure.
2129  */
sdp_set_service_id(sdp_record_t * rec,uuid_t uuid)2130 void sdp_set_service_id(sdp_record_t *rec, uuid_t uuid)
2131 {
2132 	switch (uuid.type) {
2133 	case SDP_UUID16:
2134 		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16, &uuid.value.uuid16);
2135 		break;
2136 	case SDP_UUID32:
2137 		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32, &uuid.value.uuid32);
2138 		break;
2139 	case SDP_UUID128:
2140 		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128, &uuid.value.uuid128);
2141 		break;
2142 	}
2143 	sdp_pattern_add_uuid(rec, &uuid);
2144 }
2145 
2146 /*
2147  * set the GroupID attribute of the service record defining a group.
2148  *
2149  * This is the UUID of the group.
2150  *
2151  * returns 0 if successful or -1 if there is a failure.
2152  */
sdp_set_group_id(sdp_record_t * rec,uuid_t uuid)2153 void sdp_set_group_id(sdp_record_t *rec, uuid_t uuid)
2154 {
2155 	switch (uuid.type) {
2156 	case SDP_UUID16:
2157 		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16, &uuid.value.uuid16);
2158 		break;
2159 	case SDP_UUID32:
2160 		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32, &uuid.value.uuid32);
2161 		break;
2162 	case SDP_UUID128:
2163 		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128, &uuid.value.uuid128);
2164 		break;
2165 	}
2166 	sdp_pattern_add_uuid(rec, &uuid);
2167 }
2168 
2169 /*
2170  * set the ProfileDescriptorList attribute of the service record
2171  * pointed to by record to the value specified in "profileDesc".
2172  *
2173  * Each element in the list is an object of type
2174  * sdp_profile_desc_t which is a definition of the
2175  * Bluetooth profile that this service conforms to.
2176  *
2177  * Using a value of NULL for profileDesc has
2178  * effect of removing this attribute (if previously set)
2179  *
2180  * This function replaces the exisiting ProfileDescriptorList
2181  * structure (if any) with the new one specified.
2182  *
2183  * returns 0 if successful or -1 if there is a failure.
2184  */
sdp_set_profile_descs(sdp_record_t * rec,const sdp_list_t * profiles)2185 int sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles)
2186 {
2187 	int status = 0;
2188 	uint8_t uuid16 = SDP_UUID16;
2189 	uint8_t uuid32 = SDP_UUID32;
2190 	uint8_t uuid128 = SDP_UUID128;
2191 	uint8_t uint16 = SDP_UINT16;
2192 	int i = 0, seqlen = sdp_list_len(profiles);
2193 	void **seqDTDs = (void **)malloc(seqlen * sizeof(void *));
2194 	void **seqs = (void **)malloc(seqlen * sizeof(void *));
2195 	const sdp_list_t *p;
2196 
2197 	for (p = profiles; p; p = p->next) {
2198 		sdp_data_t *seq;
2199 		void *dtds[2], *values[2];
2200 		sdp_profile_desc_t *profile = (sdp_profile_desc_t *)p->data;
2201 		if (!profile) {
2202 			status = -1;
2203 			break;
2204 		}
2205 		switch (profile->uuid.type) {
2206 		case SDP_UUID16:
2207 			dtds[0] = &uuid16;
2208 			values[0] = &profile->uuid.value.uuid16;
2209 			break;
2210 		case SDP_UUID32:
2211 			dtds[0] = &uuid32;
2212 			values[0] = &profile->uuid.value.uuid32;
2213 			break;
2214 		case SDP_UUID128:
2215 			dtds[0] = &uuid128;
2216 			values[0] = &profile->uuid.value.uuid128;
2217 			break;
2218 		default:
2219 			status = -1;
2220 			break;
2221 		}
2222 		dtds[1] = &uint16;
2223 		values[1] = &profile->version;
2224 		seq = sdp_seq_alloc(dtds, values, 2);
2225 		if (seq) {
2226 			seqDTDs[i] = &seq->dtd;
2227 			seqs[i] = seq;
2228 			sdp_pattern_add_uuid(rec, &profile->uuid);
2229 		}
2230 		i++;
2231 	}
2232 	if (status == 0) {
2233 		sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2234 		sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq);
2235 	}
2236 	free(seqDTDs);
2237 	free(seqs);
2238 	return status;
2239 }
2240 
2241 /*
2242  * sets various URL attributes of the service
2243  * pointed to by record. The URL include
2244  *
2245  * client: a URL to the client's
2246  *   platform specific (WinCE, PalmOS) executable
2247  *   code that can be used to access this service.
2248  *
2249  * doc: a URL pointing to service documentation
2250  *
2251  * icon: a URL to an icon that can be used to represent
2252  *   this service.
2253  *
2254  * Note that you need to pass NULL for any URLs
2255  * that you don't want to set or remove
2256  */
sdp_set_url_attr(sdp_record_t * rec,const char * client,const char * doc,const char * icon)2257 void sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc, const char *icon)
2258 {
2259 	sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client);
2260 	sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc);
2261 	sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon);
2262 }
2263 
2264 /*
2265  * The code in this function is executed only once per
2266  * thread. We compute the actual bit value of the Bluetooth
2267  * base UUID which is a string defined in bt_std_values.h
2268  * and is assumed to be of the standard form with "-" separators.
2269  *
2270  * The algorithm however converts the string to 4 unsigned longs
2271  * using the strtoul() and assigns the values in sequence to
2272  * the 128bit value
2273  */
sdp_create_base_uuid(void)2274 uint128_t *sdp_create_base_uuid(void)
2275 {
2276 	uint128_t *base_uuid;
2277 	char baseStr[128];
2278 	int delim = '-';
2279 	unsigned long dataLongValue;
2280 	char *delimPtr;
2281 	char *dataPtr;
2282 	char temp[10];
2283 	int toBeCopied;
2284 	uint8_t *data;
2285 
2286 	strcpy(baseStr, BASE_UUID);
2287 	base_uuid = malloc(sizeof(uint128_t));
2288 	if (!base_uuid)
2289 		return NULL;
2290 
2291 	data = base_uuid->data;
2292 	memset(data, '\0', sizeof(uint128_t));
2293 	memset(temp, '\0', 10);
2294 	dataPtr = baseStr;
2295 	delimPtr = NULL;
2296 	delimPtr = strchr(dataPtr, delim);
2297 	toBeCopied = delimPtr - dataPtr;
2298 	if (toBeCopied != 8) {
2299 		SDPDBG("To be copied(1) : %d\n", toBeCopied);
2300 		free(base_uuid);
2301 		return NULL;
2302 	}
2303 	strncpy(temp, dataPtr, toBeCopied);
2304 	dataLongValue = htonl(strtoul(temp, NULL, 16));
2305 	memcpy(&data[0], &dataLongValue, 4);
2306 
2307 	/*
2308 	 * Get the next 4 bytes (note that there is a "-"
2309 	 * between them now)
2310 	 */
2311 	memset(temp, '\0', 10);
2312 	dataPtr = delimPtr + 1;
2313 	delimPtr = strchr(dataPtr, delim);
2314 	toBeCopied = delimPtr - dataPtr;
2315 	if (toBeCopied != 4) {
2316 		SDPDBG("To be copied(2) : %d\n", toBeCopied);
2317 		free(base_uuid);
2318 		return NULL;
2319 	}
2320 	strncpy(temp, dataPtr, toBeCopied);
2321 	dataPtr = delimPtr + 1;
2322 	delimPtr = strchr(dataPtr, delim);
2323 	toBeCopied = delimPtr - dataPtr;
2324 	if (toBeCopied != 4) {
2325 		SDPDBG("To be copied(3) : %d\n", toBeCopied);
2326 		free(base_uuid);
2327 		return NULL;
2328 	}
2329 	strncat(temp, dataPtr, toBeCopied);
2330 	dataLongValue = htonl(strtoul(temp, NULL, 16));
2331 	memcpy(&data[4], &dataLongValue, 4);
2332 
2333 	/*
2334 	 * Get the last 4 bytes (note that there are 6 bytes
2335 	 * after the last separator, which is truncated (2+4)
2336 	 */
2337 	memset(temp, '\0', 10);
2338 	dataPtr = delimPtr + 1;
2339 	dataPtr = delimPtr + 1;
2340 	delimPtr = strchr(dataPtr, delim);
2341 	toBeCopied = delimPtr - dataPtr;
2342 	if (toBeCopied != 4) {
2343 		SDPDBG("To be copied(4) : %d\n", toBeCopied);
2344 		free(base_uuid);
2345 		return NULL;
2346 	}
2347 	strncpy(temp, dataPtr, toBeCopied);
2348 	strncat(temp, (delimPtr + 1), 4);
2349 	dataLongValue = htonl(strtoul(temp, NULL, 16));
2350 	memcpy(&data[8], &dataLongValue, 4);
2351 	dataLongValue = htonl(strtoul(delimPtr + 5, NULL, 16));
2352 	memcpy(&data[12], &dataLongValue, 4);
2353 
2354 	return base_uuid;
2355 }
2356 
sdp_uuid16_create(uuid_t * u,uint16_t val)2357 uuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val)
2358 {
2359 	memset(u, 0, sizeof(uuid_t));
2360 	u->type = SDP_UUID16;
2361 	u->value.uuid16 = val;
2362 	return u;
2363 }
2364 
sdp_uuid32_create(uuid_t * u,uint32_t val)2365 uuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val)
2366 {
2367 	memset(u, 0, sizeof(uuid_t));
2368 	u->type = SDP_UUID32;
2369 	u->value.uuid32 = val;
2370 	return u;
2371 }
2372 
sdp_uuid128_create(uuid_t * u,const void * val)2373 uuid_t *sdp_uuid128_create(uuid_t *u, const void *val)
2374 {
2375 	memset(u, 0, sizeof(uuid_t));
2376 	u->type = SDP_UUID128;
2377 	memcpy(&u->value.uuid128, val, sizeof(uint128_t));
2378 	return u;
2379 }
2380 
2381 /*
2382  * UUID comparison function
2383  * returns 0 if uuidValue1 == uuidValue2 else -1
2384  */
sdp_uuid16_cmp(const void * p1,const void * p2)2385 int sdp_uuid16_cmp(const void *p1, const void *p2)
2386 {
2387 	const uuid_t *u1 = (const uuid_t *)p1;
2388 	const uuid_t *u2 = (const uuid_t *)p2;
2389 	return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t));
2390 }
2391 
2392 /*
2393  * UUID comparison function
2394  * returns 0 if uuidValue1 == uuidValue2 else -1
2395  */
sdp_uuid128_cmp(const void * p1,const void * p2)2396 int sdp_uuid128_cmp(const void *p1, const void *p2)
2397 {
2398 	const uuid_t *u1 = (const uuid_t *)p1;
2399 	const uuid_t *u2 = (const uuid_t *)p2;
2400 	return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t));
2401 }
2402 
2403 /*
2404  * 128 to 16 bit and 32 to 16 bit UUID conversion functions
2405  * yet to be implemented. Note that the input is in NBO in
2406  * both 32 and 128 bit UUIDs and conversion is needed
2407  */
sdp_uuid16_to_uuid128(uuid_t * uuid128,uuid_t * uuid16)2408 void sdp_uuid16_to_uuid128(uuid_t *uuid128, uuid_t *uuid16)
2409 {
2410 	/*
2411 	 * We have a 16 bit value, which needs to be added to
2412 	 * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base
2413 	 */
2414 	unsigned short data1;
2415 
2416 	// allocate a 128bit UUID and init to the Bluetooth base UUID
2417 	uuid128->value.uuid128 = bluetooth_base_uuid;
2418 	uuid128->type = SDP_UUID128;
2419 
2420 	// extract bytes 2 and 3 of 128bit BT base UUID
2421 	memcpy(&data1, &bluetooth_base_uuid.data[2], 2);
2422 
2423 	// add the given UUID (16 bits)
2424 	data1 += htons(uuid16->value.uuid16);
2425 
2426 	// set bytes 2 and 3 of the 128 bit value
2427 	memcpy(&uuid128->value.uuid128.data[2], &data1, 2);
2428 }
2429 
sdp_uuid32_to_uuid128(uuid_t * uuid128,uuid_t * uuid32)2430 void sdp_uuid32_to_uuid128(uuid_t *uuid128, uuid_t *uuid32)
2431 {
2432 	/*
2433 	 * We have a 32 bit value, which needs to be added to
2434 	 * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base
2435 	 */
2436 	unsigned int data0;
2437 
2438 	// allocate a 128bit UUID and init to the Bluetooth base UUID
2439 	uuid128->value.uuid128 = bluetooth_base_uuid;
2440 	uuid128->type = SDP_UUID128;
2441 
2442 	// extract first 4 bytes
2443 	memcpy(&data0, &bluetooth_base_uuid.data[0], 4);
2444 
2445 	// add the given UUID (32bits)
2446 	data0 += htonl(uuid32->value.uuid32);
2447 
2448 	// set the 4 bytes of the 128 bit value
2449 	memcpy(&uuid128->value.uuid128.data[0], &data0, 4);
2450 }
2451 
sdp_uuid_to_uuid128(uuid_t * uuid)2452 uuid_t *sdp_uuid_to_uuid128(uuid_t *uuid)
2453 {
2454 	uuid_t *uuid128 = bt_malloc(sizeof(uuid_t));
2455 	memset(uuid128, 0, sizeof(uuid_t));
2456 	switch (uuid->type) {
2457 	case SDP_UUID128:
2458 		*uuid128 = *uuid;
2459 		break;
2460 	case SDP_UUID32:
2461 		sdp_uuid32_to_uuid128(uuid128, uuid);
2462 		break;
2463 	case SDP_UUID16:
2464 		sdp_uuid16_to_uuid128(uuid128, uuid);
2465 		break;
2466 	}
2467 	return uuid128;
2468 }
2469 
2470 /*
2471  * converts a 128-bit uuid to a 16/32-bit one if possible
2472  * returns true if uuid contains a 16/32-bit UUID at exit
2473  */
sdp_uuid128_to_uuid(uuid_t * uuid)2474 int sdp_uuid128_to_uuid(uuid_t *uuid)
2475 {
2476 	uint128_t *b = &bluetooth_base_uuid;
2477 	uint128_t *u = &uuid->value.uuid128;
2478 	uint32_t data;
2479 	int i;
2480 
2481 	if (uuid->type != SDP_UUID128)
2482 		return 1;
2483 
2484 	for (i = 4; i < sizeof(b->data); i++)
2485 		if (b->data[i] != u->data[i])
2486 			return 0;
2487 
2488 	memcpy(&data, u->data, 4);
2489 	data = htonl(data);
2490 	if (data <= 0xffff) {
2491 		uuid->type = SDP_UUID16;
2492 		uuid->value.uuid16 = (uint16_t) data;
2493 	} else {
2494 		uuid->type = SDP_UUID32;
2495 		uuid->value.uuid32 = data;
2496 	}
2497 	return 1;
2498 }
2499 
2500 /*
2501  * convert a UUID to the 16-bit short-form
2502  */
sdp_uuid_to_proto(uuid_t * uuid)2503 int sdp_uuid_to_proto(uuid_t *uuid)
2504 {
2505 	uuid_t u = *uuid;
2506 	if (sdp_uuid128_to_uuid(&u)) {
2507 		switch (u.type) {
2508 		case SDP_UUID16:
2509 			return u.value.uuid16;
2510 		case SDP_UUID32:
2511 			return u.value.uuid32;
2512 		}
2513 	}
2514 	return 0;
2515 }
2516 
2517 /*
2518  * This function appends data to the PDU buffer "dst" from source "src".
2519  * The data length is also computed and set.
2520  * Should the PDU length exceed 2^8, then sequence type is
2521  * set accordingly and the data is memmove()'d.
2522  */
sdp_append_to_buf(sdp_buf_t * dst,uint8_t * data,uint32_t len)2523 void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len)
2524 {
2525 	uint8_t *p = dst->data;
2526 	uint8_t dtd = *(uint8_t *) p;
2527 
2528 	SDPDBG("Append src size: %d\n", len);
2529 	SDPDBG("Append dst size: %d\n", dst->data_size);
2530 	SDPDBG("Dst buffer size: %d\n", dst->buf_size);
2531 	if (dst->data_size + len > dst->buf_size) {
2532 		int need = SDP_PDU_CHUNK_SIZE * ((len / SDP_PDU_CHUNK_SIZE) + 1);
2533 		dst->data = realloc(dst->data, dst->buf_size + need);
2534 
2535 		SDPDBG("Realloc'ing : %d\n", need);
2536 
2537 		if (dst->data == NULL) {
2538 			SDPERR("Realloc fails \n");
2539 		}
2540 		dst->buf_size += need;
2541 	}
2542 	if (dst->data_size == 0 && dtd == 0) {
2543 		// create initial sequence
2544 		*(uint8_t *)p = SDP_SEQ8;
2545 		p += sizeof(uint8_t);
2546 		dst->data_size += sizeof(uint8_t);
2547 		// reserve space for sequence size
2548 		p += sizeof(uint8_t);
2549 		dst->data_size += sizeof(uint8_t);
2550 	}
2551 
2552 	memcpy(dst->data + dst->data_size, data, len);
2553 	dst->data_size += len;
2554 
2555 	dtd = *(uint8_t *)dst->data;
2556 	if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) {
2557 		short offset = sizeof(uint8_t) + sizeof(uint8_t);
2558 		memmove(dst->data + offset + 1, dst->data + offset, dst->data_size - offset);
2559 		p = dst->data;
2560 		*(uint8_t *) p = SDP_SEQ16;
2561 		p += sizeof(uint8_t);
2562 		dst->data_size += 1;
2563 	}
2564 	p = dst->data;
2565 	dtd = *(uint8_t *) p;
2566 	p += sizeof(uint8_t);
2567 	switch (dtd) {
2568 	case SDP_SEQ8:
2569 		*(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t);
2570 		break;
2571 	case SDP_SEQ16:
2572 		bt_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *) p);
2573 		break;
2574 	case SDP_SEQ32:
2575 		bt_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *) p);
2576 		break;
2577 	}
2578 }
2579 
sdp_append_to_pdu(sdp_buf_t * pdu,sdp_data_t * d)2580 void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d)
2581 {
2582 	uint8_t buf[256];
2583 	sdp_buf_t append;
2584 
2585 	memset(&append, 0, sizeof(sdp_buf_t));
2586 	append.data = buf;
2587 	append.buf_size = sizeof(buf);
2588 	append.data_size = 0;
2589 
2590 	sdp_set_attrid(&append, d->attrId);
2591 	sdp_gen_pdu(&append, d);
2592 	sdp_append_to_buf(pdu, append.data, append.data_size);
2593 }
2594 
2595 /*
2596  * Registers an sdp record.
2597  *
2598  * It is incorrect to call this method on a record that
2599  * has been already registered with the server.
2600  *
2601  * Returns zero on success, otherwise -1 (and sets errno).
2602  */
sdp_device_record_register_binary(sdp_session_t * session,bdaddr_t * device,uint8_t * data,uint32_t size,uint8_t flags,uint32_t * handle)2603 int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, uint8_t *data, uint32_t size, uint8_t flags, uint32_t *handle)
2604 {
2605 	uint8_t *req, *rsp, *p;
2606 	uint32_t reqsize, rspsize;
2607 	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2608 	int status;
2609 
2610 	SDPDBG("");
2611 
2612 	if (!session->local) {
2613 		errno = EREMOTE;
2614 		return -1;
2615 	}
2616 	req = malloc(SDP_REQ_BUFFER_SIZE);
2617 	rsp = malloc(SDP_RSP_BUFFER_SIZE);
2618 	if (req == NULL || rsp == NULL) {
2619 		status = -1;
2620 		errno = ENOMEM;
2621 		goto end;
2622 	}
2623 
2624 	reqhdr = (sdp_pdu_hdr_t *)req;
2625 	reqhdr->pdu_id = SDP_SVC_REGISTER_REQ;
2626 	reqhdr->tid    = htons(sdp_gen_tid(session));
2627 	reqsize = sizeof(sdp_pdu_hdr_t) + 1;
2628 	p = req + sizeof(sdp_pdu_hdr_t);
2629 
2630 	if (bacmp(device, BDADDR_ANY)) {
2631 		*p++ = flags | SDP_DEVICE_RECORD;
2632 		bacpy((bdaddr_t *) p, device);
2633 		p += sizeof(bdaddr_t);
2634 		reqsize += sizeof(bdaddr_t);
2635 	} else
2636 		*p++ = flags;
2637 
2638 	memcpy(p, data, size);
2639 	reqsize += size;
2640 	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2641 
2642 	status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize);
2643 	if (status < 0)
2644 		goto end;
2645 
2646 	if (rspsize < sizeof(sdp_pdu_hdr_t)) {
2647 		SDPERR("Unexpected end of packet");
2648 		errno = EPROTO;
2649 		status = -1;
2650 		goto end;
2651 	}
2652 
2653 	rsphdr = (sdp_pdu_hdr_t *) rsp;
2654 	p = rsp + sizeof(sdp_pdu_hdr_t);
2655 
2656 	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2657 		/* Invalid service record */
2658 		errno = EINVAL;
2659 		status = -1;
2660 	} else if (rsphdr->pdu_id != SDP_SVC_REGISTER_RSP) {
2661 		errno = EPROTO;
2662 		status = -1;
2663 	} else {
2664 		if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint32_t)) {
2665 			SDPERR("Unexpected end of packet");
2666 			errno = EPROTO;
2667 			status = -1;
2668 			goto end;
2669 		}
2670 		if (handle)
2671 			*handle  = ntohl(bt_get_unaligned((uint32_t *) p));
2672 	}
2673 
2674 end:
2675 	if (req)
2676 		free(req);
2677 
2678 	if (rsp)
2679 		free(rsp);
2680 
2681 	return status;
2682 }
2683 
sdp_device_record_register(sdp_session_t * session,bdaddr_t * device,sdp_record_t * rec,uint8_t flags)2684 int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags)
2685 {
2686 	sdp_buf_t pdu;
2687 	uint32_t handle;
2688 	int err;
2689 
2690 	SDPDBG("");
2691 
2692 	if (rec->handle && rec->handle != 0xffffffff) {
2693 		uint32_t handle = rec->handle;
2694 		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
2695 		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
2696 	}
2697 
2698 	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
2699 		errno = ENOMEM;
2700 		return -1;
2701 	}
2702 
2703 	err = sdp_device_record_register_binary(session, device,
2704 				pdu.data, pdu.data_size, flags, &handle);
2705 
2706 	free(pdu.data);
2707 
2708 	if (err == 0) {
2709 		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
2710 		rec->handle = handle;
2711 		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
2712 	}
2713 
2714 	return err;
2715 }
2716 
sdp_record_register(sdp_session_t * session,sdp_record_t * rec,uint8_t flags)2717 int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags)
2718 {
2719 	return sdp_device_record_register(session, BDADDR_ANY, rec, flags);
2720 }
2721 
2722 /*
2723  * unregister a service record
2724  */
sdp_device_record_unregister_binary(sdp_session_t * session,bdaddr_t * device,uint32_t handle)2725 int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle)
2726 {
2727 	uint8_t *reqbuf, *rspbuf, *p;
2728 	uint32_t reqsize = 0, rspsize = 0;
2729 	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2730 	int status;
2731 
2732 	SDPDBG("");
2733 
2734 	if (handle == SDP_SERVER_RECORD_HANDLE) {
2735 		errno = EINVAL;
2736 		return -1;
2737 	}
2738 
2739 	if (!session->local) {
2740 		errno = EREMOTE;
2741 		return -1;
2742 	}
2743 
2744 	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2745 	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2746 	if (!reqbuf || !rspbuf) {
2747 		errno = ENOMEM;
2748 		status = -1;
2749 		goto end;
2750 	}
2751 	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2752 	reqhdr->pdu_id = SDP_SVC_REMOVE_REQ;
2753 	reqhdr->tid    = htons(sdp_gen_tid(session));
2754 
2755 	p = reqbuf + sizeof(sdp_pdu_hdr_t);
2756 	reqsize = sizeof(sdp_pdu_hdr_t);
2757 	bt_put_unaligned(htonl(handle), (uint32_t *) p);
2758 	reqsize += sizeof(uint32_t);
2759 
2760 	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2761 	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2762 	if (status < 0)
2763 		goto end;
2764 
2765 	if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
2766 		SDPERR("Unexpected end of packet");
2767 		errno = EPROTO;
2768 		status = -1;
2769 		goto end;
2770 	}
2771 
2772 	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2773 	p = rspbuf + sizeof(sdp_pdu_hdr_t);
2774 	status = bt_get_unaligned((uint16_t *) p);
2775 
2776 	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2777 		/* For this case the status always is invalid record handle */
2778 		errno = EINVAL;
2779 		status = -1;
2780 	} else if (rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) {
2781 		errno = EPROTO;
2782 		status = -1;
2783 	}
2784 end:
2785 	if (reqbuf)
2786 		free(reqbuf);
2787 
2788 	if (rspbuf)
2789 		free(rspbuf);
2790 
2791 	return status;
2792 }
2793 
sdp_device_record_unregister(sdp_session_t * session,bdaddr_t * device,sdp_record_t * rec)2794 int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec)
2795 {
2796 	int err;
2797 
2798 	err = sdp_device_record_unregister_binary(session, device, rec->handle);
2799 	if (err == 0)
2800 		sdp_record_free(rec);
2801 
2802 	return err;
2803 }
2804 
sdp_record_unregister(sdp_session_t * session,sdp_record_t * rec)2805 int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec)
2806 {
2807 	return sdp_device_record_unregister(session, BDADDR_ANY, rec);
2808 }
2809 
2810 /*
2811  * modify an existing service record
2812  */
sdp_device_record_update_binary(sdp_session_t * session,bdaddr_t * device,uint32_t handle,uint8_t * data,uint32_t size)2813 int sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size)
2814 {
2815 	return -1;
2816 }
2817 
sdp_device_record_update(sdp_session_t * session,bdaddr_t * device,const sdp_record_t * rec)2818 int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec)
2819 {
2820 	uint8_t *reqbuf, *rspbuf, *p;
2821 	uint32_t reqsize, rspsize;
2822 	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2823 	uint32_t handle;
2824 	sdp_buf_t pdu;
2825 	int status;
2826 
2827 	SDPDBG("");
2828 
2829 	handle = rec->handle;
2830 
2831 	if (handle == SDP_SERVER_RECORD_HANDLE) {
2832 		errno = EINVAL;
2833 		return -1;
2834 	}
2835 	if (!session->local) {
2836 		errno = EREMOTE;
2837 		return -1;
2838 	}
2839 	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2840 	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2841 	if (!reqbuf || !rspbuf) {
2842 		errno = ENOMEM;
2843 		status = -1;
2844 		goto end;
2845 	}
2846 	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2847 	reqhdr->pdu_id = SDP_SVC_UPDATE_REQ;
2848 	reqhdr->tid    = htons(sdp_gen_tid(session));
2849 
2850 	p = reqbuf + sizeof(sdp_pdu_hdr_t);
2851 	reqsize = sizeof(sdp_pdu_hdr_t);
2852 
2853 	bt_put_unaligned(htonl(handle), (uint32_t *) p);
2854 	reqsize += sizeof(uint32_t);
2855 	p += sizeof(uint32_t);
2856 
2857 	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
2858 		errno = ENOMEM;
2859 		status = -1;
2860 		goto end;
2861 	}
2862 	memcpy(p, pdu.data, pdu.data_size);
2863 	reqsize += pdu.data_size;
2864 	free(pdu.data);
2865 
2866 	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2867 	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2868 	if (status < 0)
2869 		goto end;
2870 
2871 	if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
2872 		SDPERR("Unexpected end of packet");
2873 		errno = EPROTO;
2874 		status = -1;
2875 		goto end;
2876 	}
2877 
2878 	SDPDBG("Send req status : %d\n", status);
2879 
2880 	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2881 	p = rspbuf + sizeof(sdp_pdu_hdr_t);
2882 	status = bt_get_unaligned((uint16_t *) p);
2883 
2884 	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2885 		/* The status can be invalid sintax or invalid record handle */
2886 		errno = EINVAL;
2887 		status = -1;
2888 	} else if (rsphdr->pdu_id != SDP_SVC_UPDATE_RSP) {
2889 		errno = EPROTO;
2890 		status = -1;
2891 	}
2892 end:
2893 	if (reqbuf)
2894 		free(reqbuf);
2895 	if (rspbuf)
2896 		free(rspbuf);
2897 	return status;
2898 }
2899 
sdp_record_update(sdp_session_t * session,const sdp_record_t * rec)2900 int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec)
2901 {
2902 	return sdp_device_record_update(session, BDADDR_ANY, rec);
2903 }
2904 
sdp_record_alloc()2905 sdp_record_t *sdp_record_alloc()
2906 {
2907 	sdp_record_t *rec = malloc(sizeof(sdp_record_t));
2908 	memset((void *)rec, 0, sizeof(sdp_record_t));
2909 	rec->handle = 0xffffffff;
2910 	return rec;
2911 }
2912 
2913 /*
2914  * Free the contents of a service record
2915  */
sdp_record_free(sdp_record_t * rec)2916 void sdp_record_free(sdp_record_t *rec)
2917 {
2918 	sdp_list_free(rec->attrlist, (sdp_free_func_t)sdp_data_free);
2919 	sdp_list_free(rec->pattern, free);
2920 	free(rec);
2921 }
2922 
sdp_pattern_add_uuid(sdp_record_t * rec,uuid_t * uuid)2923 void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid)
2924 {
2925 	uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid);
2926 
2927 	SDPDBG("SvcRec : 0x%lx\n", (unsigned long)rec);
2928 	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
2929 	SDPDBG("Trying to add : 0x%lx\n", (unsigned long)uuid128);
2930 
2931 	if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL)
2932 		rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp);
2933 	else
2934 		bt_free(uuid128);
2935 
2936 	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
2937 }
2938 
sdp_pattern_add_uuidseq(sdp_record_t * rec,sdp_list_t * seq)2939 void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq)
2940 {
2941 	for (; seq; seq = seq->next) {
2942 		uuid_t *uuid = (uuid_t *)seq->data;
2943 		sdp_pattern_add_uuid(rec, uuid);
2944 	}
2945 }
2946 
2947 /*
2948  * Extract a sequence of service record handles from a PDU buffer
2949  * and add the entries to a sdp_list_t. Note that the service record
2950  * handles are not in "data element sequence" form, but just like
2951  * an array of service handles
2952  */
extract_record_handle_seq(uint8_t * pdu,int bufsize,sdp_list_t ** seq,int count,int * scanned)2953 static void extract_record_handle_seq(uint8_t *pdu, int bufsize, sdp_list_t **seq, int count, int *scanned)
2954 {
2955 	sdp_list_t *pSeq = *seq;
2956 	uint8_t *pdata = pdu;
2957 	int n;
2958 
2959 	for (n = 0; n < count; n++) {
2960 		if (bufsize < sizeof(uint32_t)) {
2961 			SDPERR("Unexpected end of packet");
2962 			break;
2963 		}
2964 		uint32_t *pSvcRec = malloc(sizeof(uint32_t));
2965 		*pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata));
2966 		pSeq = sdp_list_append(pSeq, pSvcRec);
2967 		pdata += sizeof(uint32_t);
2968 		*scanned += sizeof(uint32_t);
2969 		bufsize -= sizeof(uint32_t);
2970 	}
2971 	*seq = pSeq;
2972 }
2973 /*
2974  * Generate the attribute sequence pdu form
2975  * from sdp_list_t elements. Return length of attr seq
2976  */
gen_dataseq_pdu(uint8_t * dst,const sdp_list_t * seq,uint8_t dtd)2977 static int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd)
2978 {
2979 	sdp_data_t *dataseq;
2980 	void **types, **values;
2981 	sdp_buf_t buf;
2982 	int i, seqlen = sdp_list_len(seq);
2983 
2984 	// Fill up the value and the dtd arrays
2985 	SDPDBG("");
2986 
2987 	memset(&buf, 0, sizeof(sdp_buf_t));
2988 	buf.data = malloc(256);
2989 	buf.buf_size = 256;
2990 
2991 	if (!buf.data)
2992 		return -ENOMEM;
2993 
2994 	SDPDBG("Seq length : %d\n", seqlen);
2995 
2996 	types = malloc(seqlen * sizeof(void *));
2997 	values = malloc(seqlen * sizeof(void *));
2998 	for (i = 0; i < seqlen; i++) {
2999 		void *data = seq->data;
3000 		types[i] = &dtd;
3001 		if (SDP_IS_UUID(dtd))
3002 			data = &((uuid_t *)data)->value;
3003 		values[i] = data;
3004 		seq = seq->next;
3005 	}
3006 
3007 	dataseq = sdp_seq_alloc(types, values, seqlen);
3008 	SDPDBG("Data Seq : 0x%p\n", seq);
3009 	seqlen = sdp_gen_pdu(&buf, dataseq);
3010 	SDPDBG("Copying : %d\n", buf.data_size);
3011 	memcpy(dst, buf.data, buf.data_size);
3012 
3013 	sdp_data_free(dataseq);
3014 
3015 	free(types);
3016 	free(values);
3017 	free(buf.data);
3018 	return seqlen;
3019 }
3020 
gen_searchseq_pdu(uint8_t * dst,const sdp_list_t * seq)3021 static int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq)
3022 {
3023 	uuid_t *uuid = (uuid_t *) seq->data;
3024 	return gen_dataseq_pdu(dst, seq, uuid->type);
3025 }
3026 
gen_attridseq_pdu(uint8_t * dst,const sdp_list_t * seq,uint8_t dataType)3027 static int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType)
3028 {
3029 	return gen_dataseq_pdu(dst, seq, dataType);
3030 }
3031 
3032 typedef struct {
3033 	uint8_t length;
3034 	unsigned char data[16];
3035 } __attribute__ ((packed)) sdp_cstate_t;
3036 
copy_cstate(uint8_t * pdata,int pdata_len,const sdp_cstate_t * cstate)3037 static int copy_cstate(uint8_t *pdata, int pdata_len, const sdp_cstate_t *cstate)
3038 {
3039 	if (cstate) {
3040 		uint8_t len = cstate->length;
3041 		if (len >= pdata_len) {
3042 			SDPERR("Continuation state size exceeds internal buffer");
3043 			len = pdata_len - 1;
3044 		}
3045 		*pdata++ = len;
3046 		memcpy(pdata, cstate->data, len);
3047 		return len + 1;
3048 	}
3049 	*pdata = 0;
3050 	return 1;
3051 }
3052 
3053 /*
3054  * This is a service search request.
3055  *
3056  * INPUT :
3057  *
3058  *   sdp_list_t *search
3059  *     Singly linked list containing elements of the search
3060  *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
3061  *     of the service to be searched
3062  *
3063  *   uint16_t max_rec_num
3064  *      A 16 bit integer which tells the service, the maximum
3065  *      entries that the client can handle in the response. The
3066  *      server is obliged not to return > max_rec_num entries
3067  *
3068  * OUTPUT :
3069  *
3070  *   int return value
3071  *     0:
3072  *       The request completed successfully. This does not
3073  *       mean the requested services were found
3074  *     -1:
3075  *       On any failure and sets errno
3076  *
3077  *   sdp_list_t **rsp_list
3078  *     This variable is set on a successful return if there are
3079  *     non-zero service handles. It is a singly linked list of
3080  *     service record handles (uint16_t)
3081  */
sdp_service_search_req(sdp_session_t * session,const sdp_list_t * search,uint16_t max_rec_num,sdp_list_t ** rsp)3082 int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search,
3083 			uint16_t max_rec_num, sdp_list_t **rsp)
3084 {
3085 	int status = 0;
3086 	uint32_t reqsize = 0, _reqsize;
3087 	uint32_t rspsize = 0, rsplen;
3088 	int seqlen = 0;
3089 	int scanned, total_rec_count, rec_count, pdata_len;
3090 	uint8_t *pdata, *_pdata;
3091 	uint8_t *reqbuf, *rspbuf;
3092 	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3093 	sdp_cstate_t *cstate = NULL;
3094 
3095 	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3096 	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3097 	if (!reqbuf || !rspbuf) {
3098 		errno = ENOMEM;
3099 		status = -1;
3100 		goto end;
3101 	}
3102 	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3103 	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
3104 	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3105 	reqsize = sizeof(sdp_pdu_hdr_t);
3106 
3107 	// add service class IDs for search
3108 	seqlen = gen_searchseq_pdu(pdata, search);
3109 
3110 	SDPDBG("Data seq added : %d\n", seqlen);
3111 
3112 	// set the length and increment the pointer
3113 	reqsize += seqlen;
3114 	pdata += seqlen;
3115 
3116 	// specify the maximum svc rec count that client expects
3117 	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
3118 	reqsize += sizeof(uint16_t);
3119 	pdata += sizeof(uint16_t);
3120 
3121 	_reqsize = reqsize;
3122 	_pdata   = pdata;
3123 	*rsp = NULL;
3124 
3125 	do {
3126 		// Add continuation state or NULL (first time)
3127 		reqsize = _reqsize + copy_cstate(_pdata,
3128 					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
3129 
3130 		// Set the request header's param length
3131 		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3132 
3133 		reqhdr->tid  = htons(sdp_gen_tid(session));
3134 		/*
3135 		 * Send the request, wait for response and if
3136 		 * no error, set the appropriate values and return
3137 		 */
3138 		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3139 		if (status < 0)
3140 			goto end;
3141 
3142 		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
3143 			SDPERR("Unexpected end of packet");
3144 			status = -1;
3145 			goto end;
3146 		}
3147 
3148 		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3149 		rsplen = ntohs(rsphdr->plen);
3150 
3151 		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3152 			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
3153 			status = -1;
3154 			goto end;
3155 		}
3156 		scanned = 0;
3157 		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3158 		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
3159 
3160 		if (pdata_len < sizeof(uint16_t) + sizeof(uint16_t)) {
3161 			SDPERR("Unexpected end of packet");
3162 			status = -1;
3163 			goto end;
3164 		}
3165 
3166 		// net service record match count
3167 		total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3168 		pdata += sizeof(uint16_t);
3169 		scanned += sizeof(uint16_t);
3170 		pdata_len -= sizeof(uint16_t);
3171 		rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3172 		pdata += sizeof(uint16_t);
3173 		scanned += sizeof(uint16_t);
3174 		pdata_len -= sizeof(uint16_t);
3175 
3176 		SDPDBG("Total svc count: %d\n", total_rec_count);
3177 		SDPDBG("Current svc count: %d\n", rec_count);
3178 		SDPDBG("ResponseLength: %d\n", rsplen);
3179 
3180 		if (!rec_count) {
3181 			status = -1;
3182 			goto end;
3183 		}
3184 		extract_record_handle_seq(pdata, pdata_len, rsp, rec_count, &scanned);
3185 		SDPDBG("BytesScanned : %d\n", scanned);
3186 
3187 		if (rsplen > scanned) {
3188 			uint8_t cstate_len;
3189 
3190 			if (rspsize < sizeof(sdp_pdu_hdr_t) + scanned + sizeof(uint8_t)) {
3191 				SDPERR("Unexpected end of packet: continuation state data missing");
3192 				status = -1;
3193 				goto end;
3194 			}
3195 
3196 			pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned;
3197 			cstate_len = *(uint8_t *) pdata;
3198 			if (cstate_len > 0) {
3199 				cstate = (sdp_cstate_t *)pdata;
3200 				SDPDBG("Cont state length: %d\n", cstate_len);
3201 			} else
3202 				cstate = NULL;
3203 		}
3204 	} while (cstate);
3205 
3206 end:
3207 	if (reqbuf)
3208 		free(reqbuf);
3209 	if (rspbuf)
3210 		free(rspbuf);
3211 
3212 	return status;
3213 }
3214 
3215 /*
3216  * This is a service attribute request.
3217  *
3218  * INPUT :
3219  *
3220  *   uint32_t handle
3221  *     The handle of the service for which the attribute(s) are
3222  *     requested
3223  *
3224  *   sdp_attrreq_type_t reqtype
3225  *     Attribute identifiers are 16 bit unsigned integers specified
3226  *     in one of 2 ways described below :
3227  *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3228  *        They are the actual attribute identifiers in ascending order
3229  *
3230  *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3231  *        The high-order 16bits is the start of range
3232  *        the low-order 16bits are the end of range
3233  *        0x0000 to 0xFFFF gets all attributes
3234  *
3235  *   sdp_list_t *attrid
3236  *     Singly linked list containing attribute identifiers desired.
3237  *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3238  *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3239  *
3240  * OUTPUT :
3241  *   return sdp_record_t *
3242  *     0:
3243  *       On any error and sets errno
3244  *     !0:
3245  *	 The service record
3246  */
sdp_service_attr_req(sdp_session_t * session,uint32_t handle,sdp_attrreq_type_t reqtype,const sdp_list_t * attrids)3247 sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle,
3248 			sdp_attrreq_type_t reqtype, const sdp_list_t *attrids)
3249 {
3250 	int status = 0;
3251 	uint32_t reqsize = 0, _reqsize;
3252 	uint32_t rspsize = 0, rsp_count;
3253 	int attr_list_len = 0;
3254 	int seqlen = 0, pdata_len;
3255 	uint8_t *pdata, *_pdata;
3256 	uint8_t *reqbuf, *rspbuf;
3257 	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3258 	sdp_cstate_t *cstate = NULL;
3259 	uint8_t cstate_len = 0;
3260 	sdp_buf_t rsp_concat_buf;
3261 	sdp_record_t *rec = 0;
3262 
3263 	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
3264 		errno = EINVAL;
3265 		return 0;
3266 	}
3267 
3268 	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3269 	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3270 	if (!reqbuf || !rspbuf) {
3271 		errno = ENOMEM;
3272 		status = -1;
3273 		goto end;
3274 	}
3275 	memset((char *) &rsp_concat_buf, 0, sizeof(sdp_buf_t));
3276 	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3277 	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
3278 
3279 	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3280 	reqsize = sizeof(sdp_pdu_hdr_t);
3281 
3282 	// add the service record handle
3283 	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
3284 	reqsize += sizeof(uint32_t);
3285 	pdata += sizeof(uint32_t);
3286 
3287 	// specify the response limit
3288 	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
3289 	reqsize += sizeof(uint16_t);
3290 	pdata += sizeof(uint16_t);
3291 
3292 	// get attr seq PDU form
3293 	seqlen = gen_attridseq_pdu(pdata, attrids,
3294 		reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3295 	if (seqlen == -1) {
3296 		errno = EINVAL;
3297 		status = -1;
3298 		goto end;
3299 	}
3300 	pdata += seqlen;
3301 	reqsize += seqlen;
3302 	SDPDBG("Attr list length : %d\n", seqlen);
3303 
3304 	// save before Continuation State
3305 	_pdata = pdata;
3306 	_reqsize = reqsize;
3307 
3308 	do {
3309 		// add NULL continuation state
3310 		reqsize = _reqsize + copy_cstate(_pdata,
3311 					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
3312 
3313 		// set the request header's param length
3314 		reqhdr->tid  = htons(sdp_gen_tid(session));
3315 		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3316 
3317 		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3318 		if (status < 0)
3319 			goto end;
3320 
3321 		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
3322 			SDPERR("Unexpected end of packet");
3323 			status = -1;
3324 			goto end;
3325 		}
3326 
3327 		rsp_count = 0;
3328 		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3329 		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3330 			SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id);
3331 			status = -1;
3332 			goto end;
3333 		}
3334 		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3335 		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
3336 
3337 		if (pdata_len < sizeof(uint16_t)) {
3338 			SDPERR("Unexpected end of packet");
3339 			status = -1;
3340 			goto end;
3341 		}
3342 
3343 		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3344 		attr_list_len += rsp_count;
3345 		pdata += sizeof(uint16_t);
3346 		pdata_len -= sizeof(uint16_t);
3347 
3348 		// if continuation state set need to re-issue request before parsing
3349 		if (pdata_len < rsp_count + sizeof(uint8_t)) {
3350 			SDPERR("Unexpected end of packet: continuation state data missing");
3351 			status = -1;
3352 			goto end;
3353 		}
3354 		cstate_len = *(uint8_t *) (pdata + rsp_count);
3355 
3356 		SDPDBG("Response id : %d\n", rsphdr->pdu_id);
3357 		SDPDBG("Attrlist byte count : %d\n", rsp_count);
3358 		SDPDBG("sdp_cstate_t length : %d\n", cstate_len);
3359 
3360 		/*
3361 		 * a split response: concatenate intermediate responses
3362 		 * and the last one (which has cstate_len == 0)
3363 		 */
3364 		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
3365 			uint8_t *targetPtr = NULL;
3366 
3367 			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
3368 
3369 			// build concatenated response buffer
3370 			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
3371 			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
3372 			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
3373 			memcpy(targetPtr, pdata, rsp_count);
3374 			rsp_concat_buf.data_size += rsp_count;
3375 		}
3376 	} while (cstate);
3377 
3378 	if (attr_list_len > 0) {
3379 		int scanned = 0;
3380 		if (rsp_concat_buf.data_size != 0) {
3381 			pdata = rsp_concat_buf.data;
3382 			pdata_len = rsp_concat_buf.data_size;
3383 		}
3384 		rec = sdp_extract_pdu_safe(pdata, pdata_len, &scanned);
3385 
3386 		if (!rec)
3387 			status = -1;
3388 	}
3389 
3390 end:
3391 	if (reqbuf)
3392 		free(reqbuf);
3393 	if (rsp_concat_buf.data)
3394 		free(rsp_concat_buf.data);
3395 	if (rspbuf)
3396 		free(rspbuf);
3397 	return rec;
3398 }
3399 
3400 /*
3401  * SDP transaction structure for asynchronous search
3402  */
3403 struct sdp_transaction {
3404 	sdp_callback_t *cb;	/* called when the transaction finishes */
3405 	void *udata;		/* client user data */
3406 	uint8_t *reqbuf;	/* pointer to request PDU */
3407 	sdp_buf_t rsp_concat_buf;
3408 	uint32_t reqsize;	/* without cstate */
3409 	int err;		/* ZERO if success or the errno if failed */
3410 };
3411 
3412 /*
3413  * Creates a new sdp session for asynchronous search
3414  * INPUT:
3415  *  int sk
3416  *     non-blocking L2CAP socket
3417  *
3418  * RETURN:
3419  *  sdp_session_t *
3420  *  NULL - On memory allocation failure
3421  */
sdp_create(int sk,uint32_t flags)3422 sdp_session_t *sdp_create(int sk, uint32_t flags)
3423 {
3424 	sdp_session_t *session;
3425 	struct sdp_transaction *t;
3426 
3427 	session = malloc(sizeof(sdp_session_t));
3428 	if (!session) {
3429 		errno = ENOMEM;
3430 		return NULL;
3431 	}
3432 	memset(session, 0, sizeof(*session));
3433 
3434 	session->flags = flags;
3435 	session->sock = sk;
3436 
3437 	t = malloc(sizeof(struct sdp_transaction));
3438 	if (!t) {
3439 		errno = ENOMEM;
3440 		free(session);
3441 		return NULL;
3442 	}
3443 	memset(t, 0, sizeof(*t));
3444 
3445 	session->priv = t;
3446 
3447 	return session;
3448 }
3449 
3450 /*
3451  * Sets the callback function/user data used to notify the application
3452  * that the asynchronous transaction finished. This function must be
3453  * called before request an asynchronous search.
3454  *
3455  * INPUT:
3456  *  sdp_session_t *session
3457  *	Current sdp session to be handled
3458  *  sdp_callback_t *cb
3459  *      callback to be called when the transaction finishes
3460  *  void *udata
3461  *      user data passed to callback
3462  * RETURN:
3463  * 	 0 - Success
3464  * 	-1 - Failure
3465  */
sdp_set_notify(sdp_session_t * session,sdp_callback_t * func,void * udata)3466 int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata)
3467 {
3468 	struct sdp_transaction *t;
3469 
3470 	if (!session || !session->priv)
3471 		return -1;
3472 
3473 	t = session->priv;
3474 	t->cb = func;
3475 	t->udata = udata;
3476 
3477 	return 0;
3478 }
3479 
3480 /*
3481  * This function starts an asynchronous service search request.
3482  * The incomming and outgoing data are stored in the transaction structure
3483  * buffers. When there is incomming data the sdp_process function must be
3484  * called to get the data and handle the continuation state.
3485  *
3486  * INPUT :
3487  *  sdp_session_t *session
3488  *     Current sdp session to be handled
3489  *
3490  *   sdp_list_t *search
3491  *     Singly linked list containing elements of the search
3492  *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
3493  *     of the service to be searched
3494  *
3495  *   uint16_t max_rec_num
3496  *      A 16 bit integer which tells the service, the maximum
3497  *      entries that the client can handle in the response. The
3498  *      server is obliged not to return > max_rec_num entries
3499  *
3500  * OUTPUT :
3501  *
3502  *   int return value
3503  * 	0  - if the request has been sent properly
3504  * 	-1 - On any failure and sets errno
3505  */
3506 
sdp_service_search_async(sdp_session_t * session,const sdp_list_t * search,uint16_t max_rec_num)3507 int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num)
3508 {
3509 	struct sdp_transaction *t;
3510 	sdp_pdu_hdr_t *reqhdr;
3511 	uint8_t *pdata;
3512 	int cstate_len, seqlen = 0;
3513 
3514 	if (!session || !session->priv)
3515 		return -1;
3516 
3517 	t = session->priv;
3518 
3519 	/* check if the buffer is already allocated */
3520 	if (t->rsp_concat_buf.data)
3521 		free(t->rsp_concat_buf.data);
3522 	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
3523 
3524 	if (!t->reqbuf) {
3525 		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3526 		if (!t->reqbuf) {
3527 			t->err = ENOMEM;
3528 			goto end;
3529 		}
3530 	}
3531 	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3532 
3533 	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3534 	reqhdr->tid = htons(sdp_gen_tid(session));
3535 	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
3536 
3537 	// generate PDU
3538 	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3539 	t->reqsize = sizeof(sdp_pdu_hdr_t);
3540 
3541 	// add service class IDs for search
3542 	seqlen = gen_searchseq_pdu(pdata, search);
3543 
3544 	SDPDBG("Data seq added : %d\n", seqlen);
3545 
3546 	// now set the length and increment the pointer
3547 	t->reqsize += seqlen;
3548 	pdata += seqlen;
3549 
3550 	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
3551 	t->reqsize += sizeof(uint16_t);
3552 	pdata += sizeof(uint16_t);
3553 
3554 	// set the request header's param length
3555 	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
3556 	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3557 
3558 	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3559 		SDPERR("Error sendind data:%s", strerror(errno));
3560 		t->err = errno;
3561 		goto end;
3562 	}
3563 
3564 	return 0;
3565 end:
3566 
3567 	if (t->reqbuf) {
3568 		free(t->reqbuf);
3569 		t->reqbuf = NULL;
3570 	}
3571 
3572 	return -1;
3573 }
3574 
3575 /*
3576  * This function starts an asynchronous service attribute request.
3577  * The incomming and outgoing data are stored in the transaction structure
3578  * buffers. When there is incomming data the sdp_process function must be
3579  * called to get the data and handle the continuation state.
3580  *
3581  * INPUT :
3582  *  sdp_session_t *session
3583  *	Current sdp session to be handled
3584  *
3585  *   uint32_t handle
3586  *     The handle of the service for which the attribute(s) are
3587  *     requested
3588  *
3589  *   sdp_attrreq_type_t reqtype
3590  *     Attribute identifiers are 16 bit unsigned integers specified
3591  *     in one of 2 ways described below :
3592  *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3593  *        They are the actual attribute identifiers in ascending order
3594  *
3595  *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3596  *        The high-order 16bits is the start of range
3597  *        the low-order 16bits are the end of range
3598  *        0x0000 to 0xFFFF gets all attributes
3599  *
3600  *   sdp_list_t *attrid_list
3601  *     Singly linked list containing attribute identifiers desired.
3602  *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3603  *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3604  *
3605  * OUTPUT :
3606  *   int return value
3607  * 	 0 - if the request has been sent properly
3608  * 	-1 - On any failure and sets errno
3609  */
3610 
sdp_service_attr_async(sdp_session_t * session,uint32_t handle,sdp_attrreq_type_t reqtype,const sdp_list_t * attrid_list)3611 int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
3612 {
3613 	struct sdp_transaction *t;
3614 	sdp_pdu_hdr_t *reqhdr;
3615 	uint8_t *pdata;
3616 	int cstate_len, seqlen = 0;
3617 
3618 	if (!session || !session->priv)
3619 		return -1;
3620 
3621 	t = session->priv;
3622 
3623 	/* check if the buffer is already allocated */
3624 	if (t->rsp_concat_buf.data)
3625 		free(t->rsp_concat_buf.data);
3626 	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
3627 
3628 	if (!t->reqbuf) {
3629 		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3630 		if (!t->reqbuf) {
3631 			t->err = ENOMEM;
3632 			goto end;
3633 		}
3634 	}
3635 	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3636 
3637 	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3638 	reqhdr->tid = htons(sdp_gen_tid(session));
3639 	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
3640 
3641 	// generate PDU
3642 	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3643 	t->reqsize = sizeof(sdp_pdu_hdr_t);
3644 
3645 	// add the service record handle
3646 	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
3647 	t->reqsize += sizeof(uint32_t);
3648 	pdata += sizeof(uint32_t);
3649 
3650 	// specify the response limit
3651 	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
3652 	t->reqsize += sizeof(uint16_t);
3653 	pdata += sizeof(uint16_t);
3654 
3655 	// get attr seq PDU form
3656 	seqlen = gen_attridseq_pdu(pdata, attrid_list,
3657 			reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3658 	if (seqlen == -1) {
3659 		t->err = EINVAL;
3660 		goto end;
3661 	}
3662 
3663 	// now set the length and increment the pointer
3664 	t->reqsize += seqlen;
3665 	pdata += seqlen;
3666 	SDPDBG("Attr list length : %d\n", seqlen);
3667 
3668 	// set the request header's param length
3669 	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
3670 	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3671 
3672 	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3673 		SDPERR("Error sendind data:%s", strerror(errno));
3674 		t->err = errno;
3675 		goto end;
3676 	}
3677 
3678 	return 0;
3679 end:
3680 
3681 	if (t->reqbuf) {
3682 		free(t->reqbuf);
3683 		t->reqbuf = NULL;
3684 	}
3685 
3686 	return -1;
3687 }
3688 
3689 /*
3690  * This function starts an asynchronous service search attributes.
3691  * It is a service search request combined with attribute request. The incomming
3692  * and outgoing data are stored in the transaction structure buffers. When there
3693  * is incomming data the sdp_process function must be called to get the data
3694  * and handle the continuation state.
3695  *
3696  * INPUT:
3697  *  sdp_session_t *session
3698  *	Current sdp session to be handled
3699  *
3700  *   sdp_list_t *search
3701  *     Singly linked list containing elements of the search
3702  *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
3703  *     of the service to be searched
3704  *
3705  *   AttributeSpecification attrSpec
3706  *     Attribute identifiers are 16 bit unsigned integers specified
3707  *     in one of 2 ways described below :
3708  *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3709  *        They are the actual attribute identifiers in ascending order
3710  *
3711  *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3712  *        The high-order 16bits is the start of range
3713  *        the low-order 16bits are the end of range
3714  *        0x0000 to 0xFFFF gets all attributes
3715  *
3716  *   sdp_list_t *attrid_list
3717  *     Singly linked list containing attribute identifiers desired.
3718  *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3719  *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3720  *
3721 
3722  * RETURN:
3723  * 	 0 - if the request has been sent properly
3724  * 	-1 - On any failure
3725  */
sdp_service_search_attr_async(sdp_session_t * session,const sdp_list_t * search,sdp_attrreq_type_t reqtype,const sdp_list_t * attrid_list)3726 int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
3727 {
3728 	struct sdp_transaction *t;
3729 	sdp_pdu_hdr_t *reqhdr;
3730 	uint8_t *pdata;
3731 	int cstate_len, seqlen = 0;
3732 
3733 	if (!session || !session->priv)
3734 		return -1;
3735 
3736 	t = session->priv;
3737 
3738 	/* check if the buffer is already allocated */
3739 	if (t->rsp_concat_buf.data)
3740 		free(t->rsp_concat_buf.data);
3741 	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
3742 
3743 	if (!t->reqbuf) {
3744 		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3745 		if (!t->reqbuf) {
3746 			t->err = ENOMEM;
3747 			goto end;
3748 		}
3749 	}
3750 	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3751 
3752 	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3753 	reqhdr->tid = htons(sdp_gen_tid(session));
3754 	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
3755 
3756 	// generate PDU
3757 	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3758 	t->reqsize = sizeof(sdp_pdu_hdr_t);
3759 
3760 	// add service class IDs for search
3761 	seqlen = gen_searchseq_pdu(pdata, search);
3762 
3763 	SDPDBG("Data seq added : %d\n", seqlen);
3764 
3765 	// now set the length and increment the pointer
3766 	t->reqsize += seqlen;
3767 	pdata += seqlen;
3768 
3769 	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
3770 	t->reqsize += sizeof(uint16_t);
3771 	pdata += sizeof(uint16_t);
3772 
3773 	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
3774 
3775 	// get attr seq PDU form
3776 	seqlen = gen_attridseq_pdu(pdata, attrid_list,
3777 			reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
3778 	if (seqlen == -1) {
3779 		t->err = EINVAL;
3780 		goto end;
3781 	}
3782 
3783 	pdata += seqlen;
3784 	SDPDBG("Attr list length : %d\n", seqlen);
3785 	t->reqsize += seqlen;
3786 
3787 	// set the request header's param length
3788 	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
3789 	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3790 
3791 	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3792 		SDPERR("Error sendind data:%s", strerror(errno));
3793 		t->err = errno;
3794 		goto end;
3795 	}
3796 
3797 	return 0;
3798 end:
3799 
3800 	if (t->reqbuf) {
3801 		free(t->reqbuf);
3802 		t->reqbuf = NULL;
3803 	}
3804 
3805 	return -1;
3806 }
3807 
3808 /*
3809  * Function used to get the error reason after sdp_callback_t function has been called
3810  * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1.
3811  * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly
3812  * is not safe because multiple transactions can be triggered.
3813  * This function must be used with asynchronous sdp functions only.
3814  *
3815  * INPUT:
3816  *  sdp_session_t *session
3817  *	Current sdp session to be handled
3818  * RETURN:
3819  * 	 0 = No error in the current transaction
3820  * 	-1 - if the session is invalid
3821  * 	positive value - the errno value
3822  *
3823  */
sdp_get_error(sdp_session_t * session)3824 int sdp_get_error(sdp_session_t *session)
3825 {
3826 	struct sdp_transaction *t;
3827 
3828 	if (!session || !session->priv) {
3829 		SDPERR("Invalid session");
3830 		return -1;
3831 	}
3832 
3833 	t = session->priv;
3834 
3835 	return t->err;
3836 }
3837 
3838 /*
3839  * Receive the incomming SDP PDU. This function must be called when there is data
3840  * available to be read. On continuation state, the original request (with a new
3841  * transaction ID) and the continuation state data will be appended in the initial PDU.
3842  * If an error happens or the transaction finishes the callback function will be called.
3843  *
3844  * INPUT:
3845  *  sdp_session_t *session
3846  *	Current sdp session to be handled
3847  * RETURN:
3848  * 	0  - if the transaction is on continuation state
3849  * 	-1 - On any failure or the transaction finished
3850  */
sdp_process(sdp_session_t * session)3851 int sdp_process(sdp_session_t *session)
3852 {
3853 	struct sdp_transaction *t;
3854 	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3855 	sdp_cstate_t *pcstate;
3856 	uint8_t *pdata, *rspbuf, *targetPtr;
3857 	int rsp_count, err = -1;
3858 	size_t size = 0;
3859 	int n, plen;
3860 	uint16_t status = 0xffff;
3861 	uint8_t pdu_id = 0x00;
3862 
3863 	if (!session || !session->priv) {
3864 		SDPERR("Invalid session");
3865 		return -1;
3866 	}
3867 
3868 	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3869 	if (!rspbuf) {
3870 		SDPERR("Response buffer alloc failure:%s (%d)",
3871 				strerror(errno), errno);
3872 		return -1;
3873 	}
3874 
3875 	memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE);
3876 
3877 	t = session->priv;
3878 	reqhdr = (sdp_pdu_hdr_t *)t->reqbuf;
3879 	rsphdr = (sdp_pdu_hdr_t *)rspbuf;
3880 
3881 	pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3882 
3883 	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
3884 	if (n < 0) {
3885 		SDPERR("Read response:%s (%d)", strerror(errno), errno);
3886 		t->err = errno;
3887 		goto end;
3888 	}
3889 
3890 	if (n == 0 || reqhdr->tid != rsphdr->tid ||
3891 		(n != (ntohs(rsphdr->plen) + sizeof(sdp_pdu_hdr_t)))) {
3892 		t->err = EPROTO;
3893 		SDPERR("Protocol error.");
3894 		goto end;
3895 	}
3896 
3897 	pdu_id = rsphdr->pdu_id;
3898 	switch (rsphdr->pdu_id) {
3899 	uint8_t *ssr_pdata;
3900 	uint16_t tsrc, csrc;
3901 	case SDP_SVC_SEARCH_RSP:
3902 		/*
3903 		 * TSRC: Total Service Record Count (2 bytes)
3904 		 * CSRC: Current Service Record Count (2 bytes)
3905 		 */
3906 		ssr_pdata = pdata;
3907 		tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));
3908 		ssr_pdata += sizeof(uint16_t);
3909 		csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));
3910 
3911 		/* csrc should never be larger than tsrc */
3912 		if (csrc > tsrc) {
3913 			t->err = EPROTO;
3914 			SDPERR("Protocol error: wrong current service record count value.");
3915 			goto end;
3916 		}
3917 
3918 		SDPDBG("Total svc count: %d\n", tsrc);
3919 		SDPDBG("Current svc count: %d\n", csrc);
3920 
3921 		/* parameter length without continuation state */
3922 		plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
3923 
3924 		if (t->rsp_concat_buf.data_size == 0) {
3925 			/* first fragment */
3926 			rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
3927 		} else {
3928 			/* point to the first csrc */
3929 			uint16_t *pcsrc = (uint16_t *) (t->rsp_concat_buf.data + 2);
3930 
3931 			/* FIXME: update the interface later. csrc doesn't need be passed to clients */
3932 
3933 			pdata += sizeof(uint16_t); /* point to csrc */
3934 
3935 			/* the first csrc contains the sum of partial csrc responses */
3936 			*pcsrc += bt_get_unaligned((uint16_t *) pdata);
3937 
3938 			pdata += sizeof(uint16_t); /* point to the first handle */
3939 			rsp_count = csrc * 4;
3940 		}
3941 		status = 0x0000;
3942 		break;
3943 	case SDP_SVC_ATTR_RSP:
3944 	case SDP_SVC_SEARCH_ATTR_RSP:
3945 		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3946 		SDPDBG("Attrlist byte count : %d\n", rsp_count);
3947 
3948 		/*
3949 		 * Number of bytes in the AttributeLists parameter(without
3950 		 * continuation state) + AttributeListsByteCount field size.
3951 		 */
3952 		plen = sizeof(uint16_t) + rsp_count;
3953 
3954 		pdata += sizeof(uint16_t); // points to attribute list
3955 		status = 0x0000;
3956 		break;
3957 	case SDP_ERROR_RSP:
3958 		status = ntohs(bt_get_unaligned((uint16_t *) pdata));
3959 		size = ntohs(rsphdr->plen);
3960 
3961 		/* error code + error info */
3962 		plen = size;
3963 		goto end;
3964 	default:
3965 		t->err = EPROTO;
3966 		SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id);
3967 		goto end;
3968 	}
3969 
3970 	pcstate = (sdp_cstate_t *) (pdata + rsp_count);
3971 
3972 	SDPDBG("Cstate length : %d\n", pcstate->length);
3973 
3974 	/*
3975 	 * Check out of bound. Continuation state must have at least
3976 	 * 1 byte: ZERO to indicate that it is not a partial response.
3977 	 */
3978 	if ((n - sizeof(sdp_pdu_hdr_t))  != (plen + pcstate->length + 1)) {
3979 		t->err = EPROTO;
3980 		SDPERR("Protocol error: wrong PDU size.");
3981 		status = 0xffff;
3982 		goto end;
3983 	}
3984 
3985 	/*
3986 	 * This is a split response, need to concatenate intermediate
3987 	 * responses and the last one which will have cstate length == 0
3988 	 */
3989 	t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count);
3990 	targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size;
3991 	t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count;
3992 	memcpy(targetPtr, pdata, rsp_count);
3993 	t->rsp_concat_buf.data_size += rsp_count;
3994 
3995 	if (pcstate->length > 0) {
3996 		int reqsize, cstate_len;
3997 
3998 		reqhdr->tid = htons(sdp_gen_tid(session));
3999 
4000 		// add continuation state
4001 		cstate_len = copy_cstate(t->reqbuf + t->reqsize,
4002 				SDP_REQ_BUFFER_SIZE - t->reqsize, pcstate);
4003 
4004 		reqsize = t->reqsize + cstate_len;
4005 
4006 		// set the request header's param length
4007 		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
4008 
4009 		if (sdp_send_req(session, t->reqbuf, reqsize) < 0) {
4010 			SDPERR("Error sendind data:%s(%d)", strerror(errno), errno);
4011 			status = 0xffff;
4012 			t->err = errno;
4013 			goto end;
4014 		}
4015 		err = 0;
4016 	}
4017 
4018 end:
4019 	if (err) {
4020 		if (t->rsp_concat_buf.data_size != 0) {
4021 			pdata = t->rsp_concat_buf.data;
4022 			size = t->rsp_concat_buf.data_size;
4023 		}
4024 		if (t->cb)
4025 			t->cb(pdu_id, status, pdata, size, t->udata);
4026 	}
4027 
4028 	if (rspbuf)
4029 		free(rspbuf);
4030 
4031 	return err;
4032 }
4033 
4034 /*
4035  * This is a service search request combined with the service
4036  * attribute request. First a service class match is done and
4037  * for matching service, requested attributes are extracted
4038  *
4039  * INPUT :
4040  *
4041  *   sdp_list_t *search
4042  *     Singly linked list containing elements of the search
4043  *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
4044  *     of the service to be searched
4045  *
4046  *   AttributeSpecification attrSpec
4047  *     Attribute identifiers are 16 bit unsigned integers specified
4048  *     in one of 2 ways described below :
4049  *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
4050  *        They are the actual attribute identifiers in ascending order
4051  *
4052  *     SDP_ATTR_REQ_RANGE - 32bit identifier range
4053  *        The high-order 16bits is the start of range
4054  *        the low-order 16bits are the end of range
4055  *        0x0000 to 0xFFFF gets all attributes
4056  *
4057  *   sdp_list_t *attrids
4058  *     Singly linked list containing attribute identifiers desired.
4059  *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
4060  *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
4061  *
4062  * OUTPUT :
4063  *   int return value
4064  *     0:
4065  *       The request completed successfully. This does not
4066  *       mean the requested services were found
4067  *     -1:
4068  *       On any error and sets errno
4069  *
4070  *   sdp_list_t **rsp
4071  *     This variable is set on a successful return to point to
4072  *     service(s) found. Each element of this list is of type
4073  *     sdp_record_t* (of the services which matched the search list)
4074  */
sdp_service_search_attr_req(sdp_session_t * session,const sdp_list_t * search,sdp_attrreq_type_t reqtype,const sdp_list_t * attrids,sdp_list_t ** rsp)4075 int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrids, sdp_list_t **rsp)
4076 {
4077 	int status = 0;
4078 	uint32_t reqsize = 0, _reqsize;
4079 	uint32_t rspsize = 0;
4080 	int seqlen = 0, attr_list_len = 0;
4081 	int rsp_count = 0, cstate_len = 0, pdata_len;
4082 	uint8_t *pdata, *_pdata;
4083 	uint8_t *reqbuf, *rspbuf;
4084 	sdp_pdu_hdr_t *reqhdr, *rsphdr;
4085 	uint8_t dataType;
4086 	sdp_list_t *rec_list = NULL;
4087 	sdp_buf_t rsp_concat_buf;
4088 	sdp_cstate_t *cstate = NULL;
4089 
4090 	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
4091 		errno = EINVAL;
4092 		return -1;
4093 	}
4094 	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
4095 	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
4096 	if (!reqbuf || !rspbuf) {
4097 		errno = ENOMEM;
4098 		status = -1;
4099 		goto end;
4100 	}
4101 
4102 	memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t));
4103 	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
4104 	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
4105 
4106 	// generate PDU
4107 	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
4108 	reqsize = sizeof(sdp_pdu_hdr_t);
4109 
4110 	// add service class IDs for search
4111 	seqlen = gen_searchseq_pdu(pdata, search);
4112 
4113 	SDPDBG("Data seq added : %d\n", seqlen);
4114 
4115 	// now set the length and increment the pointer
4116 	reqsize += seqlen;
4117 	pdata += seqlen;
4118 
4119 	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
4120 	reqsize += sizeof(uint16_t);
4121 	pdata += sizeof(uint16_t);
4122 
4123 	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
4124 
4125 	// get attr seq PDU form
4126 	seqlen = gen_attridseq_pdu(pdata, attrids,
4127 		reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
4128 	if (seqlen == -1) {
4129 		status = EINVAL;
4130 		goto end;
4131 	}
4132 	pdata += seqlen;
4133 	SDPDBG("Attr list length : %d\n", seqlen);
4134 	reqsize += seqlen;
4135 	*rsp = 0;
4136 
4137 	// save before Continuation State
4138 	_pdata = pdata;
4139 	_reqsize = reqsize;
4140 
4141 	do {
4142 		reqhdr->tid = htons(sdp_gen_tid(session));
4143 
4144 		// add continuation state (can be null)
4145 		reqsize = _reqsize + copy_cstate(_pdata,
4146 					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
4147 
4148 		// set the request header's param length
4149 		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
4150 		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
4151 		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
4152 		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
4153 			SDPERR("Unexpected end of packet");
4154 			status = -1;
4155 			goto end;
4156 		}
4157 
4158 		if (status < 0) {
4159 			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
4160 			goto end;
4161 		}
4162 
4163 		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
4164 			status = -1;
4165 			goto end;
4166 		}
4167 
4168 		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
4169 		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
4170 
4171 		if (pdata_len < sizeof(uint16_t)) {
4172 			SDPERR("Unexpected end of packet");
4173 			status = -1;
4174 			goto end;
4175 		}
4176 
4177 		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
4178 		attr_list_len += rsp_count;
4179 		pdata += sizeof(uint16_t);	// pdata points to attribute list
4180 		pdata_len -= sizeof(uint16_t);
4181 
4182 		if (pdata_len < rsp_count + sizeof(uint8_t)) {
4183 			SDPERR("Unexpected end of packet: continuation state data missing");
4184 			status = -1;
4185 			goto end;
4186 		}
4187 
4188 		cstate_len = *(uint8_t *) (pdata + rsp_count);
4189 
4190 		SDPDBG("Attrlist byte count : %d\n", attr_list_len);
4191 		SDPDBG("Response byte count : %d\n", rsp_count);
4192 		SDPDBG("Cstate length : %d\n", cstate_len);
4193 		/*
4194 		 * This is a split response, need to concatenate intermediate
4195 		 * responses and the last one which will have cstate_len == 0
4196 		 */
4197 		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
4198 			uint8_t *targetPtr = NULL;
4199 
4200 			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
4201 
4202 			// build concatenated response buffer
4203 			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
4204 			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
4205 			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
4206 			memcpy(targetPtr, pdata, rsp_count);
4207 			rsp_concat_buf.data_size += rsp_count;
4208 		}
4209 	} while (cstate);
4210 
4211 	if (attr_list_len > 0) {
4212 		int scanned = 0;
4213 
4214 		if (rsp_concat_buf.data_size != 0) {
4215 			pdata = rsp_concat_buf.data;
4216 			pdata_len = rsp_concat_buf.data_size;
4217 		}
4218 
4219 		/*
4220 		 * Response is a sequence of sequence(s) for one or
4221 		 * more data element sequence(s) representing services
4222 		 * for which attributes are returned
4223 		 */
4224 		scanned = sdp_extract_seqtype_safe(pdata, pdata_len, &dataType, &seqlen);
4225 
4226 		SDPDBG("Bytes scanned : %d\n", scanned);
4227 		SDPDBG("Seq length : %d\n", seqlen);
4228 
4229 		if (scanned && seqlen) {
4230 			pdata += scanned;
4231 			pdata_len -= scanned;
4232 			do {
4233 				int recsize = 0;
4234 				sdp_record_t *rec = sdp_extract_pdu_safe(pdata, pdata_len, &recsize);
4235 				if (rec == NULL) {
4236 					SDPERR("SVC REC is null\n");
4237 					status = -1;
4238 					goto end;
4239 				}
4240 				if (!recsize) {
4241 					sdp_record_free(rec);
4242 					break;
4243 				}
4244 				scanned += recsize;
4245 				pdata += recsize;
4246 				pdata_len -= recsize;
4247 
4248 				SDPDBG("Loc seq length : %d\n", recsize);
4249 				SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle);
4250 				SDPDBG("Bytes scanned : %d\n", scanned);
4251 				SDPDBG("Attrlist byte count : %d\n", attr_list_len);
4252 				rec_list = sdp_list_append(rec_list, rec);
4253 			} while (scanned < attr_list_len && pdata_len > 0);
4254 
4255 			SDPDBG("Successful scan of service attr lists\n");
4256 			*rsp = rec_list;
4257 		}
4258 	}
4259   end:
4260 	if (rsp_concat_buf.data)
4261 		free(rsp_concat_buf.data);
4262 	if (reqbuf)
4263 		free(reqbuf);
4264 	if (rspbuf)
4265 		free(rspbuf);
4266 	return status;
4267 }
4268 
4269 /*
4270  * Find devices in the piconet.
4271  */
sdp_general_inquiry(inquiry_info * ii,int num_dev,int duration,uint8_t * found)4272 int sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found)
4273 {
4274 	int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0);
4275 	if (n < 0) {
4276 		SDPERR("Inquiry failed:%s", strerror(errno));
4277 		return -1;
4278 	}
4279 	*found = n;
4280 	return 0;
4281 }
4282 
sdp_close(sdp_session_t * session)4283 int sdp_close(sdp_session_t *session)
4284 {
4285 	struct sdp_transaction *t;
4286 	int ret;
4287 
4288 	if (!session)
4289 		return -1;
4290 
4291 	ret = close(session->sock);
4292 
4293 	t = session->priv;
4294 
4295 	if (t) {
4296 		if (t->reqbuf)
4297 			free(t->reqbuf);
4298 
4299 		if (t->rsp_concat_buf.data)
4300 			free(t->rsp_concat_buf.data);
4301 
4302 		free(t);
4303 	}
4304 	free(session);
4305 	return ret;
4306 }
4307 
sdp_is_local(const bdaddr_t * device)4308 static inline int sdp_is_local(const bdaddr_t *device)
4309 {
4310 	return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0;
4311 }
4312 
sdp_connect_local(sdp_session_t * session)4313 static int sdp_connect_local(sdp_session_t *session)
4314 {
4315 	struct sockaddr_un sa;
4316 
4317 	session->sock = socket(PF_UNIX, SOCK_STREAM, 0);
4318 	if (session->sock < 0)
4319 		return -1;
4320 	session->local = 1;
4321 
4322 	sa.sun_family = AF_UNIX;
4323 	strcpy(sa.sun_path, SDP_UNIX_PATH);
4324 
4325 	return connect(session->sock, (struct sockaddr *)&sa, sizeof(sa));
4326 }
4327 
sdp_connect_l2cap(const bdaddr_t * src,const bdaddr_t * dst,sdp_session_t * session)4328 static int sdp_connect_l2cap(const bdaddr_t *src,
4329 			     const bdaddr_t *dst, sdp_session_t *session)
4330 {
4331 	uint32_t flags = session->flags;
4332 	struct sockaddr_l2 sa;
4333 	int sk;
4334 
4335 	session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
4336 	if (session->sock < 0)
4337 		return -1;
4338 	session->local = 0;
4339 
4340 	sk = session->sock;
4341 
4342 	if (flags & SDP_NON_BLOCKING) {
4343 		long arg = fcntl(sk, F_GETFL, 0);
4344 		fcntl(sk, F_SETFL, arg | O_NONBLOCK);
4345 	}
4346 
4347 	sa.l2_family = AF_BLUETOOTH;
4348 	sa.l2_psm = 0;
4349 
4350 	if (bacmp(src, BDADDR_ANY)) {
4351 		sa.l2_bdaddr = *src;
4352 		if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0)
4353 			return -1;
4354 	}
4355 
4356 	if (flags & SDP_WAIT_ON_CLOSE) {
4357 		struct linger l = { .l_onoff = 1, .l_linger = 1 };
4358 		setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
4359 	}
4360 
4361 	sa.l2_psm = htobs(SDP_PSM);
4362 	sa.l2_bdaddr = *dst;
4363 
4364 	do {
4365 		int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa));
4366 		if (!ret)
4367 			return 0;
4368 		if (ret < 0 && (flags & SDP_NON_BLOCKING) &&
4369 		    (errno == EAGAIN || errno == EINPROGRESS))
4370 			return 0;
4371 	} while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY));
4372 
4373 	return -1;
4374 }
4375 
sdp_connect(const bdaddr_t * src,const bdaddr_t * dst,uint32_t flags)4376 sdp_session_t *sdp_connect(const bdaddr_t *src,
4377 			   const bdaddr_t *dst, uint32_t flags)
4378 {
4379 	sdp_session_t *session;
4380 	int err;
4381 
4382 	if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) {
4383 		errno = EINVAL;
4384 		return NULL;
4385 	}
4386 
4387 	session = sdp_create(-1, flags);
4388 	if (!session)
4389 		return NULL;
4390 
4391 	if (sdp_is_local(dst)) {
4392 		if (sdp_connect_local(session) < 0)
4393 			goto fail;
4394 	} else {
4395 		if (sdp_connect_l2cap(src, dst, session) < 0)
4396 			goto fail;
4397 	}
4398 
4399 	return session;
4400 
4401 fail:
4402 	err = errno;
4403 	if (session->sock >= 0)
4404 		close(session->sock);
4405 	if (session->priv)
4406 		free(session->priv);
4407 	free(session);
4408 	errno = err;
4409 
4410 	return NULL;
4411 }
4412 
sdp_get_socket(const sdp_session_t * session)4413 int sdp_get_socket(const sdp_session_t *session)
4414 {
4415 	return session->sock;
4416 }
4417 
sdp_gen_tid(sdp_session_t * session)4418 uint16_t sdp_gen_tid(sdp_session_t *session)
4419 {
4420 	return session->tid++;
4421 }
4422