/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2001-2002  Nokia Corporation
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2002-2008  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/un.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>

#include <netinet/in.h>

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

#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

/* 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,		"Handfree 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"		},
	{ MDP_SVCLASS_ID,			"MDP"				},
	{ MDP_SOURCE_SVCLASS_ID,		"MDP Source"			},
	{ MDP_SINK_SVCLASS_ID,			"MDP 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, str2);
		break;
	case SDP_UUID32:
		str2 = string_lookup(message, uuid->value.uuid32);
		snprintf(str, n, str2);
		break;
	case SDP_UUID128:
		str2 = string_lookup_uuid(message, uuid);
		snprintf(str, n, 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 = *(uint8_t *) ptr++;

	switch (dtd) {
	case SDP_SEQ8:
	case SDP_ALT8:
	case SDP_TEXT_STR8:
	case SDP_URL_STR8:
		*(uint8_t *)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;
	}
}

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

	*p++ = dtd;
	buf->data_size += sizeof(uint8_t);

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

	return buf->data_size - orig;
}

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)
		n += sdp_gen_pdu(buf, d);

	return n;
}

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);

	switch (dtd) {
	case SDP_DATA_NIL:
		break;
	case SDP_UINT8:
		src = &d->val.uint8;
		data_size = sizeof(uint8_t);
		break;
	case SDP_UINT16:
		u16 = htons(d->val.uint16);
		src = (unsigned char *) &u16;
		data_size = sizeof(uint16_t);
		break;
	case SDP_UINT32:
		u32 = htonl(d->val.uint32);
		src = (unsigned char *) &u32;
		data_size = sizeof(uint32_t);
		break;
	case SDP_UINT64:
		u64 = hton64(d->val.uint64);
		src = (unsigned char *) &u64;
		data_size = sizeof(uint64_t);
		break;
	case SDP_UINT128:
		hton128(&d->val.uint128, &u128);
		src = (unsigned char *) &u128;
		data_size = sizeof(uint128_t);
		break;
	case SDP_INT8:
	case SDP_BOOL:
		src = (unsigned char *) &d->val.int8;
		data_size = sizeof(int8_t);
		break;
	case SDP_INT16:
		u16 = htons(d->val.int16);
		src = (unsigned char *) &u16;
		data_size = sizeof(int16_t);
		break;
	case SDP_INT32:
		u32 = htonl(d->val.int32);
		src = (unsigned char *) &u32;
		data_size = sizeof(int32_t);
		break;
	case SDP_INT64:
		u64 = hton64(d->val.int64);
		src = (unsigned char *) &u64;
		data_size = sizeof(int64_t);
		break;
	case SDP_INT128:
		hton128(&d->val.int128, &u128);
		src = (unsigned char *) &u128;
		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:
		src = (unsigned char *) d->val.str;
		data_size = d->unitSize - sizeof(uint8_t);
		sdp_set_seq_len(seqp, data_size);
		break;
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
		is_seq = 1;
		data_size = get_data_size(buf, d);
		sdp_set_seq_len(seqp, data_size);
		break;
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
		is_alt = 1;
		data_size = get_data_size(buf, d);
		sdp_set_seq_len(seqp, data_size);
		break;
	case SDP_UUID16:
		u16 = htons(d->val.uuid.value.uuid16);
		src = (unsigned char *) &u16;
		data_size = sizeof(uint16_t);
		break;
	case SDP_UUID32:
		u32 = htonl(d->val.uuid.value.uuid32);
		src = (unsigned char *) &u32;
		data_size = sizeof(uint32_t);
		break;
	case SDP_UUID128:
		src = (unsigned char *) &d->val.uuid.value.uuid128;
		data_size = sizeof(uint128_t);
		break;
	default:
		break;
	}

	if (!is_seq && !is_alt) {
		if (src && buf) {
			memcpy(buf->data + buf->data_size, src, data_size);
			buf->data_size += data_size;
		} else if (dtd != SDP_DATA_NIL)
			SDPDBG("Gen PDU : Cant copy from NULL 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);
}

int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf)
{
	buf->data = malloc(SDP_PDU_CHUNK_SIZE);
	if (!buf->data)
		return -ENOMEM;

	buf->buf_size = SDP_PDU_CHUNK_SIZE;
	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);
}

static sdp_data_t *extract_int(const void *p, int *len)
{
	sdp_data_t *d = malloc(sizeof(sdp_data_t));

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

	switch (d->dtd) {
	case SDP_DATA_NIL:
		break;
	case SDP_BOOL:
	case SDP_INT8:
	case SDP_UINT8:
		*len += sizeof(uint8_t);
		d->val.uint8 = *(uint8_t *) p;
		break;
	case SDP_INT16:
	case SDP_UINT16:
		*len += sizeof(uint16_t);
		d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p));
		break;
	case SDP_INT32:
	case SDP_UINT32:
		*len += sizeof(uint32_t);
		d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p));
		break;
	case SDP_INT64:
	case SDP_UINT64:
		*len += sizeof(uint64_t);
		d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p));
		break;
	case SDP_INT128:
	case SDP_UINT128:
		*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 *len, sdp_record_t *rec)
{
	sdp_data_t *d = malloc(sizeof(sdp_data_t));

	SDPDBG("Extracting UUID");
	memset(d, 0, sizeof(sdp_data_t));
	if (sdp_uuid_extract(p, &d->val.uuid, len) < 0) {
		free(d);
		return NULL;
	}
	d->dtd = *(uint8_t *) 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 *len)
{
	char *s;
	int n;
	sdp_data_t *d = malloc(sizeof(sdp_data_t));

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

	switch (d->dtd) {
	case SDP_TEXT_STR8:
	case SDP_URL_STR8:
		n = *(uint8_t *) p;
		p += sizeof(uint8_t);
		*len += sizeof(uint8_t) + n;
		break;
	case SDP_TEXT_STR16:
	case SDP_URL_STR16:
		n = ntohs(bt_get_unaligned((uint16_t *) p));
		p += sizeof(uint16_t);
		*len += sizeof(uint16_t) + n;
		break;
	default:
		SDPERR("Sizeof text string > UINT16_MAX\n");
		free(d);
		return 0;
	}

	s = malloc(n + 1);
	memset(s, 0, n + 1);
	memcpy(s, p, n);

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

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

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

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

	if (*len == 0)
		return d;

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

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

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

	*len += n;
	return d;
}

sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec)
{
	sdp_data_t *elem;
	int n = 0;
	uint8_t 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, &n);
		break;
	case SDP_UUID16:
	case SDP_UUID32:
	case SDP_UUID128:
		elem = extract_uuid(p, &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, &n);
		break;
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
		elem = extract_seq(p, &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 *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, &dtd, &seqlen);
	p += *scanned;
	rec->attrlist = NULL;
	while (extracted < seqlen) {
		int n = sizeof(uint8_t), attrlen = 0;
		sdp_data_t *data = NULL;

		SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, extracted);
		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, &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;
		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;
}

#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 (sdp_data_t *)p->data;
	}
	return NULL;
}

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

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

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;
}

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 0;

	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 0;
	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 = (sdp_data_t *) 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 = (sdp_data_t *) 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)
				goto fail;

			u = malloc(sizeof(uuid_t));
			memset(u, 0, sizeof(uuid_t));
			*u = d->val.uuid;
			*seqp = sdp_list_append(*seqp, u);
		}
		return 0;
	}
fail:
	sdp_list_free(*seqp, free);
	errno = EINVAL;
	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 = (void **)malloc(len * sizeof(void *));
	values = (void **)malloc(len * sizeof(void *));
	for (p = seq, i = 0; i < len; i++, p = p->next) {
		uuid_t *uuid = (uuid_t *)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 (pCode && pEncoding && pOffset) {
			lang = malloc(sizeof(sdp_lang_attr_t));
			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));
			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 (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;
}

/*
 * 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, (void *)name);
	if (prov)
		sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY, SDP_TEXT_STR8, (void *)prov);
	if (desc)
		sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY, SDP_TEXT_STR8, (void *)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 = (void **)malloc(seqlen * sizeof(void *));
	seqs = (void **)malloc(seqlen * sizeof(void *));
	for (i = 0, p = proto; p; p = p->next, i++) {
		sdp_list_t *elt = (sdp_list_t *)p->data;
		sdp_data_t *s;
		int pslen = 0;
		for (; elt && pslen < sizeof(dtds); elt = elt->next, pslen++) {
			sdp_data_t *d = (sdp_data_t *)elt->data;
			dtds[pslen] = &d->dtd;
			switch (d->dtd) {
			case SDP_UUID16:
				values[pslen] = &((uuid_t *)d)->value.uuid16;
				break;
			case SDP_UUID32:
				values[pslen] = &((uuid_t *)d)->value.uuid32;
				break;
			case SDP_UUID128:
				values[pslen] = &((uuid_t *)d)->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;
		}
	}
	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, (sdp_list_t *) 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, (sdp_list_t *) 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 = (void **)malloc(3 * seqlen * sizeof(void *));
	void **values = (void **)malloc(3 * seqlen * sizeof(void *));
	const sdp_list_t *p;

	for (p = seq; p; p = p->next) {
		sdp_lang_attr_t *lang = (sdp_lang_attr_t *)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 = (void **)malloc(seqlen * sizeof(void *));
	void **seqs = (void **)malloc(seqlen * sizeof(void *));
	const sdp_list_t *p;

	for (p = profiles; p; p = p->next) {
		sdp_data_t *seq;
		void *dtds[2], *values[2];
		sdp_profile_desc_t *profile = (sdp_profile_desc_t *)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);
}

/*
 * The code in this function is executed only once per
 * thread. We compute the actual bit value of the Bluetooth
 * base UUID which is a string defined in bt_std_values.h 
 * and is assumed to be of the standard form with "-" separators.
 *
 * The algorithm however converts the string to 4 unsigned longs
 * using the strtoul() and assigns the values in sequence to
 * the 128bit value
 */
