/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2001-2002  Nokia Corporation
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
 *  Copyright (C) 2002-2003  Stephen Crane <steve.crane@rococosoft.com>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <syslog.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>

#include "bluetooth.h"
#include "hci.h"
#include "hci_lib.h"
#include "l2cap.h"
#include "sdp.h"
#include "sdp_lib.h"

#define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg)
#define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg)

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

#ifdef SDP_DEBUG
#define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg)
#else
#define SDPDBG(fmt...)
#endif

#if __BYTE_ORDER == __BIG_ENDIAN
#define ntoh64(x) (x)
static inline void ntoh128(uint128_t *src, uint128_t *dst)
{
	int i;
	for (i = 0; i < 16; i++)
		dst->data[i] = src->data[i];
}
#else
static inline uint64_t ntoh64(uint64_t n)
{
	uint64_t h;
	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
	h = ntohl(n >> 32);
	h |= tmp << 32;
	return h;
}
static inline void ntoh128(uint128_t *src, uint128_t *dst)
{
	int i;
	for (i = 0; i < 16; i++)
		dst->data[15 - i] = src->data[i];
}
#endif

#define hton64(x)     ntoh64(x)
#define hton128(x, y) ntoh128(x, y)

#define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB"

static uint128_t bluetooth_base_uuid = {
	.data = {	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
};

#define SDP_MAX_ATTR_LEN 65535

static sdp_data_t *sdp_copy_seq(sdp_data_t *data);
static int sdp_attr_add_new_with_length(sdp_record_t *rec,
	uint16_t attr, uint8_t dtd, const void *value, uint32_t len);
static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d);

/* Message structure. */
struct tupla {
	int index;
	char *str;
};

static struct tupla Protocol[] = {
	{ SDP_UUID,		"SDP"		},
	{ UDP_UUID,		"UDP"		},
	{ RFCOMM_UUID,		"RFCOMM"	},
	{ TCP_UUID,		"TCP"		},
	{ TCS_BIN_UUID,		"TCS-BIN"	},
	{ TCS_AT_UUID,		"TCS-AT"	},
	{ OBEX_UUID,		"OBEX"		},
	{ IP_UUID,		"IP"		},
	{ FTP_UUID,		"FTP"		},
	{ HTTP_UUID,		"HTTP"		},
	{ WSP_UUID,		"WSP"		},
	{ BNEP_UUID,		"BNEP"		},
	{ UPNP_UUID,		"UPNP"		},
	{ HIDP_UUID,		"HIDP"		},
	{ HCRP_CTRL_UUID,	"HCRP-Ctrl"	},
	{ HCRP_DATA_UUID,	"HCRP-Data"	},
	{ HCRP_NOTE_UUID,	"HCRP-Notify"	},
	{ AVCTP_UUID,		"AVCTP"		},
	{ AVDTP_UUID,		"AVDTP"		},
	{ CMTP_UUID,		"CMTP"		},
	{ UDI_UUID,		"UDI"		},
	{ MCAP_CTRL_UUID,	"MCAP-Ctrl"	},
	{ MCAP_DATA_UUID,	"MCAP-Data"	},
	{ L2CAP_UUID,		"L2CAP"		},
	{ 0 }
};

static struct tupla ServiceClass[] = {
	{ SDP_SERVER_SVCLASS_ID,		"SDP Server"			},
	{ BROWSE_GRP_DESC_SVCLASS_ID,		"Browse Group Descriptor"	},
	{ PUBLIC_BROWSE_GROUP,			"Public Browse Group"		},
	{ SERIAL_PORT_SVCLASS_ID,		"Serial Port"			},
	{ LAN_ACCESS_SVCLASS_ID,		"LAN Access Using PPP"		},
	{ DIALUP_NET_SVCLASS_ID,		"Dialup Networking"		},
	{ IRMC_SYNC_SVCLASS_ID,			"IrMC Sync"			},
	{ OBEX_OBJPUSH_SVCLASS_ID,		"OBEX Object Push"		},
	{ OBEX_FILETRANS_SVCLASS_ID,		"OBEX File Transfer"		},
	{ IRMC_SYNC_CMD_SVCLASS_ID,		"IrMC Sync Command"		},
	{ HEADSET_SVCLASS_ID,			"Headset"			},
	{ CORDLESS_TELEPHONY_SVCLASS_ID,	"Cordless Telephony"		},
	{ AUDIO_SOURCE_SVCLASS_ID,		"Audio Source"			},
	{ AUDIO_SINK_SVCLASS_ID,		"Audio Sink"			},
	{ AV_REMOTE_TARGET_SVCLASS_ID,		"AV Remote Target"		},
	{ ADVANCED_AUDIO_SVCLASS_ID,		"Advanced Audio"		},
	{ AV_REMOTE_SVCLASS_ID,			"AV Remote"			},
	{ VIDEO_CONF_SVCLASS_ID,		"Video Conferencing"		},
	{ INTERCOM_SVCLASS_ID,			"Intercom"			},
	{ FAX_SVCLASS_ID,			"Fax"				},
	{ HEADSET_AGW_SVCLASS_ID,		"Headset Audio Gateway"		},
	{ WAP_SVCLASS_ID,			"WAP"				},
	{ WAP_CLIENT_SVCLASS_ID,		"WAP Client"			},
	{ PANU_SVCLASS_ID,			"PAN User"			},
	{ NAP_SVCLASS_ID,			"Network Access Point"		},
	{ GN_SVCLASS_ID,			"PAN Group Network"		},
	{ DIRECT_PRINTING_SVCLASS_ID,		"Direct Printing"		},
	{ REFERENCE_PRINTING_SVCLASS_ID,	"Reference Printing"		},
	{ IMAGING_SVCLASS_ID,			"Imaging"			},
	{ IMAGING_RESPONDER_SVCLASS_ID,		"Imaging Responder"		},
	{ IMAGING_ARCHIVE_SVCLASS_ID,		"Imaging Automatic Archive"	},
	{ IMAGING_REFOBJS_SVCLASS_ID,		"Imaging Referenced Objects"	},
	{ HANDSFREE_SVCLASS_ID,			"Handsfree"			},
	{ HANDSFREE_AGW_SVCLASS_ID,		"Handsfree Audio Gateway"	},
	{ DIRECT_PRT_REFOBJS_SVCLASS_ID,	"Direct Printing Ref. Objects"	},
	{ REFLECTED_UI_SVCLASS_ID,		"Reflected UI"			},
	{ BASIC_PRINTING_SVCLASS_ID,		"Basic Printing"		},
	{ PRINTING_STATUS_SVCLASS_ID,		"Printing Status"		},
	{ HID_SVCLASS_ID,			"Human Interface Device"	},
	{ HCR_SVCLASS_ID,			"Hardcopy Cable Replacement"	},
	{ HCR_PRINT_SVCLASS_ID,			"HCR Print"			},
	{ HCR_SCAN_SVCLASS_ID,			"HCR Scan"			},
	{ CIP_SVCLASS_ID,			"Common ISDN Access"		},
	{ VIDEO_CONF_GW_SVCLASS_ID,		"Video Conferencing Gateway"	},
	{ UDI_MT_SVCLASS_ID,			"UDI MT"			},
	{ UDI_TA_SVCLASS_ID,			"UDI TA"			},
	{ AV_SVCLASS_ID,			"Audio/Video"			},
	{ SAP_SVCLASS_ID,			"SIM Access"			},
	{ PBAP_PCE_SVCLASS_ID,			"Phonebook Access - PCE"	},
	{ PBAP_PSE_SVCLASS_ID,			"Phonebook Access - PSE"	},
	{ PBAP_SVCLASS_ID,			"Phonebook Access"		},
	{ PNP_INFO_SVCLASS_ID,			"PnP Information"		},
	{ GENERIC_NETWORKING_SVCLASS_ID,	"Generic Networking"		},
	{ GENERIC_FILETRANS_SVCLASS_ID,		"Generic File Transfer"		},
	{ GENERIC_AUDIO_SVCLASS_ID,		"Generic Audio"			},
	{ GENERIC_TELEPHONY_SVCLASS_ID,		"Generic Telephony"		},
	{ UPNP_SVCLASS_ID,			"UPnP"				},
	{ UPNP_IP_SVCLASS_ID,			"UPnP IP"			},
	{ UPNP_PAN_SVCLASS_ID,			"UPnP PAN"			},
	{ UPNP_LAP_SVCLASS_ID,			"UPnP LAP"			},
	{ UPNP_L2CAP_SVCLASS_ID,		"UPnP L2CAP"			},
	{ VIDEO_SOURCE_SVCLASS_ID,		"Video Source"			},
	{ VIDEO_SINK_SVCLASS_ID,		"Video Sink"			},
	{ VIDEO_DISTRIBUTION_SVCLASS_ID,	"Video Distribution"		},
	{ HDP_SVCLASS_ID,			"HDP"				},
	{ HDP_SOURCE_SVCLASS_ID,		"HDP Source"			},
	{ HDP_SINK_SVCLASS_ID,			"HDP Sink"			},
	{ APPLE_AGENT_SVCLASS_ID,		"Apple Agent"			},
	{ 0 }
};

#define Profile ServiceClass

static char *string_lookup(struct tupla *pt0, int index)
{
	struct tupla *pt;

	for (pt = pt0; pt->index; pt++)
		if (pt->index == index)
			return pt->str;

	return "";
}

static char *string_lookup_uuid(struct tupla *pt0, const uuid_t* uuid)
{
	uuid_t tmp_uuid;

	memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid));

	if (sdp_uuid128_to_uuid(&tmp_uuid)) {
		switch (tmp_uuid.type) {
		case SDP_UUID16:
			return string_lookup(pt0, tmp_uuid.value.uuid16);
		case SDP_UUID32:
			return string_lookup(pt0, tmp_uuid.value.uuid32);
		}
	}

	return "";
}

/*
 * Prints into a string the Protocol UUID
 * coping a maximum of n characters.
 */
static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n)
{
	char *str2;

	if (!uuid) {
		snprintf(str, n, "NULL");
		return -2;
	}

	switch (uuid->type) {
	case SDP_UUID16:
		str2 = string_lookup(message, uuid->value.uuid16);
		snprintf(str, n, "%s", str2);
		break;
	case SDP_UUID32:
		str2 = string_lookup(message, uuid->value.uuid32);
		snprintf(str, n, "%s", str2);
		break;
	case SDP_UUID128:
		str2 = string_lookup_uuid(message, uuid);
		snprintf(str, n, "%s", str2);
		break;
	default:
		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
		return -1;
	}

	return 0;
}

int sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n)
{
	return uuid2str(Protocol, uuid, str, n);
}

int sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n)
{
	return uuid2str(ServiceClass, uuid, str, n);
}

int sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n)
{
	return uuid2str(Profile, uuid, str, n);
}

/*
 * convert the UUID to string, copying a maximum of n characters.
 */
int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n)
{
	if (!uuid) {
		snprintf(str, n, "NULL");
		return -2;
	}
	switch (uuid->type) {
	case SDP_UUID16:
		snprintf(str, n, "%.4x", uuid->value.uuid16);
		break;
	case SDP_UUID32:
		snprintf(str, n, "%.8x", uuid->value.uuid32);
		break;
	case SDP_UUID128:{
		unsigned int   data0;
		unsigned short data1;
		unsigned short data2;
		unsigned short data3;
		unsigned int   data4;
		unsigned short data5;

		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
		memcpy(&data5, &uuid->value.uuid128.data[14], 2);

		snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
				ntohl(data0), ntohs(data1),
				ntohs(data2), ntohs(data3),
				ntohl(data4), ntohs(data5));
		}
		break;
	default:
		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
		return -1;	/* Enum type of UUID not set */
	}
	return 0;
}

#ifdef SDP_DEBUG
/*
 * Function prints the UUID in hex as per defined syntax -
 *
 * 4bytes-2bytes-2bytes-2bytes-6bytes
 *
 * There is some ugly code, including hardcoding, but
 * that is just the way it is converting 16 and 32 bit
 * UUIDs to 128 bit as defined in the SDP doc
 */
void sdp_uuid_print(const uuid_t *uuid)
{
	if (uuid == NULL) {
		SDPERR("Null passed to print UUID\n");
		return;
	}
	if (uuid->type == SDP_UUID16) {
		SDPDBG("  uint16_t : 0x%.4x\n", uuid->value.uuid16);
	} else if (uuid->type == SDP_UUID32) {
		SDPDBG("  uint32_t : 0x%.8x\n", uuid->value.uuid32);
	} else if (uuid->type == SDP_UUID128) {
		unsigned int data0;
		unsigned short data1;
		unsigned short data2;
		unsigned short data3;
		unsigned int data4;
		unsigned short data5;

		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
		memcpy(&data5, &uuid->value.uuid128.data[14], 2);

		SDPDBG("  uint128_t : 0x%.8x-", ntohl(data0));
		SDPDBG("%.4x-", ntohs(data1));
		SDPDBG("%.4x-", ntohs(data2));
		SDPDBG("%.4x-", ntohs(data3));
		SDPDBG("%.8x", ntohl(data4));
		SDPDBG("%.4x\n", ntohs(data5));
	} else
		SDPERR("Enum type of UUID not set\n");
}
#endif

sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value,
							uint32_t length)
{
	sdp_data_t *seq;
	sdp_data_t *d = malloc(sizeof(sdp_data_t));

	if (!d)
		return NULL;

	memset(d, 0, sizeof(sdp_data_t));
	d->dtd = dtd;
	d->unitSize = sizeof(uint8_t);

	switch (dtd) {
	case SDP_DATA_NIL:
		break;
	case SDP_UINT8:
		d->val.uint8 = *(uint8_t *) value;
		d->unitSize += sizeof(uint8_t);
		break;
	case SDP_INT8:
	case SDP_BOOL:
		d->val.int8 = *(int8_t *) value;
		d->unitSize += sizeof(int8_t);
		break;
	case SDP_UINT16:
		d->val.uint16 = bt_get_unaligned((uint16_t *) value);
		d->unitSize += sizeof(uint16_t);
		break;
	case SDP_INT16:
		d->val.int16 = bt_get_unaligned((int16_t *) value);
		d->unitSize += sizeof(int16_t);
		break;
	case SDP_UINT32:
		d->val.uint32 = bt_get_unaligned((uint32_t *) value);
		d->unitSize += sizeof(uint32_t);
		break;
	case SDP_INT32:
		d->val.int32 = bt_get_unaligned((int32_t *) value);
		d->unitSize += sizeof(int32_t);
		break;
	case SDP_INT64:
		d->val.int64 = bt_get_unaligned((int64_t *) value);
		d->unitSize += sizeof(int64_t);
		break;
	case SDP_UINT64:
		d->val.uint64 = bt_get_unaligned((uint64_t *) value);
		d->unitSize += sizeof(uint64_t);
		break;
	case SDP_UINT128:
		memcpy(&d->val.uint128.data, value, sizeof(uint128_t));
		d->unitSize += sizeof(uint128_t);
		break;
	case SDP_INT128:
		memcpy(&d->val.int128.data, value, sizeof(uint128_t));
		d->unitSize += sizeof(uint128_t);
		break;
	case SDP_UUID16:
		sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value));
		d->unitSize += sizeof(uint16_t);
		break;
	case SDP_UUID32:
		sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value));
		d->unitSize += sizeof(uint32_t);
		break;
	case SDP_UUID128:
		sdp_uuid128_create(&d->val.uuid, value);
		d->unitSize += sizeof(uint128_t);
		break;
	case SDP_URL_STR8:
	case SDP_URL_STR16:
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
		if (!value) {
			free(d);
			return NULL;
		}

		d->unitSize += length;
		if (length <= USHRT_MAX) {
			d->val.str = malloc(length);
			if (!d->val.str) {
				free(d);
				return NULL;
			}

			memcpy(d->val.str, value, length);
		} else {
			SDPERR("Strings of size > USHRT_MAX not supported\n");
			free(d);
			d = NULL;
		}
		break;
	case SDP_URL_STR32:
	case SDP_TEXT_STR32:
		SDPERR("Strings of size > USHRT_MAX not supported\n");
		break;
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
		if (dtd == SDP_ALT8 || dtd == SDP_SEQ8)
			d->unitSize += sizeof(uint8_t);
		else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16)
			d->unitSize += sizeof(uint16_t);
		else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32)
			d->unitSize += sizeof(uint32_t);
		seq = (sdp_data_t *)value;
		d->val.dataseq = seq;
		for (; seq; seq = seq->next)
			d->unitSize += seq->unitSize;
		break;
	default:
		free(d);
		d = NULL;
	}

	return d;
}

sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value)
{
	uint32_t length;

	switch (dtd) {
	case SDP_URL_STR8:
	case SDP_URL_STR16:
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
		if (!value)
			return NULL;

		length = strlen((char *) value);
		break;
	default:
		length = 0;
		break;
	}

	return sdp_data_alloc_with_length(dtd, value, length);
}

sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d)
{
	if (seq) {
		sdp_data_t *p;
		for (p = seq; p->next; p = p->next);
		p->next = d;
	} else
		seq = d;
	d->next = NULL;
	return seq;
}

sdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length,
								int len)
{
	sdp_data_t *curr = NULL, *seq = NULL;
	int i;

	for (i = 0; i < len; i++) {
		sdp_data_t *data;
		int8_t dtd = *(uint8_t *) dtds[i];

		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
			data = (sdp_data_t *) values[i];
		else
			data = sdp_data_alloc_with_length(dtd, values[i], length[i]);

		if (!data)
			return NULL;

		if (curr)
			curr->next = data;
		else
			seq = data;

		curr = data;
	}

	return sdp_data_alloc_with_length(SDP_SEQ8, seq, length[i]);
}

sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len)
{
	sdp_data_t *curr = NULL, *seq = NULL;
	int i;

	for (i = 0; i < len; i++) {
		sdp_data_t *data;
		uint8_t dtd = *(uint8_t *) dtds[i];

		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
			data = (sdp_data_t *) values[i];
		else
			data = sdp_data_alloc(dtd, values[i]);

		if (!data)
			return NULL;

		if (curr)
			curr->next = data;
		else
			seq = data;

		curr = data;
	}

	return sdp_data_alloc(SDP_SEQ8, seq);
}

static void extract_svclass_uuid(sdp_data_t *data, uuid_t *uuid)
{
	sdp_data_t *d;

	if (!data || data->dtd < SDP_SEQ8 || data->dtd > SDP_SEQ32)
		return;

	d = data->val.dataseq;
	if (!d)
		return;

	if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128)
		return;

	*uuid = d->val.uuid;
}

int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
{
	sdp_data_t *p = sdp_data_get(rec, attr);

	if (p)
		return -1;

	d->attrId = attr;
	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);

	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
		extract_svclass_uuid(d, &rec->svclass);

	return 0;
}

void sdp_attr_remove(sdp_record_t *rec, uint16_t attr)
{
	sdp_data_t *d = sdp_data_get(rec, attr);

	if (d)
		rec->attrlist = sdp_list_remove(rec->attrlist, d);

	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
		memset(&rec->svclass, 0, sizeof(rec->svclass));
}

void sdp_set_seq_len(uint8_t *ptr, uint32_t length)
{
	uint8_t dtd = *ptr++;

	switch (dtd) {
	case SDP_SEQ8:
	case SDP_ALT8:
	case SDP_TEXT_STR8:
	case SDP_URL_STR8:
		*ptr = (uint8_t) length;
		break;
	case SDP_SEQ16:
	case SDP_ALT16:
	case SDP_TEXT_STR16:
	case SDP_URL_STR16:
		bt_put_unaligned(htons(length), (uint16_t *) ptr);
		break;
	case SDP_SEQ32:
	case SDP_ALT32:
	case SDP_TEXT_STR32:
	case SDP_URL_STR32:
		bt_put_unaligned(htonl(length), (uint32_t *) ptr);
		break;
	}
}

static int sdp_get_data_type(sdp_buf_t *buf, uint8_t dtd)
{
	int data_type = 0;

	data_type += sizeof(uint8_t);

	switch (dtd) {
	case SDP_SEQ8:
	case SDP_TEXT_STR8:
	case SDP_URL_STR8:
	case SDP_ALT8:
		data_type += sizeof(uint8_t);
		break;
	case SDP_SEQ16:
	case SDP_TEXT_STR16:
	case SDP_URL_STR16:
	case SDP_ALT16:
		data_type += sizeof(uint16_t);
		break;
	case SDP_SEQ32:
	case SDP_TEXT_STR32:
	case SDP_URL_STR32:
	case SDP_ALT32:
		data_type += sizeof(uint32_t);
		break;
	}

	if (!buf->data)
		buf->buf_size += data_type;

	return data_type;
}

static int sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd)
{
	int data_type = 0;
	uint8_t *p = buf->data + buf->data_size;

	*p++ = dtd;
	data_type = sdp_get_data_type(buf, dtd);
	buf->data_size += data_type;

	return data_type;
}

void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr)
{
	uint8_t *p = buf->data;

	/* data type for attr */
	*p++ = SDP_UINT16;
	buf->data_size = sizeof(uint8_t);
	bt_put_unaligned(htons(attr), (uint16_t *) p);
	p += sizeof(uint16_t);
	buf->data_size += sizeof(uint16_t);
}

static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata)
{
	sdp_data_t *d;
	int n = 0;

	for (d = sdpdata->val.dataseq; d; d = d->next) {
		if (buf->data)
			n += sdp_gen_pdu(buf, d);
		else
			n += sdp_gen_buffer(buf, d);
	}

	return n;
}

static int sdp_get_data_size(sdp_buf_t *buf, sdp_data_t *d)
{
	uint32_t data_size = 0;
	uint8_t dtd = d->dtd;

	switch (dtd) {
	case SDP_DATA_NIL:
		break;
	case SDP_UINT8:
		data_size = sizeof(uint8_t);
		break;
	case SDP_UINT16:
		data_size = sizeof(uint16_t);
		break;
	case SDP_UINT32:
		data_size = sizeof(uint32_t);
		break;
	case SDP_UINT64:
		data_size = sizeof(uint64_t);
		break;
	case SDP_UINT128:
		data_size = sizeof(uint128_t);
		break;
	case SDP_INT8:
	case SDP_BOOL:
		data_size = sizeof(int8_t);
		break;
	case SDP_INT16:
		data_size = sizeof(int16_t);
		break;
	case SDP_INT32:
		data_size = sizeof(int32_t);
		break;
	case SDP_INT64:
		data_size = sizeof(int64_t);
		break;
	case SDP_INT128:
		data_size = sizeof(uint128_t);
		break;
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
	case SDP_TEXT_STR32:
	case SDP_URL_STR8:
	case SDP_URL_STR16:
	case SDP_URL_STR32:
		data_size = d->unitSize - sizeof(uint8_t);
		break;
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
		data_size = get_data_size(buf, d);
		break;
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
		data_size = get_data_size(buf, d);
		break;
	case SDP_UUID16:
		data_size = sizeof(uint16_t);
		break;
	case SDP_UUID32:
		data_size = sizeof(uint32_t);
		break;
	case SDP_UUID128:
		data_size = sizeof(uint128_t);
		break;
	default:
		break;
	}

	if (!buf->data)
		buf->buf_size += data_size;

	return data_size;
}

static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d)
{
	int orig = buf->buf_size;

	if (buf->buf_size == 0 && d->dtd == 0) {
		/* create initial sequence */
		buf->buf_size += sizeof(uint8_t);

		/* reserve space for sequence size */
		buf->buf_size += sizeof(uint8_t);
	}

	/* attribute length */
	buf->buf_size += sizeof(uint8_t) + sizeof(uint16_t);

	sdp_get_data_type(buf, d->dtd);
	sdp_get_data_size(buf, d);

	if (buf->buf_size > UCHAR_MAX && d->dtd == SDP_SEQ8)
		buf->buf_size += sizeof(uint8_t);

	return buf->buf_size - orig;
}

int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
{
	uint32_t pdu_size = 0, data_size = 0;
	unsigned char *src = NULL, is_seq = 0, is_alt = 0;
	uint8_t dtd = d->dtd;
	uint16_t u16;
	uint32_t u32;
	uint64_t u64;
	uint128_t u128;
	uint8_t *seqp = buf->data + buf->data_size;

	pdu_size = sdp_set_data_type(buf, dtd);
	data_size = sdp_get_data_size(buf, d);

	switch (dtd) {
	case SDP_DATA_NIL:
		break;
	case SDP_UINT8:
		src = &d->val.uint8;
		break;
	case SDP_UINT16:
		u16 = htons(d->val.uint16);
		src = (unsigned char *) &u16;
		break;
	case SDP_UINT32:
		u32 = htonl(d->val.uint32);
		src = (unsigned char *) &u32;
		break;
	case SDP_UINT64:
		u64 = hton64(d->val.uint64);
		src = (unsigned char *) &u64;
		break;
	case SDP_UINT128:
		hton128(&d->val.uint128, &u128);
		src = (unsigned char *) &u128;
		break;
	case SDP_INT8:
	case SDP_BOOL:
		src = (unsigned char *) &d->val.int8;
		break;
	case SDP_INT16:
		u16 = htons(d->val.int16);
		src = (unsigned char *) &u16;
		break;
	case SDP_INT32:
		u32 = htonl(d->val.int32);
		src = (unsigned char *) &u32;
		break;
	case SDP_INT64:
		u64 = hton64(d->val.int64);
		src = (unsigned char *) &u64;
		break;
	case SDP_INT128:
		hton128(&d->val.int128, &u128);
		src = (unsigned char *) &u128;
		break;
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
	case SDP_TEXT_STR32:
	case SDP_URL_STR8:
	case SDP_URL_STR16:
	case SDP_URL_STR32:
		src = (unsigned char *) d->val.str;
		sdp_set_seq_len(seqp, data_size);
		break;
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
		is_seq = 1;
		sdp_set_seq_len(seqp, data_size);
		break;
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
		is_alt = 1;
		sdp_set_seq_len(seqp, data_size);
		break;
	case SDP_UUID16:
		u16 = htons(d->val.uuid.value.uuid16);
		src = (unsigned char *) &u16;
		break;
	case SDP_UUID32:
		u32 = htonl(d->val.uuid.value.uuid32);
		src = (unsigned char *) &u32;
		break;
	case SDP_UUID128:
		src = (unsigned char *) &d->val.uuid.value.uuid128;
		break;
	default:
		break;
	}

	if (!is_seq && !is_alt) {
		if (src && buf && buf->buf_size >= buf->data_size + data_size) {
			memcpy(buf->data + buf->data_size, src, data_size);
			buf->data_size += data_size;
		} else if (dtd != SDP_DATA_NIL) {
			SDPDBG("Gen PDU : Can't copy from invalid source or dest\n");
		}
	}

	pdu_size += data_size;

	return pdu_size;
}

static void sdp_attr_pdu(void *value, void *udata)
{
	sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);
}

static void sdp_attr_size(void *value, void *udata)
{
	sdp_gen_buffer((sdp_buf_t *)udata, (sdp_data_t *)value);
}

int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf)
{
	memset(buf, 0, sizeof(sdp_buf_t));
	sdp_list_foreach(rec->attrlist, sdp_attr_size, buf);

	buf->data = malloc(buf->buf_size);
	if (!buf->data)
		return -ENOMEM;
	buf->data_size = 0;
	memset(buf->data, 0, buf->buf_size);

	sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf);

	return 0;
}

void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
{
	sdp_data_t *p = sdp_data_get(rec, attr);

	if (p) {
		rec->attrlist = sdp_list_remove(rec->attrlist, p);
		sdp_data_free(p);
	}

	d->attrId = attr;
	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);

	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
		extract_svclass_uuid(d, &rec->svclass);
}

int sdp_attrid_comp_func(const void *key1, const void *key2)
{
	const sdp_data_t *d1 = (const sdp_data_t *)key1;
	const sdp_data_t *d2 = (const sdp_data_t *)key2;

	if (d1 && d2)
		return d1->attrId - d2->attrId;
	return 0;
}

static void data_seq_free(sdp_data_t *seq)
{
	sdp_data_t *d = seq->val.dataseq;

	while (d) {
		sdp_data_t *next = d->next;
		sdp_data_free(d);
		d = next;
	}
}

void sdp_data_free(sdp_data_t *d)
{
	switch (d->dtd) {
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
		data_seq_free(d);
		break;
	case SDP_URL_STR8:
	case SDP_URL_STR16:
	case SDP_URL_STR32:
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
	case SDP_TEXT_STR32:
		free(d->val.str);
		break;
	}
	free(d);
}

int sdp_uuid_extract(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned)
{
	uint8_t type;

	if (bufsize < (int) sizeof(uint8_t)) {
		SDPERR("Unexpected end of packet");
		return -1;
	}

	type = *(const uint8_t *) p;

	if (!SDP_IS_UUID(type)) {
		SDPERR("Unknown data type : %d expecting a svc UUID\n", type);
		return -1;
	}
	p += sizeof(uint8_t);
	*scanned += sizeof(uint8_t);
	bufsize -= sizeof(uint8_t);
	if (type == SDP_UUID16) {
		if (bufsize < (int) sizeof(uint16_t)) {
			SDPERR("Not enough room for 16-bit UUID");
			return -1;
		}
		sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p)));
		*scanned += sizeof(uint16_t);
		p += sizeof(uint16_t);
	} else if (type == SDP_UUID32) {
		if (bufsize < (int) sizeof(uint32_t)) {
			SDPERR("Not enough room for 32-bit UUID");
			return -1;
		}
		sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p)));
		*scanned += sizeof(uint32_t);
		p += sizeof(uint32_t);
	} else {
		if (bufsize < (int) sizeof(uint128_t)) {
			SDPERR("Not enough room for 128-bit UUID");
			return -1;
		}
		sdp_uuid128_create(uuid, p);
		*scanned += sizeof(uint128_t);
		p += sizeof(uint128_t);
	}
	return 0;
}

