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