uint128_t *sdp_create_base_uuid(void)
{
	uint128_t *base_uuid;
	char baseStr[128];
	int delim = '-';
	unsigned long dataLongValue;
	char *delimPtr;
	char *dataPtr;
	char temp[10];
	int toBeCopied;
	uint8_t *data;

	strcpy(baseStr, BASE_UUID);
	base_uuid = malloc(sizeof(uint128_t));
	if (!base_uuid)
		return NULL;

	data = base_uuid->data;
	memset(data, '\0', sizeof(uint128_t));
	memset(temp, '\0', 10);
	dataPtr = baseStr;
	delimPtr = NULL;
	delimPtr = strchr(dataPtr, delim);
	toBeCopied = delimPtr - dataPtr;
	if (toBeCopied != 8) {
		SDPDBG("To be copied(1) : %d\n", toBeCopied);
		free(base_uuid);
		return NULL;
	}
	strncpy(temp, dataPtr, toBeCopied);
	dataLongValue = htonl(strtoul(temp, NULL, 16));
	memcpy(&data[0], &dataLongValue, 4);

	/*
	 * Get the next 4 bytes (note that there is a "-"
	 * between them now)
	 */
	memset(temp, '\0', 10);
	dataPtr = delimPtr + 1;
	delimPtr = strchr(dataPtr, delim);
	toBeCopied = delimPtr - dataPtr;
	if (toBeCopied != 4) {
		SDPDBG("To be copied(2) : %d\n", toBeCopied);
		free(base_uuid);
		return NULL;
	}
	strncpy(temp, dataPtr, toBeCopied);
	dataPtr = delimPtr + 1;
	delimPtr = strchr(dataPtr, delim);
	toBeCopied = delimPtr - dataPtr;
	if (toBeCopied != 4) {
		SDPDBG("To be copied(3) : %d\n", toBeCopied);
		free(base_uuid);
		return NULL;
	}
	strncat(temp, dataPtr, toBeCopied);
	dataLongValue = htonl(strtoul(temp, NULL, 16));
	memcpy(&data[4], &dataLongValue, 4);

	/*
	 * Get the last 4 bytes (note that there are 6 bytes
	 * after the last separator, which is truncated (2+4)
	 */
	memset(temp, '\0', 10);
	dataPtr = delimPtr + 1;
	dataPtr = delimPtr + 1;
	delimPtr = strchr(dataPtr, delim);
	toBeCopied = delimPtr - dataPtr;
	if (toBeCopied != 4) {
		SDPDBG("To be copied(4) : %d\n", toBeCopied);
		free(base_uuid);
		return NULL;
	}
	strncpy(temp, dataPtr, toBeCopied);
	strncat(temp, (delimPtr + 1), 4);
	dataLongValue = htonl(strtoul(temp, NULL, 16));
	memcpy(&data[8], &dataLongValue, 4);
	dataLongValue = htonl(strtoul(delimPtr + 5, NULL, 16));
	memcpy(&data[12], &dataLongValue, 4);

	return base_uuid;
}

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_uuid16_cmp(const void *p1, const void *p2)
{
	const uuid_t *u1 = (const uuid_t *)p1;
	const uuid_t *u2 = (const uuid_t *)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 = (const uuid_t *)p1;
	const uuid_t *u2 = (const uuid_t *)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, 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, 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(uuid_t *uuid)
{
	uuid_t *uuid128 = bt_malloc(sizeof(uuid_t));
	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;
	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;
}

int sdp_uuid_extract(const uint8_t *p, uuid_t *uuid, int *scanned)
{
	uint8_t 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);
	if (type == SDP_UUID16) {
		sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p)));
		*scanned += sizeof(uint16_t);
		p += sizeof(uint16_t);
	} else if (type == SDP_UUID32) {
		sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p)));
		*scanned += sizeof(uint32_t);
		p += sizeof(uint32_t);
	} else {
		sdp_uuid128_create(uuid, p);
		*scanned += sizeof(uint128_t);
		p += sizeof(uint128_t);
	}
	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 = *(uint8_t *) 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 + len > dst->buf_size) {
		int need = SDP_PDU_CHUNK_SIZE * ((len / SDP_PDU_CHUNK_SIZE) + 1);
		dst->data = realloc(dst->data, dst->buf_size + need);

		SDPDBG("Realloc'ing : %d\n", need);

		if (dst->data == NULL) {
			SDPERR("Realloc fails \n");
		}
		dst->buf_size += need;
	}
	if (dst->data_size == 0 && dtd == 0) {
		// create initial sequence
		*(uint8_t *)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;
		*(uint8_t *) 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)
{
	uint8_t buf[256];
	sdp_buf_t append;

	memset(&append, 0, sizeof(sdp_buf_t));
	append.data = buf;
	append.buf_size = sizeof(buf);
	append.data_size = 0;

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

/*
 * 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;

	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 (handle)
			*handle  = ntohl(bt_get_unaligned((uint32_t *) p));
	}

end:
	if (req)
		free(req);

	if (rsp)
		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;

	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:
	if (reqbuf)
		free(reqbuf);

	if (rspbuf)
		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;

	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:
	if (reqbuf)
		free(reqbuf);
	if (rspbuf)
		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));
	memset((void *)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("SvcRec : 0x%lx\n", (unsigned long)rec);
	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, sdp_list_t **seq, int count, int *scanned)
{
	sdp_list_t *pSeq = *seq;
	uint8_t *pdata = pdu;
	int n;

	for (n = 0; n < count; n++) {
		uint32_t *pSvcRec = malloc(sizeof(uint32_t));
		*pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata));
		pSeq = sdp_list_append(pSeq, pSvcRec);
		pdata += sizeof(uint32_t);
		*scanned += 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("");
	
	memset(&buf, 0, sizeof(sdp_buf_t));
	buf.data = malloc(256);
	buf.buf_size = 256;

	if (!buf.data)
		return -ENOMEM;

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

	types = malloc(seqlen * sizeof(void *));
	values = malloc(seqlen * sizeof(void *));
	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);
	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 = (uuid_t *) 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, const sdp_cstate_t *cstate)
{
	if (cstate) {
		*pdata++ = cstate->length;
		memcpy(pdata, cstate->data, cstate->length);
		return cstate->length + 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 scanned, total_rec_count, rec_count;
	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, 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;

		rsplen = 0;
		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);

		// net service record match count
		total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
		pdata += sizeof(uint16_t);
		scanned += sizeof(uint16_t);
		rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
		pdata += sizeof(uint16_t);
		scanned += 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, rsp, rec_count, &scanned);
		SDPDBG("BytesScanned : %d\n", scanned);

		if (rsplen > scanned) {
			uint8_t cstate_len;

			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:
	if (reqbuf)
		free(reqbuf);
	if (rspbuf)
		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)
{
	int status = 0;
	uint32_t reqsize = 0, _reqsize;
	uint32_t rspsize = 0, rsp_count;
	int attr_list_len = 0;
	int seqlen = 0;
	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 0;
	}

	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
	if (!reqbuf || !rspbuf) {
		errno = ENOMEM;
		status = -1;
		goto end;
	}
	memset((char *) &rsp_concat_buf, 0, sizeof(sdp_buf_t));
	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;
		status = -1;
		goto end;
	}
	pdata += seqlen;
	reqsize += seqlen;
	SDPDBG("Attr list length : %d\n", seqlen);

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

	do {
		// add NULL continuation state
		reqsize = _reqsize + copy_cstate(_pdata, 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;
		rsp_count = 0;
		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
			SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id);
			status = -1;
			goto end;
		}
		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
		attr_list_len += rsp_count;
		pdata += sizeof(uint16_t);

		// if continuation state set need to re-issue request before parsing
		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;
		rec = sdp_extract_pdu(pdata, &scanned);

		if (!rec)
			status = -1;
	}
	
  end:
	if (reqbuf)
		free(reqbuf);
	if (rsp_concat_buf.data)
		free(rsp_concat_buf.data);
	if (rspbuf)
		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;

	/* check if the buffer is already allocated */
	if (t->rsp_concat_buf.data)
		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, 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:

	if (t->reqbuf) {
		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;

	/* check if the buffer is already allocated */
	if (t->rsp_concat_buf.data)
		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, 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:

	if (t->reqbuf) {
		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;

	/* check if the buffer is already allocated */
	if (t->rsp_concat_buf.data)
		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, 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:

	if (t->reqbuf) {
		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) + 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 - 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, 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);
	}

	if (rspbuf)
		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;
	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;
	}
	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
	if (!reqbuf || !rspbuf) {
		errno = ENOMEM;
		status = -1;
		goto end;
	}

	memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t));
	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, 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 (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);
		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
		attr_list_len += rsp_count;
		pdata += sizeof(uint16_t);	// pdata points to attribute list
		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;

		/*
		 * 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, &dataType, &seqlen);

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

		if (scanned && seqlen) {
			pdata += scanned;
			do {
				int recsize = 0;
				sdp_record_t *rec = sdp_extract_pdu(pdata, &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;

				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);

			SDPDBG("Successful scan of service attr lists\n");
			*rsp = rec_list;
		}
	}
  end:
	if (rsp_concat_buf.data)
		free(rsp_concat_buf.data);
	if (reqbuf)
		free(reqbuf);
	if (rspbuf)
		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) {
		if (t->reqbuf)
			free(t->reqbuf);

		if (t->rsp_concat_buf.data)
			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);
	}

	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);
	if (session->priv)
		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++;
}