static sdp_data_t *extract_int(const void *p, int bufsize, int *len)
{
	sdp_data_t *d;

	if (bufsize < (int) sizeof(uint8_t)) {
		SDPERR("Unexpected end of packet");
		return NULL;
	}

	d = malloc(sizeof(sdp_data_t));
	if (!d)
		return NULL;

	SDPDBG("Extracting integer\n");
	memset(d, 0, sizeof(sdp_data_t));
	d->dtd = *(uint8_t *) p;
	p += sizeof(uint8_t);
	*len += sizeof(uint8_t);
	bufsize -= sizeof(uint8_t);

	switch (d->dtd) {
	case SDP_DATA_NIL:
		break;
	case SDP_BOOL:
	case SDP_INT8:
	case SDP_UINT8:
		if (bufsize < (int) sizeof(uint8_t)) {
			SDPERR("Unexpected end of packet");
			free(d);
			return NULL;
		}
		*len += sizeof(uint8_t);
		d->val.uint8 = *(uint8_t *) p;
		break;
	case SDP_INT16:
	case SDP_UINT16:
		if (bufsize < (int) sizeof(uint16_t)) {
			SDPERR("Unexpected end of packet");
			free(d);
			return NULL;
		}
		*len += sizeof(uint16_t);
		d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p));
		break;
	case SDP_INT32:
	case SDP_UINT32:
		if (bufsize < (int) sizeof(uint32_t)) {
			SDPERR("Unexpected end of packet");
			free(d);
			return NULL;
		}
		*len += sizeof(uint32_t);
		d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p));
		break;
	case SDP_INT64:
	case SDP_UINT64:
		if (bufsize < (int) sizeof(uint64_t)) {
			SDPERR("Unexpected end of packet");
			free(d);
			return NULL;
		}
		*len += sizeof(uint64_t);
		d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p));
		break;
	case SDP_INT128:
	case SDP_UINT128:
		if (bufsize < (int) sizeof(uint128_t)) {
			SDPERR("Unexpected end of packet");
			free(d);
			return NULL;
		}
		*len += sizeof(uint128_t);
		ntoh128((uint128_t *) p, &d->val.uint128);
		break;
	default:
		free(d);
		d = NULL;
	}
	return d;
}

static sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len,
							sdp_record_t *rec)
{
	sdp_data_t *d = malloc(sizeof(sdp_data_t));

	if (!d)
		return NULL;

	SDPDBG("Extracting UUID");
	memset(d, 0, sizeof(sdp_data_t));
	if (sdp_uuid_extract(p, bufsize, &d->val.uuid, len) < 0) {
		free(d);
		return NULL;
	}
	d->dtd = *p;
	if (rec)
		sdp_pattern_add_uuid(rec, &d->val.uuid);
	return d;
}

/*
 * Extract strings from the PDU (could be service description and similar info)
 */
static sdp_data_t *extract_str(const void *p, int bufsize, int *len)
{
	char *s;
	int n;
	sdp_data_t *d;

	if (bufsize < (int) sizeof(uint8_t)) {
		SDPERR("Unexpected end of packet");
		return NULL;
	}

	d = malloc(sizeof(sdp_data_t));
	if (!d)
		return NULL;

	memset(d, 0, sizeof(sdp_data_t));
	d->dtd = *(uint8_t *) p;
	p += sizeof(uint8_t);
	*len += sizeof(uint8_t);
	bufsize -= sizeof(uint8_t);

	switch (d->dtd) {
	case SDP_TEXT_STR8:
	case SDP_URL_STR8:
		if (bufsize < (int) sizeof(uint8_t)) {
			SDPERR("Unexpected end of packet");
			free(d);
			return NULL;
		}
		n = *(uint8_t *) p;
		p += sizeof(uint8_t);
		*len += sizeof(uint8_t);
		bufsize -= sizeof(uint8_t);
		break;
	case SDP_TEXT_STR16:
	case SDP_URL_STR16:
		if (bufsize < (int) sizeof(uint16_t)) {
			SDPERR("Unexpected end of packet");
			free(d);
			return NULL;
		}
		n = ntohs(bt_get_unaligned((uint16_t *) p));
		p += sizeof(uint16_t);
		*len += sizeof(uint16_t) + n;
		bufsize -= sizeof(uint16_t);
		break;
	default:
		SDPERR("Sizeof text string > UINT16_MAX\n");
		free(d);
		return NULL;
	}

	if (bufsize < n) {
		SDPERR("String too long to fit in packet");
		free(d);
		return NULL;
	}

	s = malloc(n + 1);
	if (!s) {
		SDPERR("Not enough memory for incoming string");
		free(d);
		return NULL;
	}
	memset(s, 0, n + 1);
	memcpy(s, p, n);

	*len += n;

	SDPDBG("Len : %d\n", n);
	SDPDBG("Str : %s\n", s);

	d->val.str = s;
	d->unitSize = n + sizeof(uint8_t);
	return d;
}

/*
 * Extract the sequence type and its length, and return offset into buf
 * or 0 on failure.
 */
int sdp_extract_seqtype(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size)
{
	uint8_t dtd;
	int scanned = sizeof(uint8_t);

	if (bufsize < (int) sizeof(uint8_t)) {
		SDPERR("Unexpected end of packet");
		return 0;
	}

	dtd = *(uint8_t *) buf;
	buf += sizeof(uint8_t);
	bufsize -= sizeof(uint8_t);
	*dtdp = dtd;
	switch (dtd) {
	case SDP_SEQ8:
	case SDP_ALT8:
		if (bufsize < (int) sizeof(uint8_t)) {
			SDPERR("Unexpected end of packet");
			return 0;
		}
		*size = *(uint8_t *) buf;
		scanned += sizeof(uint8_t);
		break;
	case SDP_SEQ16:
	case SDP_ALT16:
		if (bufsize < (int) sizeof(uint16_t)) {
			SDPERR("Unexpected end of packet");
			return 0;
		}
		*size = ntohs(bt_get_unaligned((uint16_t *) buf));
		scanned += sizeof(uint16_t);
		break;
	case SDP_SEQ32:
	case SDP_ALT32:
		if (bufsize < (int) sizeof(uint32_t)) {
			SDPERR("Unexpected end of packet");
			return 0;
		}
		*size = ntohl(bt_get_unaligned((uint32_t *) buf));
		scanned += sizeof(uint32_t);
		break;
	default:
		SDPERR("Unknown sequence type, aborting\n");
		return 0;
	}
	return scanned;
}

static sdp_data_t *extract_seq(const void *p, int bufsize, int *len,
							sdp_record_t *rec)
{
	int seqlen, n = 0;
	sdp_data_t *curr, *prev;
	sdp_data_t *d = malloc(sizeof(sdp_data_t));

	if (!d)
		return NULL;

	SDPDBG("Extracting SEQ");
	memset(d, 0, sizeof(sdp_data_t));
	*len = sdp_extract_seqtype(p, bufsize, &d->dtd, &seqlen);
	SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen);

	if (*len == 0)
		return d;

	if (*len > bufsize) {
		SDPERR("Packet not big enough to hold sequence.");
		free(d);
		return NULL;
	}

	p += *len;
	bufsize -= *len;
	prev = NULL;
	while (n < seqlen) {
		int attrlen = 0;
		curr = sdp_extract_attr(p, bufsize, &attrlen, rec);
		if (curr == NULL)
			break;

		if (prev)
			prev->next = curr;
		else
			d->val.dataseq = curr;
		prev = curr;
		p += attrlen;
		n += attrlen;
		bufsize -= attrlen;

		SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen);
	}

	*len += n;
	return d;
}

sdp_data_t *sdp_extract_attr(const uint8_t *p, int bufsize, int *size,
							sdp_record_t *rec)
{
	sdp_data_t *elem;
	int n = 0;
	uint8_t dtd;

	if (bufsize < (int) sizeof(uint8_t)) {
		SDPERR("Unexpected end of packet");
		return NULL;
	}

	dtd = *(const uint8_t *)p;

	SDPDBG("extract_attr: dtd=0x%x", dtd);
	switch (dtd) {
	case SDP_DATA_NIL:
	case SDP_BOOL:
	case SDP_UINT8:
	case SDP_UINT16:
	case SDP_UINT32:
	case SDP_UINT64:
	case SDP_UINT128:
	case SDP_INT8:
	case SDP_INT16:
	case SDP_INT32:
	case SDP_INT64:
	case SDP_INT128:
		elem = extract_int(p, bufsize, &n);
		break;
	case SDP_UUID16:
	case SDP_UUID32:
	case SDP_UUID128:
		elem = extract_uuid(p, bufsize, &n, rec);
		break;
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
	case SDP_TEXT_STR32:
	case SDP_URL_STR8:
	case SDP_URL_STR16:
	case SDP_URL_STR32:
		elem = extract_str(p, bufsize, &n);
		break;
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
		elem = extract_seq(p, bufsize, &n, rec);
		break;
	default:
		SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd);
		return NULL;
	}
	*size += n;
	return elem;
}

#ifdef SDP_DEBUG
static void attr_print_func(void *value, void *userData)
{
	sdp_data_t *d = (sdp_data_t *)value;

	SDPDBG("=====================================\n");
	SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n",  d->attrId);
	SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value);
	if (d)
		sdp_data_print(d);
	else
		SDPDBG("NULL value\n");
	SDPDBG("=====================================\n");
}

void sdp_print_service_attr(sdp_list_t *svcAttrList)
{
	SDPDBG("Printing service attr list %p\n", svcAttrList);
	sdp_list_foreach(svcAttrList, attr_print_func, NULL);
	SDPDBG("Printed service attr list %p\n", svcAttrList);
}
#endif

sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int bufsize, int *scanned)
{
	int extracted = 0, seqlen = 0;
	uint8_t dtd;
	uint16_t attr;
	sdp_record_t *rec = sdp_record_alloc();
	const uint8_t *p = buf;

	*scanned = sdp_extract_seqtype(buf, bufsize, &dtd, &seqlen);
	p += *scanned;
	bufsize -= *scanned;
	rec->attrlist = NULL;

	while (extracted < seqlen && bufsize > 0) {
		int n = sizeof(uint8_t), attrlen = 0;
		sdp_data_t *data = NULL;

		SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d",
							seqlen, extracted);

		if (bufsize < n + (int) sizeof(uint16_t)) {
			SDPERR("Unexpected end of packet");
			break;
		}

		dtd = *(uint8_t *) p;
		attr = ntohs(bt_get_unaligned((uint16_t *) (p + n)));
		n += sizeof(uint16_t);

		SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr);

		data = sdp_extract_attr(p + n, bufsize - n, &attrlen, rec);

		SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen);

		n += attrlen;
		if (data == NULL) {
			SDPDBG("Terminating extraction of attributes");
			break;
		}

		if (attr == SDP_ATTR_RECORD_HANDLE)
			rec->handle = data->val.uint32;

		if (attr == SDP_ATTR_SVCLASS_ID_LIST)
			extract_svclass_uuid(data, &rec->svclass);

		extracted += n;
		p += n;
		bufsize -= n;
		sdp_attr_replace(rec, attr, data);

		SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",
							seqlen, extracted);
	}
#ifdef SDP_DEBUG
	SDPDBG("Successful extracting of Svc Rec attributes\n");
	sdp_print_service_attr(rec->attrlist);
#endif
	*scanned += seqlen;
	return rec;
}

static void sdp_copy_pattern(void *value, void *udata)
{
	uuid_t *uuid = value;
	sdp_record_t *rec = udata;

	sdp_pattern_add_uuid(rec, uuid);
}

static void *sdp_data_value(sdp_data_t *data, uint32_t *len)
{
	void *val = NULL;

	switch (data->dtd) {
	case SDP_DATA_NIL:
		break;
	case SDP_UINT8:
		val = &data->val.uint8;
		break;
	case SDP_INT8:
	case SDP_BOOL:
		val = &data->val.int8;
		break;
	case SDP_UINT16:
		val = &data->val.uint16;
		break;
	case SDP_INT16:
		val = &data->val.int16;
		break;
	case SDP_UINT32:
		val = &data->val.uint32;
		break;
	case SDP_INT32:
		val = &data->val.int32;
		break;
	case SDP_INT64:
		val = &data->val.int64;
		break;
	case SDP_UINT64:
		val = &data->val.uint64;
		break;
	case SDP_UINT128:
		val = &data->val.uint128;
		break;
	case SDP_INT128:
		val = &data->val.int128;
		break;
	case SDP_UUID16:
		val = &data->val.uuid.value.uuid16;
		break;
	case SDP_UUID32:
		val = &data->val.uuid.value.uuid32;
		break;
	case SDP_UUID128:
		val = &data->val.uuid.value.uuid128;
		break;
	case SDP_URL_STR8:
	case SDP_URL_STR16:
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
	case SDP_URL_STR32:
	case SDP_TEXT_STR32:
		val = data->val.str;
		if (len)
			*len = data->unitSize - 1;
		break;
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
		val = sdp_copy_seq(data->val.dataseq);
		break;
	}

	return val;
}

static sdp_data_t *sdp_copy_seq(sdp_data_t *data)
{
	sdp_data_t *tmp, *seq = NULL, *cur = NULL;

	for (tmp = data; tmp; tmp = tmp->next) {
		sdp_data_t *datatmp;
		void *value;

		value = sdp_data_value(tmp, NULL);
		datatmp = sdp_data_alloc_with_length(tmp->dtd, value,
								tmp->unitSize);

		if (cur)
			cur->next = datatmp;
		else
			seq = datatmp;

		cur = datatmp;
	}

	return seq;
}

static void sdp_copy_attrlist(void *value, void *udata)
{
	sdp_data_t *data = value;
	sdp_record_t *rec = udata;
	void *val;
	uint32_t len = 0;

	val = sdp_data_value(data, &len);

	if (!len)
		sdp_attr_add_new(rec, data->attrId, data->dtd, val);
	else
		sdp_attr_add_new_with_length(rec, data->attrId,
							data->dtd, val, len);
}

sdp_record_t *sdp_copy_record(sdp_record_t *rec)
{
	sdp_record_t *cpy;

	cpy = sdp_record_alloc();

	cpy->handle = rec->handle;

	sdp_list_foreach(rec->pattern, sdp_copy_pattern, cpy);
	sdp_list_foreach(rec->attrlist, sdp_copy_attrlist, cpy);

	cpy->svclass = rec->svclass;

	return cpy;
}

#ifdef SDP_DEBUG
static void print_dataseq(sdp_data_t *p)
{
	sdp_data_t *d;

	for (d = p; d; d = d->next)
		sdp_data_print(d);
}
#endif

void sdp_record_print(const sdp_record_t *rec)
{
	sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
	if (d)
		printf("Service Name: %.*s\n", d->unitSize, d->val.str);
	d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
	if (d)
		printf("Service Description: %.*s\n", d->unitSize, d->val.str);
	d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
	if (d)
		printf("Service Provider: %.*s\n", d->unitSize, d->val.str);
}

#ifdef SDP_DEBUG
void sdp_data_print(sdp_data_t *d)
{
	switch (d->dtd) {
	case SDP_DATA_NIL:
		SDPDBG("NIL\n");
		break;
	case SDP_BOOL:
	case SDP_UINT8:
	case SDP_UINT16:
	case SDP_UINT32:
	case SDP_UINT64:
	case SDP_UINT128:
	case SDP_INT8:
	case SDP_INT16:
	case SDP_INT32:
	case SDP_INT64:
	case SDP_INT128:
		SDPDBG("Integer : 0x%x\n", d->val.uint32);
		break;
	case SDP_UUID16:
	case SDP_UUID32:
	case SDP_UUID128:
		SDPDBG("UUID\n");
		sdp_uuid_print(&d->val.uuid);
		break;
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
	case SDP_TEXT_STR32:
		SDPDBG("Text : %s\n", d->val.str);
		break;
	case SDP_URL_STR8:
	case SDP_URL_STR16:
	case SDP_URL_STR32:
		SDPDBG("URL : %s\n", d->val.str);
		break;
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
		print_dataseq(d->val.dataseq);
		break;
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
		SDPDBG("Data Sequence Alternates\n");
		print_dataseq(d->val.dataseq);
		break;
	}
}
#endif

sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId)
{
	if (rec->attrlist) {
		sdp_data_t sdpTemplate;
		sdp_list_t *p;

		sdpTemplate.attrId = attrId;
		p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func);
		if (p)
			return p->data;
	}
	return NULL;
}

static int sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size)
{
	uint32_t sent = 0;

	while (sent < size) {
		int n = send(session->sock, buf + sent, size - sent, 0);
		if (n < 0)
			return -1;
		sent += n;
	}
	return 0;
}

static int sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size)
{
	fd_set readFds;
	struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 };

	FD_ZERO(&readFds);
	FD_SET(session->sock, &readFds);
	SDPDBG("Waiting for response\n");
	if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) {
		SDPERR("Client timed out\n");
		errno = ETIMEDOUT;
		return -1;
	}
	return recv(session->sock, buf, size, 0);
}

/*
 * generic send request, wait for response method.
 */
int sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf,
			uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize)
{
	int n;
	sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *) reqbuf;
	sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *) rspbuf;

	SDPDBG("");
	if (0 > sdp_send_req(session, reqbuf, reqsize)) {
		SDPERR("Error sending data:%s", strerror(errno));
		return -1;
	}
	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
	if (0 > n)
		return -1;
	SDPDBG("Read : %d\n", n);
	if (n == 0 || reqhdr->tid != rsphdr->tid) {
		errno = EPROTO;
		return -1;
	}
	*rspsize = n;
	return 0;
}

/*
 * singly-linked lists (after openobex implementation)
 */
sdp_list_t *sdp_list_append(sdp_list_t *p, void *d)
{
	sdp_list_t *q, *n = malloc(sizeof(sdp_list_t));

	if (!n)
		return NULL;

	n->data = d;
	n->next = 0;

	if (!p)
		return n;

	for (q = p; q->next; q = q->next);
	q->next = n;

	return p;
}

sdp_list_t *sdp_list_remove(sdp_list_t *list, void *d)
{
	sdp_list_t *p, *q;

	for (q = 0, p = list; p; q = p, p = p->next)
		if (p->data == d) {
			if (q)
				q->next = p->next;
			else
				list = p->next;
			free(p);
			break;
		}

	return list;
}

sdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d,
							sdp_comp_func_t f)
{
	sdp_list_t *q, *p, *n;

	n = malloc(sizeof(sdp_list_t));
	if (!n)
		return NULL;
	n->data = d;
	for (q = 0, p = list; p; q = p, p = p->next)
		if (f(p->data, d) >= 0)
			break;
	// insert between q and p; if !q insert at head
	if (q)
		q->next = n;
	else
		list = n;
	n->next = p;
	return list;
}

/*
 * Every element of the list points to things which need
 * to be free()'d. This method frees the list's contents
 */
void sdp_list_free(sdp_list_t *list, sdp_free_func_t f)
{
	sdp_list_t *next;
	while (list) {
		next = list->next;
		if (f)
			f(list->data);
		free(list);
		list = next;
	}
}

static inline int __find_port(sdp_data_t *seq, int proto)
{
	if (!seq || !seq->next)
		return 0;

	if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) {
		seq = seq->next;
		switch (seq->dtd) {
		case SDP_UINT8:
			return seq->val.uint8;
		case SDP_UINT16:
			return seq->val.uint16;
		}
	}
	return 0;
}

int sdp_get_proto_port(const sdp_list_t *list, int proto)
{
	if (proto != L2CAP_UUID && proto != RFCOMM_UUID) {
		errno = EINVAL;
		return -1;
	}

	for (; list; list = list->next) {
		sdp_list_t *p;
		for (p = list->data; p; p = p->next) {
			sdp_data_t *seq = p->data;
			int port = __find_port(seq, proto);
			if (port)
				return port;
		}
	}
	return 0;
}

sdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto)
{
	for (; list; list = list->next) {
		sdp_list_t *p;
		for (p = list->data; p; p = p->next) {
			sdp_data_t *seq = p->data;
			if (SDP_IS_UUID(seq->dtd) &&
					sdp_uuid_to_proto(&seq->val.uuid) == proto)
				return seq->next;
		}
	}
	return NULL;
}

int sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
{
	sdp_data_t *pdlist, *curr;
	sdp_list_t *ap = 0;

	pdlist = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
	if (pdlist == NULL) {
		errno = ENODATA;
		return -1;
	}
	SDPDBG("AP type : 0%x\n", pdlist->dtd);

	for (; pdlist; pdlist = pdlist->next) {
		sdp_list_t *pds = 0;
		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
			pds = sdp_list_append(pds, curr->val.dataseq);
		ap = sdp_list_append(ap, pds);
	}
	*pap = ap;
	return 0;
}

int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
{
	sdp_data_t *pdlist, *curr;
	sdp_list_t *ap = 0;

	pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
	if (pdlist == NULL) {
		errno = ENODATA;
		return -1;
	}
	SDPDBG("AP type : 0%x\n", pdlist->dtd);

	pdlist = pdlist->val.dataseq;

	for (; pdlist; pdlist = pdlist->next) {
		sdp_list_t *pds = 0;
		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
			pds = sdp_list_append(pds, curr->val.dataseq);
		ap = sdp_list_append(ap, pds);
	}
	*pap = ap;
	return 0;
}

int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr,
							sdp_list_t **seqp)
{
	sdp_data_t *sdpdata = sdp_data_get(rec, attr);

	*seqp = NULL;
	if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) {
		sdp_data_t *d;
		for (d = sdpdata->val.dataseq; d; d = d->next) {
			uuid_t *u;
			if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) {
				errno = EINVAL;
				goto fail;
			}

			u = malloc(sizeof(uuid_t));
			if (!u)
				goto fail;

			memset(u, 0, sizeof(uuid_t));
			*u = d->val.uuid;
			*seqp = sdp_list_append(*seqp, u);
		}
		return 0;
	}
fail:
	sdp_list_free(*seqp, free);
	*seqp = NULL;
	return -1;
}

int sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq)
{
	int status = 0, i, len;
	void **dtds, **values;
	uint8_t uuid16 = SDP_UUID16;
	uint8_t uuid32 = SDP_UUID32;
	uint8_t uuid128 = SDP_UUID128;
	sdp_list_t *p;

	len = sdp_list_len(seq);
	if (!seq || len == 0)
		return -1;
	dtds = malloc(len * sizeof(void *));
	if (!dtds)
		return -1;

	values = malloc(len * sizeof(void *));
	if (!values) {
		free(dtds);
		return -1;
	}

	for (p = seq, i = 0; i < len; i++, p = p->next) {
		uuid_t *uuid = p->data;
		if (uuid)
			switch (uuid->type) {
			case SDP_UUID16:
				dtds[i] = &uuid16;
				values[i] = &uuid->value.uuid16;
				break;
			case SDP_UUID32:
				dtds[i] = &uuid32;
				values[i] = &uuid->value.uuid32;
				break;
			case SDP_UUID128:
				dtds[i] = &uuid128;
				values[i] = &uuid->value.uuid128;
				break;
			default:
				status = -1;
				break;
			}
		else {
			status = -1;
			break;
		}
	}
	if (status == 0) {
		sdp_data_t *data = sdp_seq_alloc(dtds, values, len);
		sdp_attr_replace(rec, aid, data);
		sdp_pattern_add_uuidseq(rec, seq);
	}
	free(dtds);
	free(values);
	return status;
}

int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq)
{
	sdp_lang_attr_t *lang;
	sdp_data_t *sdpdata, *curr_data;

	*langSeq = NULL;
	sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST);
	if (sdpdata == NULL) {
		errno = ENODATA;
		return -1;
	}
	curr_data = sdpdata->val.dataseq;
	while (curr_data) {
		sdp_data_t *pCode = curr_data;
		sdp_data_t *pEncoding = pCode->next;
		sdp_data_t *pOffset = pEncoding->next;
		if (pEncoding && pOffset) {
			lang = malloc(sizeof(sdp_lang_attr_t));
			if (!lang) {
				sdp_list_free(*langSeq, free);
				*langSeq = NULL;
				return -1;
			}
			lang->code_ISO639 = pCode->val.uint16;
			lang->encoding = pEncoding->val.uint16;
			lang->base_offset = pOffset->val.uint16;
			SDPDBG("code_ISO639 :  0x%02x\n", lang->code_ISO639);
			SDPDBG("encoding :     0x%02x\n", lang->encoding);
			SDPDBG("base_offfset : 0x%02x\n", lang->base_offset);
			*langSeq = sdp_list_append(*langSeq, lang);
		}
		curr_data = pOffset->next;
	}
	return 0;
}

int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq)
{
	sdp_profile_desc_t *profDesc;
	sdp_data_t *sdpdata, *seq;

	*profDescSeq = NULL;
	sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST);
	if (!sdpdata || !sdpdata->val.dataseq) {
		errno = ENODATA;
		return -1;
	}
	for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) {
		uuid_t *uuid = NULL;
		uint16_t version = 0x100;

		if (SDP_IS_UUID(seq->dtd)) {
			uuid = &seq->val.uuid;
		} else {
			sdp_data_t *puuid = seq->val.dataseq;
			sdp_data_t *pVnum = seq->val.dataseq->next;
			if (puuid && pVnum) {
				uuid = &puuid->val.uuid;
				version = pVnum->val.uint16;
			}
		}

		if (uuid != NULL) {
			profDesc = malloc(sizeof(sdp_profile_desc_t));
			if (!profDesc) {
				sdp_list_free(*profDescSeq, free);
				*profDescSeq = NULL;
				return -1;
			}
			profDesc->uuid = *uuid;
			profDesc->version = version;
#ifdef SDP_DEBUG
			sdp_uuid_print(&profDesc->uuid);
			SDPDBG("Vnum : 0x%04x\n", profDesc->version);
#endif
			*profDescSeq = sdp_list_append(*profDescSeq, profDesc);
		}
	}
	return 0;
}

int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16)
{
	sdp_data_t *d, *curr;

	*u16 = NULL;
	d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST);
	if (d == NULL) {
		errno = ENODATA;
		return -1;
	}
	for (curr = d->val.dataseq; curr; curr = curr->next)
		*u16 = sdp_list_append(*u16, &curr->val.uint16);
	return 0;
}

/* flexible extraction of basic attributes - Jean II */
/* How do we expect caller to extract predefined data sequences? */
int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value)
{
	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);

	if (sdpdata)
		/* Verify that it is what the caller expects */
		if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 ||
		sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 ||
		sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 ||
		sdpdata->dtd == SDP_INT32) {
			*value = sdpdata->val.uint32;
			return 0;
		}
	errno = EINVAL;
	return -1;
}

int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value,
								int valuelen)
{
	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
	if (sdpdata)
		/* Verify that it is what the caller expects */
		if (sdpdata->dtd == SDP_TEXT_STR8 ||
				sdpdata->dtd == SDP_TEXT_STR16 ||
				sdpdata->dtd == SDP_TEXT_STR32)
			if ((int) strlen(sdpdata->val.str) < valuelen) {
				strcpy(value, sdpdata->val.str);
				return 0;
			}
	errno = EINVAL;
	return -1;
}

#define get_basic_attr(attrID, pAttrValue, fieldName)		\
	sdp_data_t *data = sdp_data_get(rec, attrID);		\
	if (data) {						\
		*pAttrValue = data->val.fieldName;		\
		return 0;					\
	}							\
	errno = EINVAL;						\
	return -1;

int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid)
{
	get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);
}

int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid)
{
	get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);
}

int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState)
{
	get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);
}

int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail)
{
	get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);
}

int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo)
{
	get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);
}

int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState)
{
	get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);
}

/*
 * NOTE that none of the setXXX() functions below will
 * actually update the SDP server, unless the
 * {register, update}sdp_record_t() function is invoked.
 */

int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd,
							const void *value)
{
	sdp_data_t *d = sdp_data_alloc(dtd, value);
	if (d) {
		sdp_attr_replace(rec, attr, d);
		return 0;
	}
	return -1;
}

static int sdp_attr_add_new_with_length(sdp_record_t *rec,
	uint16_t attr, uint8_t dtd, const void *value, uint32_t len)
{
	sdp_data_t *d;

	d = sdp_data_alloc_with_length(dtd, value, len);
	if (!d)
		return -1;

	sdp_attr_replace(rec, attr, d);

	return 0;
}

/*
 * Set the information attributes of the service
 * pointed to by rec. The attributes are
 * service name, description and provider name
 */
void sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov,
							const char *desc)
{
	if (name)
		sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY,
							SDP_TEXT_STR8, name);
	if (prov)
		sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY,
							SDP_TEXT_STR8, prov);
	if (desc)
		sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY,
							SDP_TEXT_STR8, desc);
}

static sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto)
{
	sdp_data_t *seq = NULL;
	void *dtds[10], *values[10];
	void **seqDTDs, **seqs;
	int i, seqlen;
	sdp_list_t *p;

	seqlen = sdp_list_len(proto);
	seqDTDs = malloc(seqlen * sizeof(void *));
	if (!seqDTDs)
		return NULL;

	seqs = malloc(seqlen * sizeof(void *));
	if (!seqs) {
		free(seqDTDs);
		return NULL;
	}

	for (i = 0, p = proto; p; p = p->next, i++) {
		sdp_list_t *elt = p->data;
		sdp_data_t *s;
		uuid_t *uuid = NULL;
		unsigned int pslen = 0;
		for (; elt && pslen < ARRAY_SIZE(dtds); elt = elt->next, pslen++) {
			sdp_data_t *d = elt->data;
			dtds[pslen] = &d->dtd;
			switch (d->dtd) {
			case SDP_UUID16:
				uuid = (uuid_t *) d;
				values[pslen] = &uuid->value.uuid16;
				break;
			case SDP_UUID32:
				uuid = (uuid_t *) d;
				values[pslen] = &uuid->value.uuid32;
				break;
			case SDP_UUID128:
				uuid = (uuid_t *) d;
				values[pslen] = &uuid->value.uuid128;
				break;
			case SDP_UINT8:
				values[pslen] = &d->val.uint8;
				break;
			case SDP_UINT16:
				values[pslen] = &d->val.uint16;
				break;
			case SDP_SEQ8:
			case SDP_SEQ16:
			case SDP_SEQ32:
				values[pslen] = d;
				break;
			/* FIXME: more */
			}
		}
		s = sdp_seq_alloc(dtds, values, pslen);
		if (s) {
			seqDTDs[i] = &s->dtd;
			seqs[i] = s;
			if (uuid)
				sdp_pattern_add_uuid(rec, uuid);
		}
	}
	seq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
	free(seqDTDs);
	free(seqs);
	return seq;
}

/*
 * sets the access protocols of the service specified
 * to the value specified in "access_proto"
 *
 * Note that if there are alternate mechanisms by
 * which the service is accessed, then they should
 * be specified as sequences
 *
 * Using a value of NULL for accessProtocols has
 * effect of removing this attribute (if previously set)
 *
 * This function replaces the existing sdp_access_proto_t
 * structure (if any) with the new one specified.
 *
 * returns 0 if successful or -1 if there is a failure.
 */
int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
{
	const sdp_list_t *p;
	sdp_data_t *protos = NULL;

	for (p = ap; p; p = p->next) {
		sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
		protos = sdp_seq_append(protos, seq);
	}

	sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos);

	return 0;
}

int sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
{
	const sdp_list_t *p;
	sdp_data_t *protos = NULL;

	for (p = ap; p; p = p->next) {
		sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
		protos = sdp_seq_append(protos, seq);
	}

	sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST,
			protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL);

	return 0;
}

/*
 * set the "LanguageBase" attributes of the service record
 * record to the value specified in "langAttrList".
 *
 * "langAttrList" is a linked list of "sdp_lang_attr_t"
 * objects, one for each language in which user visible
 * attributes are present in the service record.
 *
 * Using a value of NULL for langAttrList has
 * effect of removing this attribute (if previously set)
 *
 * This function replaces the exisiting sdp_lang_attr_t
 * structure (if any) with the new one specified.
 *
 * returns 0 if successful or -1 if there is a failure.
 */
int sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq)
{
	uint8_t uint16 = SDP_UINT16;
	int status = 0, i = 0, seqlen = sdp_list_len(seq);
	void **dtds, **values;
	const sdp_list_t *p;

	dtds = malloc(3 * seqlen * sizeof(void *));
	if (!dtds)
		return -1;

	values = malloc(3 * seqlen * sizeof(void *));
	if (!values) {
		free(dtds);
		return -1;
	}

	for (p = seq; p; p = p->next) {
		sdp_lang_attr_t *lang = p->data;
		if (!lang) {
			status = -1;
			break;
		}
		dtds[i] = &uint16;
		values[i] = &lang->code_ISO639;
		i++;
		dtds[i] = &uint16;
		values[i] = &lang->encoding;
		i++;
		dtds[i] = &uint16;
		values[i] = &lang->base_offset;
		i++;
	}
	if (status == 0) {
		sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen);
		sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq);
	}
	free(dtds);
	free(values);
	return status;
}

/*
 * set the "ServiceID" attribute of the service.
 *
 * This is the UUID of the service.
 *
 * returns 0 if successful or -1 if there is a failure.
 */
void sdp_set_service_id(sdp_record_t *rec, uuid_t uuid)
{
	switch (uuid.type) {
	case SDP_UUID16:
		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16,
							&uuid.value.uuid16);
		break;
	case SDP_UUID32:
		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32,
							&uuid.value.uuid32);
		break;
	case SDP_UUID128:
		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128,
							&uuid.value.uuid128);
		break;
	}
	sdp_pattern_add_uuid(rec, &uuid);
}

/*
 * set the GroupID attribute of the service record defining a group.
 *
 * This is the UUID of the group.
 *
 * returns 0 if successful or -1 if there is a failure.
 */
void sdp_set_group_id(sdp_record_t *rec, uuid_t uuid)
{
	switch (uuid.type) {
	case SDP_UUID16:
		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16,
							&uuid.value.uuid16);
		break;
	case SDP_UUID32:
		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32,
							&uuid.value.uuid32);
		break;
	case SDP_UUID128:
		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128,
							&uuid.value.uuid128);
		break;
	}
	sdp_pattern_add_uuid(rec, &uuid);
}

/*
 * set the ProfileDescriptorList attribute of the service record
 * pointed to by record to the value specified in "profileDesc".
 *
 * Each element in the list is an object of type
 * sdp_profile_desc_t which is a definition of the
 * Bluetooth profile that this service conforms to.
 *
 * Using a value of NULL for profileDesc has
 * effect of removing this attribute (if previously set)
 *
 * This function replaces the exisiting ProfileDescriptorList
 * structure (if any) with the new one specified.
 *
 * returns 0 if successful or -1 if there is a failure.
 */
int sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles)
{
	int status = 0;
	uint8_t uuid16 = SDP_UUID16;
	uint8_t uuid32 = SDP_UUID32;
	uint8_t uuid128 = SDP_UUID128;
	uint8_t uint16 = SDP_UINT16;
	int i = 0, seqlen = sdp_list_len(profiles);
	void **seqDTDs, **seqs;
	const sdp_list_t *p;

	seqDTDs = malloc(seqlen * sizeof(void *));
	if (!seqDTDs)
		return -1;

	seqs = malloc(seqlen * sizeof(void *));
	if (!seqs) {
		free(seqDTDs);
		return -1;
	}

	for (p = profiles; p; p = p->next) {
		sdp_data_t *seq;
		void *dtds[2], *values[2];
		sdp_profile_desc_t *profile = p->data;
		if (!profile) {
			status = -1;
			break;
		}
		switch (profile->uuid.type) {
		case SDP_UUID16:
			dtds[0] = &uuid16;
			values[0] = &profile->uuid.value.uuid16;
			break;
		case SDP_UUID32:
			dtds[0] = &uuid32;
			values[0] = &profile->uuid.value.uuid32;
			break;
		case SDP_UUID128:
			dtds[0] = &uuid128;
			values[0] = &profile->uuid.value.uuid128;
			break;
		default:
			status = -1;
			break;
		}
		dtds[1] = &uint16;
		values[1] = &profile->version;
		seq = sdp_seq_alloc(dtds, values, 2);
		if (seq) {
			seqDTDs[i] = &seq->dtd;
			seqs[i] = seq;
			sdp_pattern_add_uuid(rec, &profile->uuid);
		}
		i++;
	}
	if (status == 0) {
		sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
		sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq);
	}
	free(seqDTDs);
	free(seqs);
	return status;
}

/*
 * sets various URL attributes of the service
 * pointed to by record. The URL include
 *
 * client: a URL to the client's
 *   platform specific (WinCE, PalmOS) executable
 *   code that can be used to access this service.
 *
 * doc: a URL pointing to service documentation
 *
 * icon: a URL to an icon that can be used to represent
 *   this service.
 *
 * Note that you need to pass NULL for any URLs
 * that you don't want to set or remove
 */
void sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc,
							const char *icon)
{
	sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client);
	sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc);
	sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon);
}

uuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val)
{
	memset(u, 0, sizeof(uuid_t));
	u->type = SDP_UUID16;
	u->value.uuid16 = val;
	return u;
}

uuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val)
{
	memset(u, 0, sizeof(uuid_t));
	u->type = SDP_UUID32;
	u->value.uuid32 = val;
	return u;
}

uuid_t *sdp_uuid128_create(uuid_t *u, const void *val)
{
	memset(u, 0, sizeof(uuid_t));
	u->type = SDP_UUID128;
	memcpy(&u->value.uuid128, val, sizeof(uint128_t));
	return u;
}

/*
 * UUID comparison function
 * returns 0 if uuidValue1 == uuidValue2 else -1
 */
int sdp_uuid_cmp(const void *p1, const void *p2)
{
	uuid_t *u1 = sdp_uuid_to_uuid128(p1);
	uuid_t *u2 = sdp_uuid_to_uuid128(p2);
	int ret;

	ret = sdp_uuid128_cmp(u1, u2);

	bt_free(u1);
	bt_free(u2);

	return ret;
}

/*
 * UUID comparison function
 * returns 0 if uuidValue1 == uuidValue2 else -1
 */
int sdp_uuid16_cmp(const void *p1, const void *p2)
{
	const uuid_t *u1 = p1;
	const uuid_t *u2 = p2;
	return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t));
}

/*
 * UUID comparison function
 * returns 0 if uuidValue1 == uuidValue2 else -1
 */
int sdp_uuid128_cmp(const void *p1, const void *p2)
{
	const uuid_t *u1 = p1;
	const uuid_t *u2 = p2;
	return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t));
}

/*
 * 128 to 16 bit and 32 to 16 bit UUID conversion functions
 * yet to be implemented. Note that the input is in NBO in
 * both 32 and 128 bit UUIDs and conversion is needed
 */
void sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16)
{
	/*
	 * We have a 16 bit value, which needs to be added to
	 * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base
	 */
	unsigned short data1;

	/* allocate a 128bit UUID and init to the Bluetooth base UUID */
	uuid128->value.uuid128 = bluetooth_base_uuid;
	uuid128->type = SDP_UUID128;

	/* extract bytes 2 and 3 of 128bit BT base UUID */
	memcpy(&data1, &bluetooth_base_uuid.data[2], 2);

	/* add the given UUID (16 bits) */
	data1 += htons(uuid16->value.uuid16);

	/* set bytes 2 and 3 of the 128 bit value */
	memcpy(&uuid128->value.uuid128.data[2], &data1, 2);
}

void sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32)
{
	/*
	 * We have a 32 bit value, which needs to be added to
	 * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base
	 */
	unsigned int data0;

	/* allocate a 128bit UUID and init to the Bluetooth base UUID */
	uuid128->value.uuid128 = bluetooth_base_uuid;
	uuid128->type = SDP_UUID128;

	/* extract first 4 bytes */
	memcpy(&data0, &bluetooth_base_uuid.data[0], 4);

	/* add the given UUID (32bits) */
	data0 += htonl(uuid32->value.uuid32);

	/* set the 4 bytes of the 128 bit value */
	memcpy(&uuid128->value.uuid128.data[0], &data0, 4);
}

uuid_t *sdp_uuid_to_uuid128(const uuid_t *uuid)
{
	uuid_t *uuid128 = bt_malloc(sizeof(uuid_t));

	if (!uuid128)
		return NULL;

	memset(uuid128, 0, sizeof(uuid_t));
	switch (uuid->type) {
	case SDP_UUID128:
		*uuid128 = *uuid;
		break;
	case SDP_UUID32:
		sdp_uuid32_to_uuid128(uuid128, uuid);
		break;
	case SDP_UUID16:
		sdp_uuid16_to_uuid128(uuid128, uuid);
		break;
	}
	return uuid128;
}

/*
 * converts a 128-bit uuid to a 16/32-bit one if possible
 * returns true if uuid contains a 16/32-bit UUID at exit
 */
int sdp_uuid128_to_uuid(uuid_t *uuid)
{
	uint128_t *b = &bluetooth_base_uuid;
	uint128_t *u = &uuid->value.uuid128;
	uint32_t data;
	unsigned int i;

	if (uuid->type != SDP_UUID128)
		return 1;

	for (i = 4; i < sizeof(b->data); i++)
		if (b->data[i] != u->data[i])
			return 0;

	memcpy(&data, u->data, 4);
	data = htonl(data);
	if (data <= 0xffff) {
		uuid->type = SDP_UUID16;
		uuid->value.uuid16 = (uint16_t) data;
	} else {
		uuid->type = SDP_UUID32;
		uuid->value.uuid32 = data;
	}
	return 1;
}

/*
 * convert a UUID to the 16-bit short-form
 */
int sdp_uuid_to_proto(uuid_t *uuid)
{
	uuid_t u = *uuid;
	if (sdp_uuid128_to_uuid(&u)) {
		switch (u.type) {
		case SDP_UUID16:
			return u.value.uuid16;
		case SDP_UUID32:
			return u.value.uuid32;
		}
	}
	return 0;
}

/*
 * This function appends data to the PDU buffer "dst" from source "src".
 * The data length is also computed and set.
 * Should the PDU length exceed 2^8, then sequence type is
 * set accordingly and the data is memmove()'d.
 */
void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len)
{
	uint8_t *p = dst->data;
	uint8_t dtd = *p;

	SDPDBG("Append src size: %d\n", len);
	SDPDBG("Append dst size: %d\n", dst->data_size);
	SDPDBG("Dst buffer size: %d\n", dst->buf_size);
	if (dst->data_size == 0 && dtd == 0) {
		/* create initial sequence */
		*p = SDP_SEQ8;
		p += sizeof(uint8_t);
		dst->data_size += sizeof(uint8_t);
		/* reserve space for sequence size */
		p += sizeof(uint8_t);
		dst->data_size += sizeof(uint8_t);
	}

	memcpy(dst->data + dst->data_size, data, len);
	dst->data_size += len;

	dtd = *(uint8_t *) dst->data;
	if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) {
		short offset = sizeof(uint8_t) + sizeof(uint8_t);
		memmove(dst->data + offset + 1, dst->data + offset,
						dst->data_size - offset);
		p = dst->data;
		*p = SDP_SEQ16;
		p += sizeof(uint8_t);
		dst->data_size += 1;
	}
	p = dst->data;
	dtd = *(uint8_t *) p;
	p += sizeof(uint8_t);
	switch (dtd) {
	case SDP_SEQ8:
		*(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t);
		break;
	case SDP_SEQ16:
		bt_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *) p);
		break;
	case SDP_SEQ32:
		bt_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *) p);
		break;
	}
}

void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d)
{
	sdp_buf_t append;

	memset(&append, 0, sizeof(sdp_buf_t));
	sdp_gen_buffer(&append, d);
	append.data = malloc(append.buf_size);
	if (!append.data)
		return;

	sdp_set_attrid(&append, d->attrId);
	sdp_gen_pdu(&append, d);
	sdp_append_to_buf(pdu, append.data, append.data_size);
	free(append.data);
}

/*
 * Registers an sdp record.
 *
 * It is incorrect to call this method on a record that
 * has been already registered with the server.
 *
 * Returns zero on success, otherwise -1 (and sets errno).
 */
int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, uint8_t *data, uint32_t size, uint8_t flags, uint32_t *handle)
{
	uint8_t *req, *rsp, *p;
	uint32_t reqsize, rspsize;
	sdp_pdu_hdr_t *reqhdr, *rsphdr;
	int status;

	SDPDBG("");

	if (!session->local) {
		errno = EREMOTE;
		return -1;
	}
	req = malloc(SDP_REQ_BUFFER_SIZE);
	rsp = malloc(SDP_RSP_BUFFER_SIZE);
	if (req == NULL || rsp == NULL) {
		status = -1;
		errno = ENOMEM;
		goto end;
	}

	reqhdr = (sdp_pdu_hdr_t *)req;
	reqhdr->pdu_id = SDP_SVC_REGISTER_REQ;
	reqhdr->tid    = htons(sdp_gen_tid(session));
	reqsize = sizeof(sdp_pdu_hdr_t) + 1;
	p = req + sizeof(sdp_pdu_hdr_t);

	if (bacmp(device, BDADDR_ANY)) {
		*p++ = flags | SDP_DEVICE_RECORD;
		bacpy((bdaddr_t *) p, device);
		p += sizeof(bdaddr_t);
		reqsize += sizeof(bdaddr_t);
	} else
		*p++ = flags;

	memcpy(p, data, size);
	reqsize += size;
	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));

	status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize);
	if (status < 0)
		goto end;

	if (rspsize < sizeof(sdp_pdu_hdr_t)) {
		SDPERR("Unexpected end of packet");
		errno = EPROTO;
		status = -1;
		goto end;
	}

	rsphdr = (sdp_pdu_hdr_t *) rsp;
	p = rsp + sizeof(sdp_pdu_hdr_t);

	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
		/* Invalid service record */
		errno = EINVAL;
		status = -1;
	} else if (rsphdr->pdu_id != SDP_SVC_REGISTER_RSP) {
		errno = EPROTO;
		status = -1;
	} else {
		if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint32_t)) {
			SDPERR("Unexpected end of packet");
			errno = EPROTO;
			status = -1;
			goto end;
		}
		if (handle)
			*handle  = ntohl(bt_get_unaligned((uint32_t *) p));
	}

end:
	free(req);
	free(rsp);

	return status;
}

int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags)
{
	sdp_buf_t pdu;
	uint32_t handle;
	int err;

	SDPDBG("");

	if (rec->handle && rec->handle != 0xffffffff) {
		uint32_t handle = rec->handle;
		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
	}

	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
		errno = ENOMEM;
		return -1;
	}

	err = sdp_device_record_register_binary(session, device,
				pdu.data, pdu.data_size, flags, &handle);

	free(pdu.data);

	if (err == 0) {
		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
		rec->handle = handle;
		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
	}

	return err;
}

int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags)
{
	return sdp_device_record_register(session, BDADDR_ANY, rec, flags);
}

/*
 * unregister a service record
 */
int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle)
{
	uint8_t *reqbuf, *rspbuf, *p;
	uint32_t reqsize = 0, rspsize = 0;
	sdp_pdu_hdr_t *reqhdr, *rsphdr;
	int status;

	SDPDBG("");

	if (handle == SDP_SERVER_RECORD_HANDLE) {
		errno = EINVAL;
		return -1;
	}

	if (!session->local) {
		errno = EREMOTE;
		return -1;
	}

	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
	if (!reqbuf || !rspbuf) {
		errno = ENOMEM;
		status = -1;
		goto end;
	}
	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
	reqhdr->pdu_id = SDP_SVC_REMOVE_REQ;
	reqhdr->tid    = htons(sdp_gen_tid(session));

	p = reqbuf + sizeof(sdp_pdu_hdr_t);
	reqsize = sizeof(sdp_pdu_hdr_t);
	bt_put_unaligned(htonl(handle), (uint32_t *) p);
	reqsize += sizeof(uint32_t);

	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
	if (status < 0)
		goto end;

	if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
		SDPERR("Unexpected end of packet");
		errno = EPROTO;
		status = -1;
		goto end;
	}

	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
	p = rspbuf + sizeof(sdp_pdu_hdr_t);
	status = bt_get_unaligned((uint16_t *) p);

	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
		/* For this case the status always is invalid record handle */
		errno = EINVAL;
		status = -1;
	} else if (rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) {
		errno = EPROTO;
		status = -1;
	}
end:
	free(reqbuf);
	free(rspbuf);

	return status;
}

int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec)
{
	int err;

	err = sdp_device_record_unregister_binary(session, device, rec->handle);
	if (err == 0)
		sdp_record_free(rec);

	return err;
}

int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec)
{
	return sdp_device_record_unregister(session, BDADDR_ANY, rec);
}

/*
 * modify an existing service record
 */
int sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size)
{
	return -1;
}

int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec)
{
	uint8_t *reqbuf, *rspbuf, *p;
	uint32_t reqsize, rspsize;
	sdp_pdu_hdr_t *reqhdr, *rsphdr;
	uint32_t handle;
	sdp_buf_t pdu;
	int status;

	SDPDBG("");

	handle = rec->handle;

	if (handle == SDP_SERVER_RECORD_HANDLE) {
		errno = EINVAL;
		return -1;
	}
	if (!session->local) {
		errno = EREMOTE;
		return -1;
	}
	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
	if (!reqbuf || !rspbuf) {
		errno = ENOMEM;
		status = -1;
		goto end;
	}
	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
	reqhdr->pdu_id = SDP_SVC_UPDATE_REQ;
	reqhdr->tid    = htons(sdp_gen_tid(session));

	p = reqbuf + sizeof(sdp_pdu_hdr_t);
	reqsize = sizeof(sdp_pdu_hdr_t);

	bt_put_unaligned(htonl(handle), (uint32_t *) p);
	reqsize += sizeof(uint32_t);
	p += sizeof(uint32_t);

	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
		errno = ENOMEM;
		status = -1;
		goto end;
	}
	memcpy(p, pdu.data, pdu.data_size);
	reqsize += pdu.data_size;
	free(pdu.data);

	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
	if (status < 0)
		goto end;

	if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
		SDPERR("Unexpected end of packet");
		errno = EPROTO;
		status = -1;
		goto end;
	}

	SDPDBG("Send req status : %d\n", status);

	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
	p = rspbuf + sizeof(sdp_pdu_hdr_t);
	status = bt_get_unaligned((uint16_t *) p);

	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
		/* The status can be invalid sintax or invalid record handle */
		errno = EINVAL;
		status = -1;
	} else if (rsphdr->pdu_id != SDP_SVC_UPDATE_RSP) {
		errno = EPROTO;
		status = -1;
	}
end:
	free(reqbuf);
	free(rspbuf);
	return status;
}

int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec)
{
	return sdp_device_record_update(session, BDADDR_ANY, rec);
}

sdp_record_t *sdp_record_alloc()
{
	sdp_record_t *rec = malloc(sizeof(sdp_record_t));

	if (!rec)
		return NULL;

	memset(rec, 0, sizeof(sdp_record_t));
	rec->handle = 0xffffffff;
	return rec;
}

/*
 * Free the contents of a service record
 */
void sdp_record_free(sdp_record_t *rec)
{
	sdp_list_free(rec->attrlist, (sdp_free_func_t) sdp_data_free);
	sdp_list_free(rec->pattern, free);
	free(rec);
}

void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid)
{
	uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid);

	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
	SDPDBG("Trying to add : 0x%lx\n", (unsigned long) uuid128);

	if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL)
		rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp);
	else
		bt_free(uuid128);

	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
}

void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq)
{
	for (; seq; seq = seq->next) {
		uuid_t *uuid = (uuid_t *)seq->data;
		sdp_pattern_add_uuid(rec, uuid);
	}
}

/*
 * Extract a sequence of service record handles from a PDU buffer
 * and add the entries to a sdp_list_t. Note that the service record
 * handles are not in "data element sequence" form, but just like
 * an array of service handles
 */
static void extract_record_handle_seq(uint8_t *pdu, int bufsize, sdp_list_t **seq, int count, unsigned int *scanned)
{
	sdp_list_t *pSeq = *seq;
	uint8_t *pdata = pdu;
	int n;

	for (n = 0; n < count; n++) {
		uint32_t *pSvcRec;
		if (bufsize < (int) sizeof(uint32_t)) {
			SDPERR("Unexpected end of packet");
			break;
		}
		pSvcRec = malloc(sizeof(uint32_t));
		if (!pSvcRec)
			break;
		*pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata));
		pSeq = sdp_list_append(pSeq, pSvcRec);
		pdata += sizeof(uint32_t);
		*scanned += sizeof(uint32_t);
		bufsize -= sizeof(uint32_t);
	}
	*seq = pSeq;
}
/*
 * Generate the attribute sequence pdu form
 * from sdp_list_t elements. Return length of attr seq
 */
static int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd)
{
	sdp_data_t *dataseq;
	void **types, **values;
	sdp_buf_t buf;
	int i, seqlen = sdp_list_len(seq);

	// Fill up the value and the dtd arrays
	SDPDBG("");

	SDPDBG("Seq length : %d\n", seqlen);

	types = malloc(seqlen * sizeof(void *));
	if (!types)
		return -ENOMEM;

	values = malloc(seqlen * sizeof(void *));
	if (!values) {
		free(types);
		return -ENOMEM;
	}

	for (i = 0; i < seqlen; i++) {
		void *data = seq->data;
		types[i] = &dtd;
		if (SDP_IS_UUID(dtd))
			data = &((uuid_t *)data)->value;
		values[i] = data;
		seq = seq->next;
	}

	dataseq = sdp_seq_alloc(types, values, seqlen);
	if (!dataseq) {
		free(types);
		free(values);
		return -ENOMEM;
	}

	memset(&buf, 0, sizeof(sdp_buf_t));
	sdp_gen_buffer(&buf, dataseq);
	buf.data = malloc(buf.buf_size);

	if (!buf.data) {
		sdp_data_free(dataseq);
		free(types);
		free(values);
		return -ENOMEM;
	}

	SDPDBG("Data Seq : 0x%p\n", seq);
	seqlen = sdp_gen_pdu(&buf, dataseq);
	SDPDBG("Copying : %d\n", buf.data_size);
	memcpy(dst, buf.data, buf.data_size);

	sdp_data_free(dataseq);

	free(types);
	free(values);
	free(buf.data);
	return seqlen;
}

static int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq)
{
	uuid_t *uuid = seq->data;
	return gen_dataseq_pdu(dst, seq, uuid->type);
}

static int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType)
{
	return gen_dataseq_pdu(dst, seq, dataType);
}

typedef struct {
	uint8_t length;
	unsigned char data[16];
} __attribute__ ((packed)) sdp_cstate_t;

static int copy_cstate(uint8_t *pdata, int pdata_len, const sdp_cstate_t *cstate)
{
	if (cstate) {
		uint8_t len = cstate->length;
		if (len >= pdata_len) {
			SDPERR("Continuation state size exceeds internal buffer");
			len = pdata_len - 1;
		}
		*pdata++ = len;
		memcpy(pdata, cstate->data, len);
		return len + 1;
	}
	*pdata = 0;
	return 1;
}

/*
 * This is a service search request.
 *
 * INPUT :
 *
 *   sdp_list_t *search
 *     Singly linked list containing elements of the search
 *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
 *     of the service to be searched
 *
 *   uint16_t max_rec_num
 *      A 16 bit integer which tells the service, the maximum
 *      entries that the client can handle in the response. The
 *      server is obliged not to return > max_rec_num entries
 *
 * OUTPUT :
 *
 *   int return value
 *     0:
 *       The request completed successfully. This does not
 *       mean the requested services were found
 *     -1:
 *       On any failure and sets errno
 *
 *   sdp_list_t **rsp_list
 *     This variable is set on a successful return if there are
 *     non-zero service handles. It is a singly linked list of
 *     service record handles (uint16_t)
 */
int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search,
			uint16_t max_rec_num, sdp_list_t **rsp)
{
	int status = 0;
	uint32_t reqsize = 0, _reqsize;
	uint32_t rspsize = 0, rsplen;
	int seqlen = 0;
	int total_rec_count, rec_count;
	unsigned scanned, pdata_len;
	uint8_t *pdata, *_pdata;
	uint8_t *reqbuf, *rspbuf;
	sdp_pdu_hdr_t *reqhdr, *rsphdr;
	sdp_cstate_t *cstate = NULL;

	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
	if (!reqbuf || !rspbuf) {
		errno = ENOMEM;
		status = -1;
		goto end;
	}
	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
	reqsize = sizeof(sdp_pdu_hdr_t);

	// add service class IDs for search
	seqlen = gen_searchseq_pdu(pdata, search);

	SDPDBG("Data seq added : %d\n", seqlen);

	// set the length and increment the pointer
	reqsize += seqlen;
	pdata += seqlen;

	// specify the maximum svc rec count that client expects
	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
	reqsize += sizeof(uint16_t);
	pdata += sizeof(uint16_t);

	_reqsize = reqsize;
	_pdata   = pdata;
	*rsp = NULL;

	do {
		// Add continuation state or NULL (first time)
		reqsize = _reqsize + copy_cstate(_pdata,
					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);

		// Set the request header's param length
		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));

		reqhdr->tid  = htons(sdp_gen_tid(session));
		/*
		 * Send the request, wait for response and if
		 * no error, set the appropriate values and return
		 */
		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
		if (status < 0)
			goto end;

		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
			SDPERR("Unexpected end of packet");
			status = -1;
			goto end;
		}

		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
		rsplen = ntohs(rsphdr->plen);

		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
			status = -1;
			goto end;
		}
		scanned = 0;
		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);

		if (pdata_len < sizeof(uint16_t) + sizeof(uint16_t)) {
			SDPERR("Unexpected end of packet");
			status = -1;
			goto end;
		}

		// net service record match count
		total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
		pdata += sizeof(uint16_t);
		scanned += sizeof(uint16_t);
		pdata_len -= sizeof(uint16_t);
		rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
		pdata += sizeof(uint16_t);
		scanned += sizeof(uint16_t);
		pdata_len -= sizeof(uint16_t);

		SDPDBG("Total svc count: %d\n", total_rec_count);
		SDPDBG("Current svc count: %d\n", rec_count);
		SDPDBG("ResponseLength: %d\n", rsplen);

		if (!rec_count) {
			status = -1;
			goto end;
		}
		extract_record_handle_seq(pdata, pdata_len, rsp, rec_count, &scanned);
		SDPDBG("BytesScanned : %d\n", scanned);

		if (rsplen > scanned) {
			uint8_t cstate_len;

			if (rspsize < sizeof(sdp_pdu_hdr_t) + scanned + sizeof(uint8_t)) {
				SDPERR("Unexpected end of packet: continuation state data missing");
				status = -1;
				goto end;
			}

			pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned;
			cstate_len = *(uint8_t *) pdata;
			if (cstate_len > 0) {
				cstate = (sdp_cstate_t *)pdata;
				SDPDBG("Cont state length: %d\n", cstate_len);
			} else
				cstate = NULL;
		}
	} while (cstate);

end:
	free(reqbuf);
	free(rspbuf);

	return status;
}

/*
 * This is a service attribute request.
 *
 * INPUT :
 *
 *   uint32_t handle
 *     The handle of the service for which the attribute(s) are
 *     requested
 *
 *   sdp_attrreq_type_t reqtype
 *     Attribute identifiers are 16 bit unsigned integers specified
 *     in one of 2 ways described below :
 *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
 *        They are the actual attribute identifiers in ascending order
 *
 *     SDP_ATTR_REQ_RANGE - 32bit identifier range
 *        The high-order 16bits is the start of range
 *        the low-order 16bits are the end of range
 *        0x0000 to 0xFFFF gets all attributes
 *
 *   sdp_list_t *attrid
 *     Singly linked list containing attribute identifiers desired.
 *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
 *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
 *
 * OUTPUT :
 *   return sdp_record_t *
 *     0:
 *       On any error and sets errno
 *     !0:
 *	 The service record
 */
sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle,
			sdp_attrreq_type_t reqtype, const sdp_list_t *attrids)
{
	uint32_t reqsize = 0, _reqsize;
	uint32_t rspsize = 0, rsp_count;
	int attr_list_len = 0;
	int seqlen = 0;
	unsigned int pdata_len;
	uint8_t *pdata, *_pdata;
	uint8_t *reqbuf, *rspbuf;
	sdp_pdu_hdr_t *reqhdr, *rsphdr;
	sdp_cstate_t *cstate = NULL;
	uint8_t cstate_len = 0;
	sdp_buf_t rsp_concat_buf;
	sdp_record_t *rec = 0;

	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
		errno = EINVAL;
		return NULL;
	}

	memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));

	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
	if (!reqbuf || !rspbuf) {
		errno = ENOMEM;
		goto end;
	}
	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;

	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
	reqsize = sizeof(sdp_pdu_hdr_t);

	// add the service record handle
	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
	reqsize += sizeof(uint32_t);
	pdata += sizeof(uint32_t);

	// specify the response limit
	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
	reqsize += sizeof(uint16_t);
	pdata += sizeof(uint16_t);

	// get attr seq PDU form
	seqlen = gen_attridseq_pdu(pdata, attrids,
		reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
	if (seqlen == -1) {
		errno = EINVAL;
		goto end;
	}
	pdata += seqlen;
	reqsize += seqlen;
	SDPDBG("Attr list length : %d\n", seqlen);

	// save before Continuation State
	_pdata = pdata;
	_reqsize = reqsize;

	do {
		int status;

		// add NULL continuation state
		reqsize = _reqsize + copy_cstate(_pdata,
					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);

		// set the request header's param length
		reqhdr->tid  = htons(sdp_gen_tid(session));
		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));

		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
		if (status < 0)
			goto end;

		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
			SDPERR("Unexpected end of packet");
			goto end;
		}

		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
			SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id);
			goto end;
		}
		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);

		if (pdata_len < sizeof(uint16_t)) {
			SDPERR("Unexpected end of packet");
			goto end;
		}

		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
		attr_list_len += rsp_count;
		pdata += sizeof(uint16_t);
		pdata_len -= sizeof(uint16_t);

		// if continuation state set need to re-issue request before parsing
		if (pdata_len < rsp_count + sizeof(uint8_t)) {
			SDPERR("Unexpected end of packet: continuation state data missing");
			goto end;
		}
		cstate_len = *(uint8_t *) (pdata + rsp_count);

		SDPDBG("Response id : %d\n", rsphdr->pdu_id);
		SDPDBG("Attrlist byte count : %d\n", rsp_count);
		SDPDBG("sdp_cstate_t length : %d\n", cstate_len);

		/*
		 * a split response: concatenate intermediate responses
		 * and the last one (which has cstate_len == 0)
		 */
		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
			uint8_t *targetPtr = NULL;

			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;

			// build concatenated response buffer
			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
			memcpy(targetPtr, pdata, rsp_count);
			rsp_concat_buf.data_size += rsp_count;
		}
	} while (cstate);

	if (attr_list_len > 0) {
		int scanned = 0;
		if (rsp_concat_buf.data_size != 0) {
			pdata = rsp_concat_buf.data;
			pdata_len = rsp_concat_buf.data_size;
		}
		rec = sdp_extract_pdu(pdata, pdata_len, &scanned);
	}

end:
	free(reqbuf);
	free(rsp_concat_buf.data);
	free(rspbuf);
	return rec;
}

/*
 * SDP transaction structure for asynchronous search
 */
struct sdp_transaction {
	sdp_callback_t *cb;	/* called when the transaction finishes */
	void *udata;		/* client user data */
	uint8_t *reqbuf;	/* pointer to request PDU */
	sdp_buf_t rsp_concat_buf;
	uint32_t reqsize;	/* without cstate */
	int err;		/* ZERO if success or the errno if failed */
};

/*
 * Creates a new sdp session for asynchronous search
 * INPUT:
 *  int sk
 *     non-blocking L2CAP socket
 *
 * RETURN:
 *  sdp_session_t *
 *  NULL - On memory allocation failure
 */
sdp_session_t *sdp_create(int sk, uint32_t flags)
{
	sdp_session_t *session;
	struct sdp_transaction *t;

	session = malloc(sizeof(sdp_session_t));
	if (!session) {
		errno = ENOMEM;
		return NULL;
	}
	memset(session, 0, sizeof(*session));

	session->flags = flags;
	session->sock = sk;

	t = malloc(sizeof(struct sdp_transaction));
	if (!t) {
		errno = ENOMEM;
		free(session);
		return NULL;
	}
	memset(t, 0, sizeof(*t));

	session->priv = t;

	return session;
}

/*
 * Sets the callback function/user data used to notify the application
 * that the asynchronous transaction finished. This function must be
 * called before request an asynchronous search.
 *
 * INPUT:
 *  sdp_session_t *session
 *	Current sdp session to be handled
 *  sdp_callback_t *cb
 *      callback to be called when the transaction finishes
 *  void *udata
 *      user data passed to callback
 * RETURN:
 * 	 0 - Success
 * 	-1 - Failure
 */
int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata)
{
	struct sdp_transaction *t;

	if (!session || !session->priv)
		return -1;

	t = session->priv;
	t->cb = func;
	t->udata = udata;

	return 0;
}

/*
 * This function starts an asynchronous service search request.
 * The incomming and outgoing data are stored in the transaction structure
 * buffers. When there is incomming data the sdp_process function must be
 * called to get the data and handle the continuation state.
 *
 * INPUT :
 *  sdp_session_t *session
 *     Current sdp session to be handled
 *
 *   sdp_list_t *search
 *     Singly linked list containing elements of the search
 *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
 *     of the service to be searched
 *
 *   uint16_t max_rec_num
 *      A 16 bit integer which tells the service, the maximum
 *      entries that the client can handle in the response. The
 *      server is obliged not to return > max_rec_num entries
 *
 * OUTPUT :
 *
 *   int return value
 * 	0  - if the request has been sent properly
 * 	-1 - On any failure and sets errno
 */

int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num)
{
	struct sdp_transaction *t;
	sdp_pdu_hdr_t *reqhdr;
	uint8_t *pdata;
	int cstate_len, seqlen = 0;

	if (!session || !session->priv)
		return -1;

	t = session->priv;

	/* clean possible allocated buffer */
	free(t->rsp_concat_buf.data);
	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));

	if (!t->reqbuf) {
		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
		if (!t->reqbuf) {
			t->err = ENOMEM;
			goto end;
		}
	}
	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);

	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
	reqhdr->tid = htons(sdp_gen_tid(session));
	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;

	// generate PDU
	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
	t->reqsize = sizeof(sdp_pdu_hdr_t);

	// add service class IDs for search
	seqlen = gen_searchseq_pdu(pdata, search);

	SDPDBG("Data seq added : %d\n", seqlen);

	// now set the length and increment the pointer
	t->reqsize += seqlen;
	pdata += seqlen;

	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
	t->reqsize += sizeof(uint16_t);
	pdata += sizeof(uint16_t);

	// set the request header's param length
	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));

	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
		SDPERR("Error sendind data:%s", strerror(errno));
		t->err = errno;
		goto end;
	}

	return 0;
end:

	free(t->reqbuf);
	t->reqbuf = NULL;

	return -1;
}

/*
 * This function starts an asynchronous service attribute request.
 * The incomming and outgoing data are stored in the transaction structure
 * buffers. When there is incomming data the sdp_process function must be
 * called to get the data and handle the continuation state.
 *
 * INPUT :
 *  sdp_session_t *session
 *	Current sdp session to be handled
 *
 *   uint32_t handle
 *     The handle of the service for which the attribute(s) are
 *     requested
 *
 *   sdp_attrreq_type_t reqtype
 *     Attribute identifiers are 16 bit unsigned integers specified
 *     in one of 2 ways described below :
 *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
 *        They are the actual attribute identifiers in ascending order
 *
 *     SDP_ATTR_REQ_RANGE - 32bit identifier range
 *        The high-order 16bits is the start of range
 *        the low-order 16bits are the end of range
 *        0x0000 to 0xFFFF gets all attributes
 *
 *   sdp_list_t *attrid_list
 *     Singly linked list containing attribute identifiers desired.
 *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
 *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
 *
 * OUTPUT :
 *   int return value
 * 	 0 - if the request has been sent properly
 * 	-1 - On any failure and sets errno
 */

int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
{
	struct sdp_transaction *t;
	sdp_pdu_hdr_t *reqhdr;
	uint8_t *pdata;
	int cstate_len, seqlen = 0;

	if (!session || !session->priv)
		return -1;

	t = session->priv;

	/* clean possible allocated buffer */
	free(t->rsp_concat_buf.data);
	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));

	if (!t->reqbuf) {
		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
		if (!t->reqbuf) {
			t->err = ENOMEM;
			goto end;
		}
	}
	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);

	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
	reqhdr->tid = htons(sdp_gen_tid(session));
	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;

	// generate PDU
	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
	t->reqsize = sizeof(sdp_pdu_hdr_t);

	// add the service record handle
	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
	t->reqsize += sizeof(uint32_t);
	pdata += sizeof(uint32_t);

	// specify the response limit
	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
	t->reqsize += sizeof(uint16_t);
	pdata += sizeof(uint16_t);

	// get attr seq PDU form
	seqlen = gen_attridseq_pdu(pdata, attrid_list,
			reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
	if (seqlen == -1) {
		t->err = EINVAL;
		goto end;
	}

	// now set the length and increment the pointer
	t->reqsize += seqlen;
	pdata += seqlen;
	SDPDBG("Attr list length : %d\n", seqlen);

	// set the request header's param length
	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));

	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
		SDPERR("Error sendind data:%s", strerror(errno));
		t->err = errno;
		goto end;
	}

	return 0;
end:

	free(t->reqbuf);
	t->reqbuf = NULL;

	return -1;
}

/*
 * This function starts an asynchronous service search attributes.
 * It is a service search request combined with attribute request. The incomming
 * and outgoing data are stored in the transaction structure buffers. When there
 * is incomming data the sdp_process function must be called to get the data
 * and handle the continuation state.
 *
 * INPUT:
 *  sdp_session_t *session
 *	Current sdp session to be handled
 *
 *   sdp_list_t *search
 *     Singly linked list containing elements of the search
 *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
 *     of the service to be searched
 *
 *   AttributeSpecification attrSpec
 *     Attribute identifiers are 16 bit unsigned integers specified
 *     in one of 2 ways described below :
 *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
 *        They are the actual attribute identifiers in ascending order
 *
 *     SDP_ATTR_REQ_RANGE - 32bit identifier range
 *        The high-order 16bits is the start of range
 *        the low-order 16bits are the end of range
 *        0x0000 to 0xFFFF gets all attributes
 *
 *   sdp_list_t *attrid_list
 *     Singly linked list containing attribute identifiers desired.
 *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
 *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
 *

 * RETURN:
 * 	 0 - if the request has been sent properly
 * 	-1 - On any failure
 */
int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
{
	struct sdp_transaction *t;
	sdp_pdu_hdr_t *reqhdr;
	uint8_t *pdata;
	int cstate_len, seqlen = 0;

	if (!session || !session->priv)
		return -1;

	t = session->priv;

	/* clean possible allocated buffer */
	free(t->rsp_concat_buf.data);
	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));

	if (!t->reqbuf) {
		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
		if (!t->reqbuf) {
			t->err = ENOMEM;
			goto end;
		}
	}
	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);

	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
	reqhdr->tid = htons(sdp_gen_tid(session));
	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;

	// generate PDU
	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
	t->reqsize = sizeof(sdp_pdu_hdr_t);

	// add service class IDs for search
	seqlen = gen_searchseq_pdu(pdata, search);

	SDPDBG("Data seq added : %d\n", seqlen);

	// now set the length and increment the pointer
	t->reqsize += seqlen;
	pdata += seqlen;

	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
	t->reqsize += sizeof(uint16_t);
	pdata += sizeof(uint16_t);

	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);

	// get attr seq PDU form
	seqlen = gen_attridseq_pdu(pdata, attrid_list,
			reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
	if (seqlen == -1) {
		t->err = EINVAL;
		goto end;
	}

	pdata += seqlen;
	SDPDBG("Attr list length : %d\n", seqlen);
	t->reqsize += seqlen;

	// set the request header's param length
	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));

	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
		SDPERR("Error sendind data:%s", strerror(errno));
		t->err = errno;
		goto end;
	}

	return 0;
end:

	free(t->reqbuf);
	t->reqbuf = NULL;

	return -1;
}

/*
 * Function used to get the error reason after sdp_callback_t function has been called
 * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1.
 * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly
 * is not safe because multiple transactions can be triggered.
 * This function must be used with asynchronous sdp functions only.
 *
 * INPUT:
 *  sdp_session_t *session
 *	Current sdp session to be handled
 * RETURN:
 * 	 0 = No error in the current transaction
 * 	-1 - if the session is invalid
 * 	positive value - the errno value
 *
 */
int sdp_get_error(sdp_session_t *session)
{
	struct sdp_transaction *t;

	if (!session || !session->priv) {
		SDPERR("Invalid session");
		return -1;
	}

	t = session->priv;

	return t->err;
}

/*
 * Receive the incomming SDP PDU. This function must be called when there is data
 * available to be read. On continuation state, the original request (with a new
 * transaction ID) and the continuation state data will be appended in the initial PDU.
 * If an error happens or the transaction finishes the callback function will be called.
 *
 * INPUT:
 *  sdp_session_t *session
 *	Current sdp session to be handled
 * RETURN:
 * 	0  - if the transaction is on continuation state
 * 	-1 - On any failure or the transaction finished
 */
int sdp_process(sdp_session_t *session)
{
	struct sdp_transaction *t;
	sdp_pdu_hdr_t *reqhdr, *rsphdr;
	sdp_cstate_t *pcstate;
	uint8_t *pdata, *rspbuf, *targetPtr;
	int rsp_count, err = -1;
	size_t size = 0;
	int n, plen;
	uint16_t status = 0xffff;
	uint8_t pdu_id = 0x00;

	if (!session || !session->priv) {
		SDPERR("Invalid session");
		return -1;
	}

	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
	if (!rspbuf) {
		SDPERR("Response buffer alloc failure:%s (%d)",
				strerror(errno), errno);
		return -1;
	}

	memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE);

	t = session->priv;
	reqhdr = (sdp_pdu_hdr_t *)t->reqbuf;
	rsphdr = (sdp_pdu_hdr_t *)rspbuf;

	pdata = rspbuf + sizeof(sdp_pdu_hdr_t);

	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
	if (n < 0) {
		SDPERR("Read response:%s (%d)", strerror(errno), errno);
		t->err = errno;
		goto end;
	}

	if (n == 0 || reqhdr->tid != rsphdr->tid ||
		(n != (ntohs(rsphdr->plen) + (int) sizeof(sdp_pdu_hdr_t)))) {
		t->err = EPROTO;
		SDPERR("Protocol error.");
		goto end;
	}

	pdu_id = rsphdr->pdu_id;
	switch (rsphdr->pdu_id) {
	uint8_t *ssr_pdata;
	uint16_t tsrc, csrc;
	case SDP_SVC_SEARCH_RSP:
		/*
		 * TSRC: Total Service Record Count (2 bytes)
		 * CSRC: Current Service Record Count (2 bytes)
		 */
		ssr_pdata = pdata;
		tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));
		ssr_pdata += sizeof(uint16_t);
		csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));

		/* csrc should never be larger than tsrc */
		if (csrc > tsrc) {
			t->err = EPROTO;
			SDPERR("Protocol error: wrong current service record count value.");
			goto end;
		}

		SDPDBG("Total svc count: %d\n", tsrc);
		SDPDBG("Current svc count: %d\n", csrc);

		/* parameter length without continuation state */
		plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4;

		if (t->rsp_concat_buf.data_size == 0) {
			/* first fragment */
			rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
		} else {
			/* point to the first csrc */
			uint16_t *pcsrc = (uint16_t *) (t->rsp_concat_buf.data + 2);

			/* FIXME: update the interface later. csrc doesn't need be passed to clients */

			pdata += sizeof(uint16_t); /* point to csrc */

			/* the first csrc contains the sum of partial csrc responses */
			*pcsrc += bt_get_unaligned((uint16_t *) pdata);

			pdata += sizeof(uint16_t); /* point to the first handle */
			rsp_count = csrc * 4;
		}
		status = 0x0000;
		break;
	case SDP_SVC_ATTR_RSP:
	case SDP_SVC_SEARCH_ATTR_RSP:
		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
		SDPDBG("Attrlist byte count : %d\n", rsp_count);

		/*
		 * Number of bytes in the AttributeLists parameter(without
		 * continuation state) + AttributeListsByteCount field size.
		 */
		plen = sizeof(uint16_t) + rsp_count;

		pdata += sizeof(uint16_t); // points to attribute list
		status = 0x0000;
		break;
	case SDP_ERROR_RSP:
		status = ntohs(bt_get_unaligned((uint16_t *) pdata));
		size = ntohs(rsphdr->plen);

		/* error code + error info */
		plen = size;
		goto end;
	default:
		t->err = EPROTO;
		SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id);
		goto end;
	}

	pcstate = (sdp_cstate_t *) (pdata + rsp_count);

	SDPDBG("Cstate length : %d\n", pcstate->length);

	/*
	 * Check out of bound. Continuation state must have at least
	 * 1 byte: ZERO to indicate that it is not a partial response.
	 */
	if ((n - (int) sizeof(sdp_pdu_hdr_t))  != (plen + pcstate->length + 1)) {
		t->err = EPROTO;
		SDPERR("Protocol error: wrong PDU size.");
		status = 0xffff;
		goto end;
	}

	/*
	 * This is a split response, need to concatenate intermediate
	 * responses and the last one which will have cstate length == 0
	 */
	t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count);
	targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size;
	t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count;
	memcpy(targetPtr, pdata, rsp_count);
	t->rsp_concat_buf.data_size += rsp_count;

	if (pcstate->length > 0) {
		int reqsize, cstate_len;

		reqhdr->tid = htons(sdp_gen_tid(session));

		// add continuation state
		cstate_len = copy_cstate(t->reqbuf + t->reqsize,
				SDP_REQ_BUFFER_SIZE - t->reqsize, pcstate);

		reqsize = t->reqsize + cstate_len;

		// set the request header's param length
		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));

		if (sdp_send_req(session, t->reqbuf, reqsize) < 0) {
			SDPERR("Error sendind data:%s(%d)", strerror(errno), errno);
			status = 0xffff;
			t->err = errno;
			goto end;
		}
		err = 0;
	}

end:
	if (err) {
		if (t->rsp_concat_buf.data_size != 0) {
			pdata = t->rsp_concat_buf.data;
			size = t->rsp_concat_buf.data_size;
		}
		if (t->cb)
			t->cb(pdu_id, status, pdata, size, t->udata);
	}

	free(rspbuf);

	return err;
}

/*
 * This is a service search request combined with the service
 * attribute request. First a service class match is done and
 * for matching service, requested attributes are extracted
 *
 * INPUT :
 *
 *   sdp_list_t *search
 *     Singly linked list containing elements of the search
 *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
 *     of the service to be searched
 *
 *   AttributeSpecification attrSpec
 *     Attribute identifiers are 16 bit unsigned integers specified
 *     in one of 2 ways described below :
 *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
 *        They are the actual attribute identifiers in ascending order
 *
 *     SDP_ATTR_REQ_RANGE - 32bit identifier range
 *        The high-order 16bits is the start of range
 *        the low-order 16bits are the end of range
 *        0x0000 to 0xFFFF gets all attributes
 *
 *   sdp_list_t *attrids
 *     Singly linked list containing attribute identifiers desired.
 *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
 *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
 *
 * OUTPUT :
 *   int return value
 *     0:
 *       The request completed successfully. This does not
 *       mean the requested services were found
 *     -1:
 *       On any error and sets errno
 *
 *   sdp_list_t **rsp
 *     This variable is set on a successful return to point to
 *     service(s) found. Each element of this list is of type
 *     sdp_record_t* (of the services which matched the search list)
 */
int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrids, sdp_list_t **rsp)
{
	int status = 0;
	uint32_t reqsize = 0, _reqsize;
	uint32_t rspsize = 0;
	int seqlen = 0, attr_list_len = 0;
	int rsp_count = 0, cstate_len = 0;
	unsigned int pdata_len;
	uint8_t *pdata, *_pdata;
	uint8_t *reqbuf, *rspbuf;
	sdp_pdu_hdr_t *reqhdr, *rsphdr;
	uint8_t dataType;
	sdp_list_t *rec_list = NULL;
	sdp_buf_t rsp_concat_buf;
	sdp_cstate_t *cstate = NULL;

	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
		errno = EINVAL;
		return -1;
	}

	memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));

	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
	if (!reqbuf || !rspbuf) {
		errno = ENOMEM;
		status = -1;
		goto end;
	}

	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;

	// generate PDU
	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
	reqsize = sizeof(sdp_pdu_hdr_t);

	// add service class IDs for search
	seqlen = gen_searchseq_pdu(pdata, search);

	SDPDBG("Data seq added : %d\n", seqlen);

	/* now set the length and increment the pointer */
	reqsize += seqlen;
	pdata += seqlen;

	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
	reqsize += sizeof(uint16_t);
	pdata += sizeof(uint16_t);

	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);

	/* get attr seq PDU form */
	seqlen = gen_attridseq_pdu(pdata, attrids,
		reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
	if (seqlen == -1) {
		status = EINVAL;
		goto end;
	}
	pdata += seqlen;
	SDPDBG("Attr list length : %d\n", seqlen);
	reqsize += seqlen;
	*rsp = 0;

	/* save before Continuation State */
	_pdata = pdata;
	_reqsize = reqsize;

	do {
		reqhdr->tid = htons(sdp_gen_tid(session));

		/* add continuation state (can be null) */
		reqsize = _reqsize + copy_cstate(_pdata,
					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);

		/* set the request header's param length */
		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
			SDPERR("Unexpected end of packet");
			status = -1;
			goto end;
		}

		if (status < 0) {
			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
			goto end;
		}

		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
			status = -1;
			goto end;
		}

		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);

		if (pdata_len < sizeof(uint16_t)) {
			SDPERR("Unexpected end of packet");
			status = -1;
			goto end;
		}

		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
		attr_list_len += rsp_count;
		pdata += sizeof(uint16_t);	// pdata points to attribute list
		pdata_len -= sizeof(uint16_t);

		if (pdata_len < rsp_count + sizeof(uint8_t)) {
			SDPERR("Unexpected end of packet: continuation state data missing");
			status = -1;
			goto end;
		}

		cstate_len = *(uint8_t *) (pdata + rsp_count);

		SDPDBG("Attrlist byte count : %d\n", attr_list_len);
		SDPDBG("Response byte count : %d\n", rsp_count);
		SDPDBG("Cstate length : %d\n", cstate_len);
		/*
		 * This is a split response, need to concatenate intermediate
		 * responses and the last one which will have cstate_len == 0
		 */
		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
			uint8_t *targetPtr = NULL;

			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;

			/* build concatenated response buffer */
			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
			memcpy(targetPtr, pdata, rsp_count);
			rsp_concat_buf.data_size += rsp_count;
		}
	} while (cstate);

	if (attr_list_len > 0) {
		int scanned = 0;

		if (rsp_concat_buf.data_size != 0) {
			pdata = rsp_concat_buf.data;
			pdata_len = rsp_concat_buf.data_size;
		}

		/*
		 * Response is a sequence of sequence(s) for one or
		 * more data element sequence(s) representing services
		 * for which attributes are returned
		 */
		scanned = sdp_extract_seqtype(pdata, pdata_len, &dataType, &seqlen);

		SDPDBG("Bytes scanned : %d\n", scanned);
		SDPDBG("Seq length : %d\n", seqlen);

		if (scanned && seqlen) {
			pdata += scanned;
			pdata_len -= scanned;
			do {
				int recsize = 0;
				sdp_record_t *rec = sdp_extract_pdu(pdata, pdata_len, &recsize);
				if (rec == NULL) {
					SDPERR("SVC REC is null\n");
					status = -1;
					goto end;
				}
				if (!recsize) {
					sdp_record_free(rec);
					break;
				}
				scanned += recsize;
				pdata += recsize;
				pdata_len -= recsize;

				SDPDBG("Loc seq length : %d\n", recsize);
				SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle);
				SDPDBG("Bytes scanned : %d\n", scanned);
				SDPDBG("Attrlist byte count : %d\n", attr_list_len);
				rec_list = sdp_list_append(rec_list, rec);
			} while (scanned < attr_list_len && pdata_len > 0);

			SDPDBG("Successful scan of service attr lists\n");
			*rsp = rec_list;
		}
	}
end:
	free(rsp_concat_buf.data);
	free(reqbuf);
	free(rspbuf);
	return status;
}

/*
 * Find devices in the piconet.
 */
int sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found)
{
	int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0);
	if (n < 0) {
		SDPERR("Inquiry failed:%s", strerror(errno));
		return -1;
	}
	*found = n;
	return 0;
}

int sdp_close(sdp_session_t *session)
{
	struct sdp_transaction *t;
	int ret;

	if (!session)
		return -1;

	ret = close(session->sock);

	t = session->priv;

	if (t) {
		free(t->reqbuf);

		free(t->rsp_concat_buf.data);

		free(t);
	}
	free(session);
	return ret;
}

static inline int sdp_is_local(const bdaddr_t *device)
{
	return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0;
}

static int sdp_connect_local(sdp_session_t *session)
{
	struct sockaddr_un sa;

	session->sock = socket(PF_UNIX, SOCK_STREAM, 0);
	if (session->sock < 0)
		return -1;
	session->local = 1;

	sa.sun_family = AF_UNIX;
	strcpy(sa.sun_path, SDP_UNIX_PATH);

	return connect(session->sock, (struct sockaddr *) &sa, sizeof(sa));
}

static int sdp_connect_l2cap(const bdaddr_t *src,
		const bdaddr_t *dst, sdp_session_t *session)
{
	uint32_t flags = session->flags;
	struct sockaddr_l2 sa;
	int sk;

	session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	if (session->sock < 0)
		return -1;
	session->local = 0;

	sk = session->sock;

	if (flags & SDP_NON_BLOCKING) {
		long arg = fcntl(sk, F_GETFL, 0);
		fcntl(sk, F_SETFL, arg | O_NONBLOCK);
	}

	memset(&sa, 0, sizeof(sa));

	sa.l2_family = AF_BLUETOOTH;
	sa.l2_psm = 0;

	if (bacmp(src, BDADDR_ANY)) {
		sa.l2_bdaddr = *src;
		if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0)
			return -1;
	}

	if (flags & SDP_WAIT_ON_CLOSE) {
		struct linger l = { .l_onoff = 1, .l_linger = 1 };
		setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
	}

	sa.l2_psm = htobs(SDP_PSM);
	sa.l2_bdaddr = *dst;

	do {
		int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa));
		if (!ret)
			return 0;
		if (ret < 0 && (flags & SDP_NON_BLOCKING) &&
				(errno == EAGAIN || errno == EINPROGRESS))
			return 0;
	} while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY));

	return -1;
}

sdp_session_t *sdp_connect(const bdaddr_t *src,
		const bdaddr_t *dst, uint32_t flags)
{
	sdp_session_t *session;
	int err;

	if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) {
		errno = EINVAL;
		return NULL;
	}

	session = sdp_create(-1, flags);
	if (!session)
		return NULL;

	if (sdp_is_local(dst)) {
		if (sdp_connect_local(session) < 0)
			goto fail;
	} else {
		if (sdp_connect_l2cap(src, dst, session) < 0)
			goto fail;
	}

	return session;

fail:
	err = errno;
	if (session->sock >= 0)
		close(session->sock);
	free(session->priv);
	free(session);
	errno = err;

	return NULL;
}

int sdp_get_socket(const sdp_session_t *session)
{
	return session->sock;
}

uint16_t sdp_gen_tid(sdp_session_t *session)
{
	return session->tid++;
}

/*
 * Set the supported features
 */
int sdp_set_supp_feat(sdp_record_t *rec, const sdp_list_t *sf)
{
	const sdp_list_t *p, *r;
	sdp_data_t *feat, *seq_feat;
	int seqlen, i;
	void **seqDTDs, **seqVals;

	seqlen = sdp_list_len(sf);
	seqDTDs = malloc(seqlen * sizeof(void *));
	if (!seqDTDs)
		return -1;
	seqVals = malloc(seqlen * sizeof(void *));
	if (!seqVals) {
		free(seqDTDs);
		return -1;
	}

	for (p = sf, i = 0; p; p = p->next, i++) {
		int plen, j;
		void **dtds, **vals;
		int *lengths;

		plen = sdp_list_len(p->data);
		dtds = malloc(plen * sizeof(void *));
		if (!dtds)
			goto fail;
		vals = malloc(plen * sizeof(void *));
		if (!vals) {
			free(dtds);
			goto fail;
		}
		lengths = malloc(plen * sizeof(int *));
		if (!lengths) {
			free(dtds);
			free(vals);
			goto fail;
		}
		for (r = p->data, j = 0; r; r = r->next, j++) {
			sdp_data_t *data = (sdp_data_t*)r->data;
			dtds[j] = &data->dtd;
			switch (data->dtd) {
			case SDP_URL_STR8:
			case SDP_URL_STR16:
			case SDP_TEXT_STR8:
			case SDP_TEXT_STR16:
				vals[j] = data->val.str;
				lengths[j] = data->unitSize - sizeof(uint8_t);
				break;
			case SDP_ALT8:
			case SDP_ALT16:
			case SDP_ALT32:
			case SDP_SEQ8:
			case SDP_SEQ16:
			case SDP_SEQ32:
				vals[j] = data->val.dataseq;
				lengths[j] = 0;
				break;
			default:
				vals[j] = &data->val;
				lengths[j] = 0;
				break;
			}
		}
		feat = sdp_seq_alloc_with_length(dtds, vals, lengths, plen);
		free(dtds);
		free(vals);
		free(lengths);
		if (!feat)
			goto fail;
		seqDTDs[i] = &feat->dtd;
		seqVals[i] = feat;
	}
	seq_feat = sdp_seq_alloc(seqDTDs, seqVals, seqlen);
	if (!seq_feat)
		goto fail;
	sdp_attr_replace(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST, seq_feat);

	free(seqVals);
	free(seqDTDs);
	return 0;

fail:
	free(seqVals);
	free(seqDTDs);
	return -1;
}

/*
 * Get the supported features
 * If an error occurred -1 is returned and errno is set
 */
int sdp_get_supp_feat(const sdp_record_t *rec, sdp_list_t **seqp)
{
	sdp_data_t *sdpdata, *d;
	sdp_list_t *tseq;
	tseq = NULL;

	sdpdata = sdp_data_get(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST);

	if (!sdpdata || sdpdata->dtd < SDP_SEQ8 || sdpdata->dtd > SDP_SEQ32)
		return sdp_get_uuidseq_attr(rec,
					SDP_ATTR_SUPPORTED_FEATURES_LIST, seqp);

	for (d = sdpdata->val.dataseq; d; d = d->next) {
		sdp_data_t *dd;
		sdp_list_t *subseq;

		if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
			goto fail;

		subseq = NULL;

		for (dd = d->val.dataseq; dd; dd = dd->next) {
			sdp_data_t *data;
			void *val;
			int length;

			switch (dd->dtd) {
			case SDP_URL_STR8:
			case SDP_URL_STR16:
			case SDP_TEXT_STR8:
			case SDP_TEXT_STR16:
				val = dd->val.str;
				length = dd->unitSize - sizeof(uint8_t);
				break;
			case SDP_UINT8:
			case SDP_UINT16:
				val = &dd->val;
				length = 0;
				break;
			default:
				goto fail;
			}

			data = sdp_data_alloc_with_length(dd->dtd, val, length);
			if (data)
				subseq = sdp_list_append(subseq, data);
		}
		tseq = sdp_list_append(tseq, subseq);
	}
	*seqp = tseq;
	return 0;

fail:
	while (tseq) {
		sdp_list_t * next;

		next = tseq->next;
		sdp_list_free(tseq, free);
		tseq = next;
	}
	errno = EINVAL;
	return -1;
}

