sdp.c revision 453a0cedb6c909047553ffc7145bcef26a3ae94c
1542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *
3764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *  BlueZ - Bluetooth protocol stack for Linux
4764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *
5764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *  Copyright (C) 2001-2002  Nokia Corporation
6764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
7197a2aee34d9a1643cd474f8f167552ca6395d01Marcel Holtmann *  Copyright (C) 2002-2006  Marcel Holtmann <marcel@holtmann.org>
8764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *  Copyright (C) 2002-2003  Stephen Crane <steve.crane@rococosoft.com>
9764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *
10764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *
11764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *  This program is free software; you can redistribute it and/or modify
12c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  it under the terms of the GNU General Public License as published by
13c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  the Free Software Foundation; either version 2 of the License, or
14c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  (at your option) any later version.
15764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *
16c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  This program is distributed in the hope that it will be useful,
17c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  GNU General Public License for more details.
20764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *
21c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  You should have received a copy of the GNU General Public License
22c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  along with this program; if not, write to the Free Software
23c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann *
25542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
26542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
27764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann#ifdef HAVE_CONFIG_H
28764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann#include <config.h>
29764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann#endif
30764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann
31542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <stdio.h>
32542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <errno.h>
33542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <unistd.h>
34542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <stdlib.h>
35542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <malloc.h>
36654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#include <syslog.h>
37542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <sys/un.h>
38542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <sys/socket.h>
398bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann#include <sys/time.h>
408bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann#include <sys/types.h>
41542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4251e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/bluetooth.h>
4351e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/hci.h>
4451e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/hci_lib.h>
4551e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/l2cap.h>
4651e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/sdp.h>
4751e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/sdp_lib.h>
48654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
49654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#include <netinet/in.h>
50654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
51654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg)
52654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg)
53654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
54654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#ifdef SDP_DEBUG
55654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg)
56654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#else
57654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPDBG(fmt...)
58654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#endif
59654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
60654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#if __BYTE_ORDER == __BIG_ENDIAN
61654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define ntoh64(x) (x)
62654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmannstatic inline void ntoh128(uint128_t *src, uint128_t *dst)
63654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann{
64654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	int i;
65654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	for (i = 0; i < 16; i++)
66654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann		dst->data[i] = src->data[i];
67654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann}
68654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#else
69654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmannstatic inline uint64_t ntoh64(uint64_t n)
70654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann{
71654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	uint64_t h;
72654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
73654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	h = ntohl(n >> 32);
74654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	h |= tmp << 32;
75654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	return h;
76654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann}
77654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmannstatic inline void ntoh128(uint128_t *src, uint128_t *dst)
78654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann{
79654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	int i;
80654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	for (i = 0; i < 16; i++)
81654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann		dst->data[15 - i] = src->data[i];
82654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann}
83654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#endif
84654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
85654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define hton64(x)     ntoh64(x)
86654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define hton128(x, y) ntoh128(x, y)
87542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
88542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB"
89542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
90542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic uint128_t *bluetooth_base_uuid = NULL;
91542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
92654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDP_BASIC_ATTR_PDUFORM_SIZE 32
93654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDP_SEQ_PDUFORM_SIZE 128
94654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDP_UUID_SEQ_SIZE 256
95654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDP_MAX_ATTR_LEN 65535
96654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
97542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* Message structure. */
98542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstruct tupla {
99542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int index;
100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *str;
101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann};
102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic struct tupla Protocol[] = {
1046864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SDP_UUID,		"SDP"		},
1056864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDP_UUID,		"UDP"		},
1066864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ RFCOMM_UUID,		"RFCOMM"	},
1076864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ TCP_UUID,		"TCP"		},
1086864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ TCS_BIN_UUID,		"TCS-BIN"	},
1096864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ TCS_AT_UUID,		"TCS-AT"	},
1106864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ OBEX_UUID,		"OBEX"		},
1116864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IP_UUID,		"IP"		},
1126864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ FTP_UUID,		"FTP"		},
1136864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HTTP_UUID,		"HTTP"		},
1146864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ WSP_UUID,		"WSP"		},
1156864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ BNEP_UUID,		"BNEP"		},
1166864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_UUID,		"UPNP"		},
1176864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HIDP_UUID,		"HIDP"		},
1186864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCRP_CTRL_UUID,	"HCRP-Ctrl"	},
1196864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCRP_DATA_UUID,	"HCRP-Data"	},
1206864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCRP_NOTE_UUID,	"HCRP-Notify"	},
1216864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AVCTP_UUID,		"AVCTP"		},
1226864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AVDTP_UUID,		"AVDTP"		},
1236864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ CMTP_UUID,		"CMTP"		},
1246864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDI_UUID,		"UDI"		},
1256864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ L2CAP_UUID,		"L2CAP"		},
126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	{ 0 }
127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann};
128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic struct tupla ServiceClass[] = {
1306864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SDP_SERVER_SVCLASS_ID,		"SDP Server"			},
1316864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ BROWSE_GRP_DESC_SVCLASS_ID,		"Browse Group Descriptor"	},
1326864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PUBLIC_BROWSE_GROUP,			"Public Browse Group"		},
1336864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SERIAL_PORT_SVCLASS_ID,		"Serial Port"			},
1346864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ LAN_ACCESS_SVCLASS_ID,		"LAN Access Using PPP"		},
1356864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ DIALUP_NET_SVCLASS_ID,		"Dialup Networking"		},
1366864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IRMC_SYNC_SVCLASS_ID,			"IrMC Sync"			},
1376864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ OBEX_OBJPUSH_SVCLASS_ID,		"OBEX Object Push"		},
1386864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ OBEX_FILETRANS_SVCLASS_ID,		"OBEX File Transfer"		},
1396864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IRMC_SYNC_CMD_SVCLASS_ID,		"IrMC Sync Command"		},
1406864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HEADSET_SVCLASS_ID,			"Headset"			},
1416864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ CORDLESS_TELEPHONY_SVCLASS_ID,	"Cordless Telephony"		},
1426864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AUDIO_SOURCE_SVCLASS_ID,		"Audio Source"			},
1436864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AUDIO_SINK_SVCLASS_ID,		"Audio Sink"			},
1446864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AV_REMOTE_TARGET_SVCLASS_ID,		"AV Remote Target"		},
1456864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ ADVANCED_AUDIO_SVCLASS_ID,		"Advanced Audio"		},
1466864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AV_REMOTE_SVCLASS_ID,			"AV Remote"			},
1476864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_CONF_SVCLASS_ID,		"Video Conferencing"		},
1486864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ INTERCOM_SVCLASS_ID,			"Intercom"			},
1496864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ FAX_SVCLASS_ID,			"Fax"				},
1506864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HEADSET_AGW_SVCLASS_ID,		"Headset Audio Gateway"		},
1516864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ WAP_SVCLASS_ID,			"WAP"				},
1526864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ WAP_CLIENT_SVCLASS_ID,		"WAP Client"			},
1536864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PANU_SVCLASS_ID,			"PAN User"			},
1546864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ NAP_SVCLASS_ID,			"Network Access Point"		},
1556864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GN_SVCLASS_ID,			"PAN Group Network"		},
1566864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ DIRECT_PRINTING_SVCLASS_ID,		"Direct Printing"		},
1576864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ REFERENCE_PRINTING_SVCLASS_ID,	"Reference Printing"		},
1586864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_SVCLASS_ID,			"Imaging"			},
1596864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_RESPONDER_SVCLASS_ID,		"Imaging Responder"		},
1606864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_ARCHIVE_SVCLASS_ID,		"Imaging Automatic Archive"	},
1616864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_REFOBJS_SVCLASS_ID,		"Imaging Referenced Objects"	},
1626864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HANDSFREE_SVCLASS_ID,			"Handsfree"			},
1636864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HANDSFREE_AGW_SVCLASS_ID,		"Handfree Audio Gateway"	},
1646864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ DIRECT_PRT_REFOBJS_SVCLASS_ID,	"Direct Printing Ref. Objects"	},
1656864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ REFLECTED_UI_SVCLASS_ID,		"Reflected UI"			},
1666864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ BASIC_PRINTING_SVCLASS_ID,		"Basic Printing"		},
1676864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PRINTING_STATUS_SVCLASS_ID,		"Printing Status"		},
1686864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HID_SVCLASS_ID,			"Human Interface Device"	},
1696864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCR_SVCLASS_ID,			"Hardcopy Cable Replacement"	},
1706864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCR_PRINT_SVCLASS_ID,			"HCR Print"			},
1716864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCR_SCAN_SVCLASS_ID,			"HCR Scan"			},
1726864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ CIP_SVCLASS_ID,			"Common ISDN Access"		},
1736864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_CONF_GW_SVCLASS_ID,		"Video Conferencing Gateway"	},
1746864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDI_MT_SVCLASS_ID,			"UDI MT"			},
1756864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDI_TA_SVCLASS_ID,			"UDI TA"			},
1766864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AV_SVCLASS_ID,			"Audio/Video"			},
1776864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SAP_SVCLASS_ID,			"SIM Access"			},
1788ce8108e712e40e1b9530c96f7ff6cbb32b5cb8bMarcel Holtmann	{ PBAP_PCE_SVCLASS_ID,			"Phonebook Access - PCE"	},
1798ce8108e712e40e1b9530c96f7ff6cbb32b5cb8bMarcel Holtmann	{ PBAP_PSE_SVCLASS_ID,			"Phonebook Access - PSE"	},
18073f2fe893f6801358ea4fb88dc8d24050c7d0ca5Marcel Holtmann	{ PBAP_SVCLASS_ID,			"Phonebook Access"		},
1816864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PNP_INFO_SVCLASS_ID,			"PnP Information"		},
1826864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_NETWORKING_SVCLASS_ID,	"Generic Networking"		},
1836864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_FILETRANS_SVCLASS_ID,		"Generic File Transfer"		},
1846864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_AUDIO_SVCLASS_ID,		"Generic Audio"			},
1856864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_TELEPHONY_SVCLASS_ID,		"Generic Telephony"		},
1866864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_SVCLASS_ID,			"UPnP"				},
1876864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_IP_SVCLASS_ID,			"UPnP IP"			},
1886864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_PAN_SVCLASS_ID,			"UPnP PAN"			},
1896864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_LAP_SVCLASS_ID,			"UPnP LAP"			},
1906864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_L2CAP_SVCLASS_ID,		"UPnP L2CAP"			},
1916864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_SOURCE_SVCLASS_ID,		"Video Source"			},
1926864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_SINK_SVCLASS_ID,		"Video Sink"			},
1932fa38208982e7c7bb55ae97acd13dbf82dd24e88Marcel Holtmann	{ VIDEO_DISTRIBUTION_SVCLASS_ID,	"Video Distribution"		},
19442e0ce5b430ac5e36c0d21bdddcaf1fe83e025f5Marcel Holtmann	{ APPLE_AGENT_SVCLASS_ID,		"Apple Agent"			},
195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	{ 0 }
196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann};
197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1986864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann#define Profile ServiceClass
199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic char *string_lookup(struct tupla *pt0, int index)
201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	struct tupla *pt;
2036864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (pt = pt0; pt->index; pt++)
2056864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann		if (pt->index == index)
206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return pt->str;
2076864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return "";
209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
210542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2113df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmannstatic char *string_lookup_uuid(struct tupla *pt0, const uuid_t* uuid)
2123df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann{
2133df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	uuid_t tmp_uuid;
2143df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
2153df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid));
2163df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
2173df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	if (sdp_uuid128_to_uuid(&tmp_uuid)) {
2183df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		switch (tmp_uuid.type) {
2193df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		case SDP_UUID16:
2203df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann			return string_lookup(pt0, tmp_uuid.value.uuid16);
2213df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		case SDP_UUID32:
2223df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann			return string_lookup(pt0, tmp_uuid.value.uuid32);
2233df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		}
2243df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	}
2253df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
2263df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	return "";
2273df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann}
2283df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
230542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Prints into a string the Protocol UUID
231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * coping a maximum of n characters.
232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n)
234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *str2;
236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!uuid) {
238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "NULL");
239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -2;
240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2416864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		str2 = string_lookup(message, uuid->value.uuid16);
245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, str2);
246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
2480e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann		str2 = string_lookup(message, uuid->value.uuid32);
2490e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann		snprintf(str, n, str2);
2500e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann		break;
251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
2523df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		str2 = string_lookup_uuid(message, uuid);
2533df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		snprintf(str, n, str2);
2543df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		break;
255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2596864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n)
264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid2str(Protocol, uuid, str, n);
266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n)
269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid2str(ServiceClass, uuid, str, n);
271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n)
274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid2str(Profile, uuid, str, n);
276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * convert the UUID to string, copying a maximum of n characters.
280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n)
282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!uuid) {
284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "NULL");
285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -2;
286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "%.4x", uuid->value.uuid16);
290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "%.8x", uuid->value.uuid32);
293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:{
295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int   data0;
296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data1;
297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data2;
298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data3;
299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int   data4;
300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data5;
301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				ntohl(data0), ntohs(data1),
311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				ntohs(data2), ntohs(data3),
312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				ntohl(data4), ntohs(data5));
313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;	// Enum type of UUID not set
318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Function prints the UUID in hex as per defined syntax -
325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 4bytes-2bytes-2bytes-2bytes-6bytes
327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * There is some ugly code, including hardcoding, but
329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * that is just the way it is converting 16 and 32 bit
330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUIDs to 128 bit as defined in the SDP doc
331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid_print(const uuid_t *uuid)
333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid == NULL) {
335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Null passed to print UUID\n");
336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return;
337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid->type == SDP_UUID16) {
339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("  uint16_t : 0x%.4x\n", uuid->value.uuid16);
340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else if (uuid->type == SDP_UUID32) {
341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("  uint32_t : 0x%.8x\n", uuid->value.uuid32);
342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else if (uuid->type == SDP_UUID128) {
343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int data0;
344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data1;
345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data2;
346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data3;
347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int data4;
348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data5;
349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("  uint128_t : 0x%.8x-", ntohl(data0));
358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x-", ntohs(data1));
359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x-", ntohs(data2));
360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x-", ntohs(data3));
361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.8x", ntohl(data4));
362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x\n", ntohs(data5));
363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else
364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Enum type of UUID not set\n");
365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
368641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, uint32_t length)
369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *seq;
37121f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!d)
374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->dtd = dtd;
378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->unitSize = sizeof(uint8_t);
379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
384aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint8 = *(uint8_t *) value;
385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint8_t);
386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
389aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int8 = *(int8_t *) value;
390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int8_t);
391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
393aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint16 = bt_get_unaligned((uint16_t *) value);
394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint16_t);
395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
397aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int16 = bt_get_unaligned((int16_t *) value);
398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int16_t);
399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
401aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint32 = bt_get_unaligned((uint32_t *) value);
402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint32_t);
403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
405aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int32 = bt_get_unaligned((int32_t *) value);
406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int32_t);
407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
409aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int64 = bt_get_unaligned((int64_t *) value);
410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int64_t);
411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
413aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint64 = bt_get_unaligned((uint64_t *) value);
414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint64_t);
415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&d->val.uint128.data, value, sizeof(uint128_t));
418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint128_t);
419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&d->val.int128.data, value, sizeof(uint128_t));
422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint128_t);
423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
425aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value));
426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint16_t);
427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
429aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value));
430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint32_t);
431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid128_create(&d->val.uuid, value);
434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint128_t);
435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
438641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_TEXT_STR8:
439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
440641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (!value) {
441641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			free(d);
442641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			return NULL;
443641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		}
444641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
445641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		d->unitSize += length;
446641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (length <= USHRT_MAX) {
447641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			d->val.str = malloc(length);
448641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			if (!d->val.str) {
449641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann				free(d);
450641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann				return NULL;
451641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			}
452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
453641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			memcpy(d->val.str, value, length);
454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		} else {
455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPERR("Strings of size > USHRT_MAX not supported\n");
456641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			free(d);
457641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			d = NULL;
458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Strings of size > USHRT_MAX not supported\n");
463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (dtd == SDP_ALT8 || dtd == SDP_SEQ8)
471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += sizeof(uint8_t);
472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16)
473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += sizeof(uint16_t);
474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32)
475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += sizeof(uint32_t);
476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = (sdp_data_t *)value;
477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->val.dataseq = seq;
478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (; seq; seq = seq->next)
479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += seq->unitSize;
480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
482641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		free(d);
483641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		d = NULL;
484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
485641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
487641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann}
488641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
489641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value)
490641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann{
491641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	uint32_t length;
492542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
493641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	switch (dtd) {
494641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR8:
495641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR16:
496641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_TEXT_STR8:
497641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_TEXT_STR16:
498641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (!value)
499641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			return NULL;
500641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
501641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		length = strlen((char *) value);
502641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		break;
503641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	default:
504641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		length = 0;
505641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		break;
506641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	}
507641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
508641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	return sdp_data_alloc_with_length(dtd, value, length);
509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d)
512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seq) {
514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *p;
515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = seq; p->next; p = p->next);
516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p->next = d;
517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else
518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = d;
519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->next = NULL;
520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seq;
521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
523641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length, int len)
524641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann{
525641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	sdp_data_t *curr = NULL, *seq = NULL;
526641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	int i;
527641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
528641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	for (i = 0; i < len; i++) {
529641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		sdp_data_t *data;
530641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		int8_t dtd = *(uint8_t *) dtds[i];
531641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
532641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
533641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			data = (sdp_data_t *) values[i];
534641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		else
535641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			data = sdp_data_alloc_with_length(dtd, values[i], length[i]);
536641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
537641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (!data)
538641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			return NULL;
539641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
540641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (curr)
541641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			curr->next = data;
542641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		else
543641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			seq = data;
544641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
545641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		curr = data;
546641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	}
547641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
548641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	return sdp_data_alloc_with_length(SDP_SEQ8, seq, length[i]);
549641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann}
550641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len)
552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *curr = NULL, *seq = NULL;
554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i;
555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0; i < len; i++) {
557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data;
558641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		uint8_t dtd = *(uint8_t *) dtds[i];
559641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
561641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			data = (sdp_data_t *) values[i];
562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			data = sdp_data_alloc(dtd, values[i]);
564641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
565542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!data)
566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
567641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
568542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (curr)
569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			curr->next = data;
570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seq = data;
572641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		curr = data;
574542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
575641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return sdp_data_alloc(SDP_SEQ8, seq);
577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
579542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *p = sdp_data_get(rec, attr);
582542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (p)
584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->attrId = attr;
586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_attr_remove(sdp_record_t *rec, uint16_t attr)
591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_get(rec, attr);
593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->attrlist = sdp_list_remove(rec->attrlist, d);
595542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
597cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannvoid sdp_set_seq_len(uint8_t *ptr, uint32_t length)
598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
599aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	uint8_t dtd = *(uint8_t *) ptr++;
600542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
601542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
605542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
606aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*(uint8_t *)ptr = (uint8_t) length;
607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
612aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htons(length), (uint16_t *) ptr);
613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
614542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
618aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htonl(length), (uint32_t *) ptr);
619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd)
624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int orig = buf->data_size;
626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t *p = buf->data + buf->data_size;
627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*p++ = dtd;
629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf->data_size += sizeof(uint8_t);
630641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		buf->data_size += sizeof(uint8_t);
637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		buf->data_size += sizeof(uint16_t);
643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		buf->data_size += sizeof(uint32_t);
649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
651641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return buf->data_size - orig;
653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_attrid(sdp_buf_t *buf, uint16_t attr)
656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t *p = buf->data;
658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// data type for attr
660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*p++ = SDP_UINT16;
661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf->data_size = sizeof(uint8_t);
662aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(attr), (uint16_t *) p);
663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint16_t);
664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf->data_size += sizeof(uint16_t);
665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata)
668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d;
670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = 0;
671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (d = sdpdata->val.dataseq; d; d = d->next)
673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += sdp_gen_pdu(buf, d);
674641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return n;
676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
680cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t pdu_size = 0, data_size = 0;
681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned char *src = NULL, is_seq = 0, is_alt = 0;
682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd = d->dtd;
683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint16_t u16;
684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t u32;
685542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint64_t u64;
686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t u128;
687cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *seqp = buf->data + buf->data_size;
688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdu_size = sdp_set_data_type(buf, dtd);
690641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = &d->val.uint8;
696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint8_t);
697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.uint16);
700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u16;
701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint16_t);
702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.uint32);
705542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u32;
706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint32_t);
707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u64 = hton64(d->val.uint64);
710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u64;
711542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint64_t);
712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		hton128(&d->val.uint128, &u128);
715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u128;
716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint128_t);
717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&d->val.int8;
721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(int8_t);
722542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.int16);
725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u16;
726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(int16_t);
727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.int32);
730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u32;
731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(int32_t);
732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u64 = hton64(d->val.int64);
735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u64;
736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(int64_t);
737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		hton128(&d->val.int128, &u128);
740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u128;
741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint128_t);
742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
746641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		src = (unsigned char *)d->val.str;
747641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		data_size = d->unitSize - sizeof(uint8_t);
748641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		sdp_set_seq_len(seqp, data_size);
749641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		break;
750641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR8:
751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)d->val.str;
754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = strlen(d->val.str);
755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		is_seq = 1;
761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = get_data_size(buf, d);
762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		is_alt = 1;
768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = get_data_size(buf, d);
769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.uuid.value.uuid16);
773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u16;
774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint16_t);
775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.uuid.value.uuid32);
778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u32;
779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint32_t);
780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
782542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&d->val.uuid.value.uuid128;
783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint128_t);
784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
788641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!is_seq && !is_alt) {
790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (src && buf) {
791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(buf->data + buf->data_size, src, data_size);
792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			buf->data_size += data_size;
793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		} else if (dtd != SDP_DATA_NIL)
794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Gen PDU : Cant copy from NULL source or dest\n");
795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
796641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdu_size += data_size;
798641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return pdu_size;
800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void sdp_attr_pdu(void *value, void *udata)
803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);
805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf)
808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
809cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	buf->data = malloc(SDP_PDU_CHUNK_SIZE);
810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (buf->data) {
811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		buf->buf_size = SDP_PDU_CHUNK_SIZE;
812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		buf->data_size = 0;
813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memset(buf->data, 0, buf->buf_size);
814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf);
815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *p = sdp_data_get(rec, attr);
823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (p) {
825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->attrlist = sdp_list_remove(rec->attrlist, p);
826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_free(p);
827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->attrId = attr;
829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, (void *)d, sdp_attrid_comp_func);
830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attrid_comp_func(const void *key1, const void *key2)
833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_data_t *d1 = (const sdp_data_t *)key1;
835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_data_t *d2 = (const sdp_data_t *)key2;
836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d1 && d2)
838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return d1->attrId - d2->attrId;
839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void data_seq_free(sdp_data_t *seq)
843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = seq->val.dataseq;
845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (d) {
847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *next = d->next;
848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_free(d);
849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d = next;
850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_free(sdp_data_t *d)
854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_seq_free(d);
860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
863542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d->val.str);
868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(d);
871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *extract_int(const void *p, int *len)
874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
87521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting integer\n");
878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
879aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += sizeof(uint8_t);
882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint8_t);
890aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint8 = *(uint8_t *) p;
891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint16_t);
895aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p));
896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint32_t);
900aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p));
901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint64_t);
905aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p));
906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
907542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
909542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint128_t);
910aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		ntoh128((uint128_t *) p, &d->val.uint128);
911542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d = NULL;
915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
919cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic sdp_data_t *extract_uuid(const uint8_t *p, int *len, sdp_record_t *rec)
920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
92121f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting UUID");
924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
92521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	if (sdp_uuid_extract(p, &d->val.uuid, len) < 0) {
926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
928542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
929aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &d->val.uuid);
931542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
932542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
933542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
934542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
935542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract strings from the PDU (could be service description and similar info)
936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *extract_str(const void *p, int *len)
938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *s;
940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
94121f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
944aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += sizeof(uint8_t);
947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
951aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		n = *(uint8_t *) p;
952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint8_t) + n;
954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
957aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		n = ntohs(bt_get_unaligned((uint16_t *) p));
958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint16_t);
959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint16_t) + n;
960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Sizeof text string > UINT16_MAX\n");
963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
967ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann	s = malloc(n + 1);
968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(s, 0, n + 1);
969ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann	memcpy(s, p, n);
970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Len : %d\n", n);
972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Str : %s\n", s);
973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->val.str = s;
9750ed4f8572e1b32b4dd57304db14351f0e0c59119Marcel Holtmann	d->unitSize = n + sizeof(uint8_t);
976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec)
980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen, n = 0;
982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *curr, *prev;
98321f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting SEQ");
986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len = sdp_extract_seqtype(p, &d->dtd, &seqlen);
988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen);
989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (*len == 0)
991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return d;
992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += *len;
994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	curr = prev = NULL;
995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (n < seqlen) {
996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int attrlen = 0;
997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		curr = sdp_extract_attr(p, &attrlen, rec);
998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (curr == NULL)
999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (prev)
1002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			prev->next = curr;
1003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
1004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->val.dataseq = curr;
1005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		prev = curr;
1006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += attrlen;
1007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += attrlen;
1008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen);
1010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += n;
1013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1016cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannsdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec)
1017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *elem;
1019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = 0;
1020542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd = *(const uint8_t *)p;
1021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("extract_attr: dtd=0x%x", dtd);
1023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
1024542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1025542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1026542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1027542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1028542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1036542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		elem = extract_int(p, &n);
1037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1039542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1041542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		elem = extract_uuid(p, &n, rec);
1042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1045542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
1046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
1049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		elem = extract_str(p, &n);
1050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		elem = extract_seq(p, &n, rec);
1058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd);
1061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
1062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*size += n;
1064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return elem;
1065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void attr_print_func(void *value, void *userData)
1069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = (sdp_data_t *)value;
1071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("=====================================\n");
1073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n",  d->attrId);
1074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value);
1075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
1076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_print(d);
1077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
1078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("NULL value\n");
1079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("=====================================\n");
1080542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1082542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_print_service_attr(sdp_list_t *svcAttrList)
1083542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
10848bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann	SDPDBG("Printing service attr list %p\n", svcAttrList);
1085542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_foreach(svcAttrList, attr_print_func, NULL);
10868bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann	SDPDBG("Printed service attr list %p\n", svcAttrList);
1087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1090cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannsdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned)
1091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1092542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int extracted = 0, seqlen = 0;
1093542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd;
1094542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint16_t attr;
1095542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_record_t *rec = sdp_record_alloc();
1096cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	const uint8_t *p = buf;
1097542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*scanned = sdp_extract_seqtype(buf, &dtd, &seqlen);
1099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += *scanned;
1100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->attrlist = NULL;
1101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (extracted < seqlen) {
1102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int n = sizeof(uint8_t), attrlen = 0;
1103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data = NULL;
1104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, extracted);
1106aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		dtd = *(uint8_t *) p;
1107aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		attr = ntohs(bt_get_unaligned((uint16_t *) (p + n)));
1108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += sizeof(uint16_t);
1109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr);
1111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1112aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		data = sdp_extract_attr(p + n, &attrlen, rec);
1113542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen);
1115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += attrlen;
1117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (data == NULL) {
1118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Terminating extraction of attributes");
1119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (attr == SDP_ATTR_RECORD_HANDLE)
1122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rec->handle = data->val.uint32;
1123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		extracted += n;
1124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += n;
1125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, attr, data);
1126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",
1127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					seqlen, extracted);
1128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Successful extracting of Svc Rec attributes\n");
1131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_print_service_attr(rec->attrlist);
1132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*scanned += seqlen;
1134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
1135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void print_dataseq(sdp_data_t *p)
1139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d;
1141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (d = p; d; d = d->next)
1143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_print(d);
1144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_print(const sdp_record_t *rec)
1148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
1150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
1151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		printf("Service Name: %s\n", d->val.str);
1152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
1153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
1154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		printf("Service Description: %s\n", d->val.str);
1155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
1156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
1157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		printf("Service Provider: %s\n", d->val.str);
1158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_print(sdp_data_t *d)
1162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
1164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("NIL\n");
1166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1174542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1176542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1177542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Integer : 0x%x\n", d->val.uint32);
1179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1181542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("UUID\n");
1184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid_print(&d->val.uuid);
1185542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
1189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Text : %s\n", d->val.str);
1190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
1194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("URL : %s\n", d->val.str);
1195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		print_dataseq(d->val.dataseq);
1200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Data Sequence Alternates\n");
1205542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		print_dataseq(d->val.dataseq);
1206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1207542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1210542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1211542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId)
1212542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rec->attrlist) {
1214542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t sdpTemplate;
1215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpTemplate.attrId = attrId;
1218542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func);
1219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (p)
1220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return (sdp_data_t *)p->data;
1221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1222542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1226542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract the sequence type and its length, and return offset into buf
1227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * or 0 on failure.
1228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1229cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_extract_seqtype(const uint8_t *buf, uint8_t *dtdp, int *size)
1230542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1231aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	uint8_t dtd = *(uint8_t *) buf;
1232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int scanned = sizeof(uint8_t);
1233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf += sizeof(uint8_t);
1235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*dtdp = dtd;
1236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
1237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1239aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*size = *(uint8_t *) buf;
1240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint8_t);
1241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1244aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*size = ntohs(bt_get_unaligned((uint16_t *) buf));
1245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
1246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1248542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1249aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*size = ntohl(bt_get_unaligned((uint32_t *) buf));
1250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint32_t);
1251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Unknown sequence type, aborting\n");
1254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return scanned;
1257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1259cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size)
1260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1261cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t sent = 0;
1262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (sent < size) {
1264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int n = send(session->sock, buf + sent, size - sent, 0);
1265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (n < 0)
1266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return -1;
1267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sent += n;
1268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1272cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size)
1273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	fd_set readFds;
1275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 };
1276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
127773fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann	FD_ZERO(&readFds);
1278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	FD_SET(session->sock, &readFds);
1279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Waiting for response\n");
128073fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann	if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) {
1281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Client timed out\n");
1282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ETIMEDOUT;
1283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return recv(session->sock, buf, size, 0);
1286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * generic send request, wait for response method.
1290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1291cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf, uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize)
1292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
1294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)reqbuf;
1295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *)rspbuf;
1296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
1298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > sdp_send_req(session, reqbuf, reqsize)) {
1299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Error sending data:%s", strerror(errno));
1300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
1303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > n)
1304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Read : %d\n", n);
1306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (n == 0 || reqhdr->tid != rsphdr->tid) {
1307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EPROTO;
1308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rspsize = n;
1311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * singly-linked lists (after openobex implementation)
1316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_append(sdp_list_t *p, void *d)
1318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
131921f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_list_t *q, *n = malloc(sizeof(sdp_list_t));
1320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!n)
1322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->data = d;
1325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->next = 0;
1326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!p)
1328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return n;
1329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = p; q->next; q = q->next);
1331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	q->next = n;
1332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return p;
1334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_remove(sdp_list_t *list, void *d)
1337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p, *q;
1339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = 0, p = list; p; q = p, p = p->next)
1341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (p->data == d) {
1342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (q)
1343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				q->next = p->next;
1344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			else
1345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				list = p->next;
1346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			free(p);
1347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return list;
1351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d, sdp_comp_func_t f)
1354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *q, *p, *n;
1356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
135721f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	n = malloc(sizeof(sdp_list_t));
1358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!n)
1359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->data = d;
1361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = 0, p = list; p; q = p, p = p->next)
1362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (f(p->data, d) >= 0)
1363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// insert between q and p; if !q insert at head
1365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (q)
1366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		q->next = n;
1367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
1368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		list = n;
1369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->next = p;
1370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return list;
1371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Every element of the list points to things which need
1375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to be free()'d. This method frees the list's contents
1376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_list_free(sdp_list_t *list, sdp_free_func_t f)
1378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *next;
1380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (list) {
1381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		next = list->next;
1382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (f)
1383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			f(list->data);
1384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(list);
1385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		list = next;
1386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int __find_port(sdp_data_t *seq, int proto)
1390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!seq || !seq->next)
1392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) {
1395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = seq->next;
1396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		switch (seq->dtd) {
1397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UINT8:
1398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return seq->val.uint8;
1399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UINT16:
1400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return seq->val.uint16;
1401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_proto_port(const sdp_list_t *list, int proto)
1407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (proto != L2CAP_UUID && proto != RFCOMM_UUID) {
1409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
1410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; list; list = list->next) {
1414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = list->data; p; p = p->next) {
1416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_data_t *seq = (sdp_data_t *) p->data;
1417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			int port = __find_port(seq, proto);
1418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (port)
1419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return port;
1420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto)
1426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; list; list = list->next) {
1428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1429542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = list->data; p; p = p->next) {
1430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_data_t *seq = (sdp_data_t *) p->data;
1431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (SDP_IS_UUID(seq->dtd) &&
1432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					sdp_uuid_to_proto(&seq->val.uuid) == proto)
1433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return seq->next;
1434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return NULL;
1437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *pdlist, *curr;
1442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *ap = 0;
1443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdlist = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
1445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (pdlist == NULL) {
1446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; pdlist; pdlist = pdlist->next) {
1452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *pds = 0;
1453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pds = sdp_list_append(pds, curr->val.dataseq);
1455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		ap = sdp_list_append(ap, pds);
1456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*pap = ap;
1458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1461233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmannint sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1462233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann{
1463233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	sdp_data_t *pdlist, *curr;
1464233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	sdp_list_t *ap = 0;
1465233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1466233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
1467233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	if (pdlist == NULL) {
1468233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		errno = ENODATA;
1469233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		return -1;
1470233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	}
1471233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1472233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1473233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	pdlist = pdlist->val.dataseq;
1474233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1475233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	for (; pdlist; pdlist = pdlist->next) {
1476233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		sdp_list_t *pds = 0;
1477233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1478233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann			pds = sdp_list_append(pds, curr->val.dataseq);
1479233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		ap = sdp_list_append(ap, pds);
1480233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	}
1481233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	*pap = ap;
1482233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	return 0;
1483233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann}
1484233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **seqp)
1486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attr);
1488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1489542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*seqp = NULL;
1490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) {
1491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *d;
1492542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (d = sdpdata->val.dataseq; d; d = d->next) {
149321f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann			uuid_t *u = malloc(sizeof(uuid_t));
1494542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memset((char *)u, 0, sizeof(uuid_t));
1495542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (d->dtd >= SDP_UUID16 && d->dtd <= SDP_UUID128) {
1496542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			  	*u = d->val.uuid;
1497542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			  	*seqp = sdp_list_append(*seqp, u);
1498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			} else
1499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				goto fail;
1500542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail:
1504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(*seqp, free);
1505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
1506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq)
1510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0, i, len;
1512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **dtds, **values;
1513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid16 = SDP_UUID16;
1514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid32 = SDP_UUID32;
1515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid128 = SDP_UUID128;
1516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p;
1517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	len = sdp_list_len(seq);
1519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!seq || len == 0)
1520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dtds = (void **)malloc(len * sizeof(void *));
1522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	values = (void **)malloc(len * sizeof(void *));
1523542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = seq, i = 0; i < len; i++, p = p->next) {
1524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid_t *uuid = (uuid_t *)p->data;
1525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (uuid)
1526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			switch (uuid->type) {
1527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID16:
1528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid16;
1529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid16;
1530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID32:
1532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid32;
1533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid32;
1534542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID128:
1536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid128;
1537542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid128;
1538542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			default:
1540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				status = -1;
1541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
1543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else {
1544542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
1549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data = sdp_seq_alloc(dtds, values, len);
1550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, aid, data);
1551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_pattern_add_uuidseq(rec, seq);
1552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(dtds);
1554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
1555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
1556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq)
1559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_lang_attr_t *lang;
1561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata, *curr_data;
1562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*langSeq = NULL;
1564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST);
1565542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata == NULL) {
1566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1568542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	curr_data = sdpdata->val.dataseq;
1570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (curr_data) {
1571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pCode = curr_data;
1572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pEncoding = pCode->next;
1573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pOffset = pEncoding->next;
1574542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (pCode && pEncoding && pOffset) {
157521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann			lang = malloc(sizeof(sdp_lang_attr_t));
1576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			lang->code_ISO639 = pCode->val.uint16;
1577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			lang->encoding = pEncoding->val.uint16;
1578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			lang->base_offset = pOffset->val.uint16;
1579542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("code_ISO639 :  0x%02x\n", lang->code_ISO639);
1580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("encoding :     0x%02x\n", lang->encoding);
1581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("base_offfset : 0x%02x\n", lang->base_offset);
1582542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*langSeq = sdp_list_append(*langSeq, lang);
1583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		curr_data = pOffset->next;
1585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq)
1590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_profile_desc_t *profDesc;
1592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata, *seq;
1593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*profDescSeq = NULL;
1595542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST);
1596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!sdpdata || !sdpdata->val.dataseq) {
1597542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1599542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1600542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) {
16010f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		uuid_t *uuid = NULL;
16020f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		uint16_t version = 0x100;
16030f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann
16040f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		if (SDP_IS_UUID(seq->dtd)) {
16050f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			uuid = &seq->val.uuid;
16060f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		} else {
16070f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			sdp_data_t *puuid = seq->val.dataseq;
16080f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			sdp_data_t *pVnum = seq->val.dataseq->next;
16090f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			if (puuid && pVnum) {
16100f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann				uuid = &puuid->val.uuid;
16110f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann				version = pVnum->val.uint16;
16120f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			}
16130f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		}
16140f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann
16150f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		if (uuid != NULL) {
161621f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann			profDesc = malloc(sizeof(sdp_profile_desc_t));
16170f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			profDesc->uuid = *uuid;
16180f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			profDesc->version = version;
1619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_uuid_print(&profDesc->uuid);
1621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Vnum : 0x%04x\n", profDesc->version);
1622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*profDescSeq = sdp_list_append(*profDescSeq, profDesc);
1624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16)
1630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d, *curr;
1632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*u16 = NULL;
1634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST);
1635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d == NULL) {
1636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (curr = d->val.dataseq; curr; curr = curr->next)
1640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*u16 = sdp_list_append(*u16, &curr->val.uint16);
1641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* flexible extraction of basic attributes - Jean II */
1645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* How do we expect caller to extract predefined data sequences? */
1646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value)
1647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
1649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata)
1651542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/* Verify that it is what the caller expects */
1652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 ||
1653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 ||
1654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 ||
1655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_INT32) {
1656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*value = sdpdata->val.uint32;
1657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return 0;
1658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
1660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value, int valuelen)
1664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
1666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata)
1667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/* Verify that it is what the caller expects */
1668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (sdpdata->dtd == SDP_TEXT_STR8 || sdpdata->dtd == SDP_TEXT_STR16 || sdpdata->dtd == SDP_TEXT_STR32)
1669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (strlen(sdpdata->val.str) < valuelen) {
1670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				strcpy(value, sdpdata->val.str);
1671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return 0;
1672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
1673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
1674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#define get_basic_attr(attrID, pAttrValue, fieldName)		\
1678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *data = sdp_data_get(rec, attrID);		\
1679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (data) {						\
1680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*pAttrValue = data->val.fieldName;		\
1681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;					\
1682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}							\
1683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;						\
1684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1685542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid)
1687542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);
1689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1690542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid)
1692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);
1694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState)
1697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);
1699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail)
1702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);
1704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1705542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo)
1707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);
1709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1711542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState)
1712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);
1714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * NOTE that none of the setXXX() functions below will
1718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * actually update the SDP server, unless the
1719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * {register, update}sdp_record_t() function is invoked.
1720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1722542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd, const void *value)
1723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_alloc(dtd, value);
1725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d) {
1726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, attr, d);
1727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Set the information attributes of the service
1734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by rec. The attributes are
1735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * service name, description and provider name
1736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov, const char *desc)
1738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (name)
1740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY, SDP_TEXT_STR8, (void *)name);
1741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (prov)
1742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY, SDP_TEXT_STR8, (void *)prov);
1743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (desc)
1744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY, SDP_TEXT_STR8, (void *)desc);
1745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto)
1748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *seq = NULL;
1750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void *dtds[10], *values[10];
1751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **seqDTDs, **seqs;
1752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i, seqlen;
1753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p;
1754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = sdp_list_len(proto);
1756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqDTDs = (void **)malloc(seqlen * sizeof(void *));
1757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqs = (void **)malloc(seqlen * sizeof(void *));
1758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0, p = proto; p; p = p->next, i++) {
1759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *elt = (sdp_list_t *)p->data;
1760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *s;
1761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int pslen = 0;
1762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (; elt && pslen < sizeof(dtds); elt = elt->next, pslen++) {
1763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_data_t *d = (sdp_data_t *)elt->data;
1764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[pslen] = &d->dtd;
1765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			switch (d->dtd) {
1766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID16:
1767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &((uuid_t *)d)->value.uuid16;
1768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID32:
1770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &((uuid_t *)d)->value.uuid32;
1771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID128:
1773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &((uuid_t *)d)->value.uuid128;
1774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UINT8:
1776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &d->val.uint8;
1777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UINT16:
1779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &d->val.uint16;
1780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ8:
1782542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ16:
1783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ32:
1784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = d;
1785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			// FIXME: more
1787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
1788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		s = sdp_seq_alloc(dtds, values, pslen);
1790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (s) {
1791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqDTDs[i] = &s->dtd;
1792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqs[i] = s;
1793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
1796542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqDTDs);
1797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqs);
1798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seq;
1799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets the access protocols of the service specified
1803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to the value specified in "access_proto"
1804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Note that if there are alternate mechanisms by
1806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * which the service is accessed, then they should
1807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * be specified as sequences
1808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for accessProtocols has
1810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
1811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the existing sdp_access_proto_t
1813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
1814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
1818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
1820aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_data_t *protos = NULL;
1821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = ap; p; p = p->next) {
1823aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann		sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data);
1824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		protos = sdp_seq_append(protos, seq);
1825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1826aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos);
1828aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1829aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	return 0;
1830aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann}
1831aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1832aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmannint sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
1833aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann{
1834aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	const sdp_list_t *p;
1835aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_data_t *protos = NULL;
1836aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1837aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	for (p = ap; p; p = p->next) {
1838aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann		sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data);
1839aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann		protos = sdp_seq_append(protos, seq);
1840aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	}
1841aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1842aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST,
1843aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann			protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL);
1844aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the "LanguageBase" attributes of the service record
1850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * record to the value specified in "langAttrList".
1851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * "langAttrList" is a linked list of "sdp_lang_attr_t"
1853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * objects, one for each language in which user visible
1854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attributes are present in the service record.
1855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for langAttrList has
1857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
1858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting sdp_lang_attr_t
1860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
1861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1863542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq)
1865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uint16 = SDP_UINT16;
1867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0, i = 0, seqlen = sdp_list_len(seq);
1868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **dtds = (void **)malloc(3 * seqlen * sizeof(void *));
1869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **values = (void **)malloc(3 * seqlen * sizeof(void *));
1870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
1871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = seq; p; p = p->next) {
1873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_lang_attr_t *lang = (sdp_lang_attr_t *)p->data;
1874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!lang) {
1875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
1879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->code_ISO639;
1880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
1881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
1882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->encoding;
1883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
1884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
1885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->base_offset;
1886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
1887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
1889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen);
1890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq);
1891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(dtds);
1893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
1894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
1895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the "ServiceID" attribute of the service.
1899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is the UUID of the service.
1901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_service_id(sdp_record_t *rec, uuid_t uuid)
1905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid.type) {
1907542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16, &uuid.value.uuid16);
1909542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1910542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1911542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32, &uuid.value.uuid32);
1912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128, &uuid.value.uuid128);
1915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &uuid);
1918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1921542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the GroupID attribute of the service record defining a group.
1922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is the UUID of the group.
1924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_group_id(sdp_record_t *rec, uuid_t uuid)
1928542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1929542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid.type) {
1930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1931542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16, &uuid.value.uuid16);
1932542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1933542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1934542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32, &uuid.value.uuid32);
1935542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128, &uuid.value.uuid128);
1938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &uuid);
1941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the ProfileDescriptorList attribute of the service record
1945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record to the value specified in "profileDesc".
1946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Each element in the list is an object of type
1948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_profile_desc_t which is a definition of the
1949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Bluetooth profile that this service conforms to.
1950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for profileDesc has
1952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
1953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting ProfileDescriptorList
1955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
1956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles)
1960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
1962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid16 = SDP_UUID16;
1963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid32 = SDP_UUID32;
1964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid128 = SDP_UUID128;
1965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uint16 = SDP_UINT16;
1966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i = 0, seqlen = sdp_list_len(profiles);
1967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **seqDTDs = (void **)malloc(seqlen * sizeof(void *));
1968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **seqs = (void **)malloc(seqlen * sizeof(void *));
1969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
1970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = profiles; p; p = p->next) {
1972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *seq;
1973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		void *dtds[2], *values[2];
1974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_profile_desc_t *profile = (sdp_profile_desc_t *)p->data;
1975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!profile) {
1976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		switch (profile->uuid.type) {
1980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID16:
1981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid16;
1982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid16;
1983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID32:
1985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid32;
1986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid32;
1987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID128:
1989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid128;
1990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid128;
1991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		default:
1993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[1] = &uint16;
1997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[1] = &profile->version;
1998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = sdp_seq_alloc(dtds, values, 2);
1999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (seq) {
2000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqDTDs[i] = &seq->dtd;
2001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqs[i] = seq;
2002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_pattern_add_uuid(rec, &profile->uuid);
2003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq);
2009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqDTDs);
2011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqs);
2012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets various URL attributes of the service
2017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record. The URL include
2018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * client: a URL to the client's
2020542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   platform specific (WinCE, PalmOS) executable
2021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   code that can be used to access this service.
2022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * doc: a URL pointing to service documentation
2024542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2025542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * icon: a URL to an icon that can be used to represent
2026542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   this service.
2027542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2028542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Note that you need to pass NULL for any URLs
2029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * that you don't want to set or remove
2030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc, const char *icon)
2032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client);
2034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc);
2035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon);
2036542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2039542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The code in this function is executed only once per
2040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * thread. We compute the actual bit value of the Bluetooth
2041542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * base UUID which is a string defined in bt_std_values.h
2042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * and is assumed to be of the standard form with "-" separators.
2043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The algorithm however converts the string to 4 unsigned longs
2045542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * using the strtoul() and assigns the values in sequence to
2046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * the 128bit value
2047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuint128_t *sdp_create_base_uuid(void)
2049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char baseStr[128];
2051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int delim = '-';
2052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned long dataLongValue;
2053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *delimPtr;
2054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *dataPtr;
2055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char temp[10];
2056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int toBeCopied;
2057cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *data;
2058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (bluetooth_base_uuid == NULL) {
2060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strcpy(baseStr, BASE_UUID);
206121f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann		bluetooth_base_uuid = malloc(sizeof(uint128_t));
2062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data = bluetooth_base_uuid->data;
2063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memset(data, '\0', sizeof(uint128_t));
2064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memset(temp, '\0', 10);
2065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = baseStr;
2066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = NULL;
2067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = strchr(dataPtr, delim);
2068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		toBeCopied = delimPtr - dataPtr;
2069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (toBeCopied != 8) {
2070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("To be copied(1) : %d\n", toBeCopied);
2071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
2072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncpy(temp, dataPtr, toBeCopied);
2074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataLongValue = htonl(strtoul(temp, NULL, 16));
2075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data[0], &dataLongValue, 4);
2076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
2078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Get the next 4 bytes (note that there is a "-"
2079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * between them now)
2080542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
2081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memset(temp, '\0', 10);
2082542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = delimPtr + 1;
2083542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = strchr(dataPtr, delim);
2084542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		toBeCopied = delimPtr - dataPtr;
2085542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (toBeCopied != 4) {
2086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("To be copied(2) : %d\n", toBeCopied);
2087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
2088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncpy(temp, dataPtr, toBeCopied);
2090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = delimPtr + 1;
2091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = strchr(dataPtr, delim);
2092542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		toBeCopied = delimPtr - dataPtr;
2093542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (toBeCopied != 4) {
2094542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("To be copied(3) : %d\n", toBeCopied);
2095542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
2096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2097542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncat(temp, dataPtr, toBeCopied);
2098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataLongValue = htonl(strtoul(temp, NULL, 16));
2099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data[4], &dataLongValue, 4);
2100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
2102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Get the last 4 bytes (note that there are 6 bytes
2103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * after the last separator, which is truncated (2+4)
2104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
2105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memset(temp, '\0', 10);
2106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = delimPtr + 1;
2107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = delimPtr + 1;
2108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = strchr(dataPtr, delim);
2109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		toBeCopied = delimPtr - dataPtr;
2110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (toBeCopied != 4) {
2111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("To be copied(4) : %d\n", toBeCopied);
2112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
2113542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncpy(temp, dataPtr, toBeCopied);
2115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncat(temp, (delimPtr + 1), 4);
2116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataLongValue = htonl(strtoul(temp, NULL, 16));
2117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data[8], &dataLongValue, 4);
2118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataLongValue = htonl(strtoul(delimPtr + 5, NULL, 16));
2119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data[12], &dataLongValue, 4);
2120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return bluetooth_base_uuid;
2122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val)
2125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID16;
2128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->value.uuid16 = val;
2129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val)
2133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID32;
2136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->value.uuid32 = val;
2137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid128_create(uuid_t *u, const void *val)
2141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID128;
2144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&u->value.uuid128, val, sizeof(uint128_t));
2145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function
2150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1
2151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid16_cmp(const void *p1, const void *p2)
2153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const uuid_t *u1 = (const uuid_t *)p1;
2155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const uuid_t *u2 = (const uuid_t *)p2;
2156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t));
2157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function
2161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1
2162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_cmp(const void *p1, const void *p2)
2164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const uuid_t *u1 = (const uuid_t *)p1;
2166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const uuid_t *u2 = (const uuid_t *)p2;
2167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t));
2168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 128 to 16 bit and 32 to 16 bit UUID conversion functions
2172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * yet to be implemented. Note that the input is in NBO in
2173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * both 32 and 128 bit UUIDs and conversion is needed
2174542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid16_to_uuid128(uuid_t *uuid128, uuid_t *uuid16)
2176542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2177542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	/*
2178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * We have a 16 bit value, which needs to be added to
2179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base
2180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 */
2181542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned short data1;
2182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// allocate a 128bit UUID and init to the Bluetooth base UUID
2184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *pBTBase128Bit = sdp_create_base_uuid();
2185542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->value.uuid128 = *pBTBase128Bit;
2186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->type = SDP_UUID128;
2187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// extract bytes 2 and 3 of 128bit BT base UUID
2189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&data1, &pBTBase128Bit->data[2], 2);
2190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add the given UUID (16 bits)
2192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data1 += htons(uuid16->value.uuid16);
2193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// set bytes 2 and 3 of the 128 bit value
2195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&uuid128->value.uuid128.data[2], &data1, 2);
2196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid32_to_uuid128(uuid_t *uuid128, uuid_t *uuid32)
2199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	/*
2201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * We have a 32 bit value, which needs to be added to
2202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base
2203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 */
2204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned int data0;
2205542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// allocate a 128bit UUID and init to the Bluetooth base UUID
2207542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *pBTBase128Bit = sdp_create_base_uuid();
2208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->value.uuid128 = *pBTBase128Bit;
2209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->type = SDP_UUID128;
2210542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2211542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// extract first 4 bytes
2212542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&data0, &pBTBase128Bit->data[0], 4);
2213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2214542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add the given UUID (32bits)
2215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data0 += htonl(uuid32->value.uuid32);
2216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// set the 4 bytes of the 128 bit value
2218542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&uuid128->value.uuid128.data[0], &data0, 4);
2219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid_to_uuid128(uuid_t *uuid)
2222542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
222321f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	uuid_t *uuid128 = bt_malloc(sizeof(uuid_t));
2224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(uuid128, 0, sizeof(uuid_t));
2225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
2226542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
2227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*uuid128 = *uuid;
2228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
2230542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid32_to_uuid128(uuid128, uuid);
2231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
2233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid16_to_uuid128(uuid128, uuid);
2234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid128;
2237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * converts a 128-bit uuid to a 16/32-bit one if possible
2241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns true if uuid contains a 16/32-bit UUID at exit
2242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_to_uuid(uuid_t *uuid)
2244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	extern uint128_t *sdp_create_base_uuid();
2246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i;
2247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *b = sdp_create_base_uuid();
2248542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *u = &uuid->value.uuid128;
2249542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t data;
2250a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid->type != SDP_UUID128)
2252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 1;
2253a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 4; i < sizeof(b->data); i++)
2255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (b->data[i] != u->data[i])
2256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return 0;
2257a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&data, u->data, 4);
2259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data = htonl(data);
2260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (data <= 0xffff) {
2261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->type = SDP_UUID16;
2262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->value.uuid16 = (uint16_t)data;
2263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
2264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->type = SDP_UUID32;
2265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->value.uuid32 = data;
2266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 1;
2268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * convert a UUID to the 16-bit short-form
2272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid_to_proto(uuid_t *uuid)
2274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid_t u = *uuid;
2276a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann	if (sdp_uuid128_to_uuid(&u)) {
2277a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		switch (u.type) {
2278a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		case SDP_UUID16:
2279a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann			return u.value.uuid16;
2280a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		case SDP_UUID32:
2281a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann			return u.value.uuid32;
2282a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		}
2283a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann	}
2284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2287cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_uuid_extract(const uint8_t *p, uuid_t *uuid, int *scanned)
2288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2289aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	uint8_t type = *(const uint8_t *) p;
2290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!SDP_IS_UUID(type)) {
2292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Unknown data type : %d expecting a svc UUID\n", type);
2293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
2296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*scanned += sizeof(uint8_t);
2297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (type == SDP_UUID16) {
2298aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p)));
2299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint16_t);
2300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint16_t);
2301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else if (type == SDP_UUID32) {
2302aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p)));
2303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint32_t);
2304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint32_t);
2305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
2306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid128_create(uuid, p);
2307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint128_t);
2308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint128_t);
2309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function appends data to the PDU buffer "dst" from source "src".
2315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The data length is also computed and set.
2316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Should the PDU length exceed 2^8, then sequence type is
2317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set accordingly and the data is memmove()'d.
2318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2319cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannvoid sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len)
2320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2321cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *p = dst->data;
2322aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	uint8_t dtd = *(uint8_t *) p;
2323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Append src size: %d\n", len);
2325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Append dst size: %d\n", dst->data_size);
2326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Dst buffer size: %d\n", dst->buf_size);
2327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size + len > dst->buf_size) {
2328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int need = SDP_PDU_CHUNK_SIZE * ((len / SDP_PDU_CHUNK_SIZE) + 1);
2329cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann		dst->data = realloc(dst->data, dst->buf_size + need);
2330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Realloc'ing : %d\n", need);
2332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (dst->data == NULL) {
2334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPERR("Realloc fails \n");
2335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->buf_size += need;
2337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size == 0 && dtd == 0) {
2339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// create initial sequence
2340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*(uint8_t *)p = SDP_SEQ8;
2341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
2342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += sizeof(uint8_t);
2343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// reserve space for sequence size
2344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
2345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += sizeof(uint8_t);
2346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(dst->data + dst->data_size, data, len);
2349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dst->data_size += len;
2350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dtd = *(uint8_t *)dst->data;
2352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) {
2353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		short offset = sizeof(uint8_t) + sizeof(uint8_t);
2354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memmove(dst->data + offset + 1, dst->data + offset, dst->data_size - offset);
2355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = dst->data;
2356aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*(uint8_t *) p = SDP_SEQ16;
2357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
2358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += 1;
2359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = dst->data;
2361aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	dtd = *(uint8_t *) p;
2362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
2363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
2364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
2365aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t);
2366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
2368aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *) p);
2369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
2371aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *) p);
2372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d)
2377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2378cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t buf[SDP_SEQ_PDUFORM_SIZE];
2379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t append;
2380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	append.data = buf;
2382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	append.buf_size = sizeof(buf);
2383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	append.data_size = 0;
2384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_set_attrid(&append, d->attrId);
2385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_gen_pdu(&append, d);
2386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_append_to_buf(pdu, append.data, append.data_size);
2387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Registers an sdp record.
2391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * It is incorrect to call this method on a record that
2393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * has been already registered with the server.
2394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
23958b11908eac4e0b4e14534ec2d44ae62806fdfd2fStephen Crane * Returns zero on success, otherwise -1 (and sets errno).
2396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2397a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags)
2398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
2400cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *req, *rsp, *p;
2401cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize, rspsize;
2402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t pdu;
2404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
2408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
2409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2411cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	req = malloc(SDP_REQ_BUFFER_SIZE);
2412cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rsp = malloc(SDP_RSP_BUFFER_SIZE);
2413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (req == NULL || rsp == NULL) {
2414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
241849fe626b5c153e4bc6a174982a89e9b3b2e4baf2Marcel Holtmann	if (rec->handle && rec->handle != 0xffffffff) {
241949fe626b5c153e4bc6a174982a89e9b3b2e4baf2Marcel Holtmann		uint32_t handle = rec->handle;
242049fe626b5c153e4bc6a174982a89e9b3b2e4baf2Marcel Holtmann		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
242149fe626b5c153e4bc6a174982a89e9b3b2e4baf2Marcel Holtmann		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
242249fe626b5c153e4bc6a174982a89e9b3b2e4baf2Marcel Holtmann	}
2423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *)req;
2424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_REGISTER_REQ;
2425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t) + 1;
2427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = req + sizeof(sdp_pdu_hdr_t);
2428fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann	if (bacmp(device, BDADDR_ANY)) {
2429fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		*p++ = flags | SDP_DEVICE_RECORD;
2430fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		bacpy((bdaddr_t *) p, device);
2431fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		p += sizeof(bdaddr_t);
24326db62cfa3a8de69270cc5e5689b633f43c02e041Marcel Holtmann		reqsize += sizeof(bdaddr_t);
2433fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann	} else
2434fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		*p++ = flags;
2435fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
2436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(p, pdu.data, pdu.data_size);
2441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(pdu.data);
2442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += pdu.data_size;
2443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize);
2446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status < 0)
2447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2448aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	rsphdr = (sdp_pdu_hdr_t *) rsp;
2449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = rsp + sizeof(sdp_pdu_hdr_t);
2450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rsphdr->pdu_id == SDP_SVC_REGISTER_RSP) {
2451aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		uint32_t handle  = ntohl(bt_get_unaligned((uint32_t *) p));
2452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
2453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->handle = handle;
2454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
2455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
2457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (req)
2458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(req);
2459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rsp)
2460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rsp);
2461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2464a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags)
2465a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
2466a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_register(session, BDADDR_ANY, rec, flags);
2467a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
2468a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
2469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * unregister a service record
2471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2472a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec)
2473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
2475cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf, *p;
2476cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, rspsize = 0;
2477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t handle = 0;
2479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	handle = rec->handle;
2483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (handle == SDP_SERVER_RECORD_HANDLE) {
2484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
2485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
2488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
2489542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2491cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2492cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2494542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2495542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2496542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2497542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2498aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_REMOVE_REQ;
2500542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = reqbuf + sizeof(sdp_pdu_hdr_t);
2503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2504aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) p);
2505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
2506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2510aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = rspbuf + sizeof(sdp_pdu_hdr_t);
2512aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		status = bt_get_unaligned((uint16_t *) p);
2513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status == 0 && rsphdr->pdu_id == SDP_SVC_REMOVE_RSP) {
2514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Removing local copy\n");
2515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_record_free(rec);
2516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
2519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
2520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
2521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
2522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
2523542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2526a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec)
2527a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
2528a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_unregister(session, BDADDR_ANY, rec);
2529a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
2530a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
2531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * modify an existing service record
2533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2534a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec)
2535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
2537cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf, *p;
2538cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize, rspsize;
2539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t handle;
2541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t pdu;
2542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2544542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	handle = rec->handle;
2545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (handle == SDP_SERVER_RECORD_HANDLE) {
2547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
2548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
2551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
2552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2554cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2555cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2561aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_UPDATE_REQ;
2563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2565cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	p = reqbuf + sizeof(sdp_pdu_hdr_t);
2566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2568aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) p);
2569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
2570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint32_t);
2571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > sdp_gen_record_pdu(rec, &pdu)) {
2573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2574542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2575542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(p, pdu.data, pdu.data_size);
2578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += pdu.data_size;
2579542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2582542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Send req status : %d\n", status);
2584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2586aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = rspbuf + sizeof(sdp_pdu_hdr_t);
2588aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		status = bt_get_unaligned((uint16_t *) p);
2589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
2591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
2592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
2593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
2594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
2595542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2597542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2598a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_update(sdp_session_t *session, const sdp_record_t *rec)
2599a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
2600a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_update(session, BDADDR_ANY, rec);
2601a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
2602a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
2603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_record_t *sdp_record_alloc()
2604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
260521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_record_t *rec = malloc(sizeof(sdp_record_t));
2606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset((void *)rec, 0, sizeof(sdp_record_t));
2607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->handle = 0xffffffff;
2608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
2609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Free the contents of a service record
2613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2614542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_free(sdp_record_t *rec)
2615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(rec->attrlist, (sdp_free_func_t)sdp_data_free);
2617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(rec->pattern, free);
2618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(rec);
2619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid)
2622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid);
2624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("SvcRec : 0x%lx\n", (unsigned long)rec);
2626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
2627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Trying to add : 0x%lx\n", (unsigned long)uuid128);
2628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL)
2630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp);
2631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
263221f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann		bt_free(uuid128);
2633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
2635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq)
2638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; seq; seq = seq->next) {
2640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid_t *uuid = (uuid_t *)seq->data;
2641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_pattern_add_uuid(rec, uuid);
2642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract a sequence of service record handles from a PDU buffer
2647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * and add the entries to a sdp_list_t. Note that the service record
2648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * handles are not in "data element sequence" form, but just like
2649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * an array of service handles
2650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2651cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic void extract_record_handle_seq(uint8_t *pdu, sdp_list_t **seq, int count, int *scanned)
2652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *pSeq = *seq;
2654cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata = pdu;
2655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
2656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (n = 0; n < count; n++) {
265821f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann		uint32_t *pSvcRec = malloc(sizeof(uint32_t));
2659aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata));
2660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pSeq = sdp_list_append(pSeq, pSvcRec);
2661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint32_t);
2662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint32_t);
2663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*seq = pSeq;
2665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Generate the attribute sequence pdu form
2668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * from sdp_list_t elements. Return length of attr seq
2669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2670cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd)
2671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *dataseq;
2673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **types, **values;
2674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t buf;
2675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i, seqlen = sdp_list_len(seq);
2676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// Fill up the value and the dtd arrays
2678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(&buf, 0, sizeof(sdp_buf_t));
2681cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	buf.data = malloc(SDP_UUID_SEQ_SIZE);
2682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf.buf_size = SDP_UUID_SEQ_SIZE;
2683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Seq length : %d\n", seqlen);
2685542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	types = malloc(seqlen * sizeof(void *));
2687542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	values = malloc(seqlen * sizeof(void *));
2688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0; i < seqlen; i++) {
2689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		void *data = seq->data;
2690542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		types[i] = &dtd;
2691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (SDP_IS_UUID(dtd))
2692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			data = &((uuid_t *)data)->value;
2693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = data;
2694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = seq->next;
2695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dataseq = sdp_seq_alloc(types, values, seqlen);
2698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data Seq : 0x%p\n", seq);
2699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = sdp_gen_pdu(&buf, dataseq);
2700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Copying : %d\n", buf.data_size);
2701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(dst, buf.data, buf.data_size);
2702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_free(dataseq);
2704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2705542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(types);
2706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
2707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(buf.data);
2708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seqlen;
2709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2711cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq)
2712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2713cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uuid_t *uuid = (uuid_t *) seq->data;
2714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return gen_dataseq_pdu(dst, seq, uuid->type);
2715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2717cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType)
2718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return gen_dataseq_pdu(dst, seq, dataType);
2720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2722cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int copy_cstate(uint8_t *pdata, const sdp_cstate_t *cstate)
2723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (cstate) {
2725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*pdata++ = cstate->length;
2726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(pdata, cstate->data, cstate->length);
2727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return cstate->length + 1;
2728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*pdata = 0;
2730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 1;
2731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service search request.
2735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
2737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *search_list
2739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing elements of the search
2740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
2741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     of the service to be searched
2742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   uint16_t max_rec_num
2744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      A 16 bit integer which tells the service, the maximum
2745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      entries that the client can handle in the response. The
2746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      server is obliged not to return > max_rec_num entries
2747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
2749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   int return value
2751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
2752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       The request completed successfully. This does not
2753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       mean the requested services were found
2754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     -1:
2755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any failure and sets errno
2756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t **rsp_list
2758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     This variable is set on a successful return if there are
2759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     non-zero service handles. It is a singly linked list of
276028b4f0aea5b15ed7c0acd17ab79705a38ffe7c2fStephen Crane *     service record handles (uint16_t)
2761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search,
2763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			uint16_t max_rec_num, sdp_list_t **rsp)
2764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
2766cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
2767cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0, rsplen;
2768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0;
2769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int scanned, total_rec_count, rec_count;
2770cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
2771cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
2772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
2774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2782aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
2784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
2785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add service class IDs for search
2788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_searchseq_pdu(pdata, search);
2789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data seq added : %d\n", seqlen);
2791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// set the length and increment the pointer
2793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
2794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
2795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2796542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// specify the maximum svc rec count that client expects
2797aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
2798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
2799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
2800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
2802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata   = pdata;
2803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rsp = NULL;
2804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
2806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// Add continuation state or NULL (first time)
2807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata, cstate);
2808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// Set the request header's param length
2810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid  = htons(sdp_gen_tid(session));
2813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
2814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Send the request, wait for response and if
2815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * no error, set the appropriate values and return
2816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
2817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0)
2819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
2820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rsplen = 0;
2822aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rsplen = ntohs(rsphdr->plen);
2824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
2827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
2829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned = 0;
2831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
2832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// net service record match count
2834aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
2835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
2836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
2837aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
2838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
2839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
2840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Total svc count: %d\n", total_rec_count);
2842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Current svc count: %d\n", rec_count);
2843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("ResponseLength: %d\n", rsplen);
2844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!rec_count) {
2846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
2848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		extract_record_handle_seq(pdata, rsp, rec_count, &scanned);
2850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("BytesScanned : %d\n", scanned);
2851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsplen > scanned) {
2853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			uint8_t cstate_len;
2854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned;
2856aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate_len = *(uint8_t *) pdata;
2857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (cstate_len > 0) {
2858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				cstate = (sdp_cstate_t *)pdata;
2859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Cont state length: %d\n", cstate_len);
2860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			} else
2861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				cstate = NULL;
2862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2863542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
2864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann  end:
2866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
2867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
2868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
2869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
2870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service attribute request.
2876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
2878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   uint32_t handle
2880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     The handle of the service for which the attribute(s) are
2881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     requested
2882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_attrreq_type_t reqtype
2884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
2885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     in one of 2 ways described below :
2886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
2887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        They are the actual attribute identifiers in ascending order
2888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
2890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        The high-order 16bits is the start of range
2891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        the low-order 16bits are the end of range
2892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        0x0000 to 0xFFFF gets all attributes
2893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *attrid
2895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing attribute identifiers desired.
2896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
2897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
2898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
2900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   return sdp_record_t *
2901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
2902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any error and sets errno
2903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     !0:
2904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *	 The service record
2905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle,
2907542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_attrreq_type_t reqtype, const sdp_list_t *attrids)
2908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2909542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
2910cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
2911cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0, rsp_count;
2912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int attr_list_len = 0;
2913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0;
2914cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
2915cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
2916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
2918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t cstate_len = 0;
2919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t rsp_concat_buf;
2920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_record_t *rec = 0;
2921542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
2923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
2924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
2925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2927cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2928cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2929542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2931542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2932542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2933542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2934aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	memset((char *) &rsp_concat_buf, 0, sizeof(sdp_buf_t));
2935aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
2937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
2939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add the service record handle
2942aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
2943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
2944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint32_t);
2945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// specify the response limit
2947aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
2948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
2949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
2950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// get attr seq PDU form
2952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrids,
2953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
2954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seqlen == -1) {
2955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
2956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
2960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
2961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Attr list length : %d\n", seqlen);
2962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// save before Continuation State
2964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata = pdata;
2965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
2966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
2968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// add NULL continuation state
2969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata, cstate);
2970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// set the request header's param length
2972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid  = htons(sdp_gen_tid(session));
2973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0)
2977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
2978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rsp_count = 0;
2979aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id);
2982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
2984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
2986aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
2987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		attr_list_len += rsp_count;
2988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
2989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// if continuation state set need to re-issue request before parsing
2991aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		cstate_len = *(uint8_t *) (pdata + rsp_count);
2992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Response id : %d\n", rsphdr->pdu_id);
2994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attrlist byte count : %d\n", rsp_count);
2995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("sdp_cstate_t length : %d\n", cstate_len);
2996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
2998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * a split response: concatenate intermediate responses
2999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * and the last one (which has cstate_len == 0)
3000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
3002cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			uint8_t *targetPtr = NULL;
3003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3004aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
3005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			// build concatenated response buffer
3007cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
3008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
3009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
3010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(targetPtr, pdata, rsp_count);
3011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.data_size += rsp_count;
3012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
3014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (attr_list_len > 0) {
3016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int scanned = 0;
3017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsp_concat_buf.data_size != 0)
3018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rsp_concat_buf.data;
3019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec = sdp_extract_pdu(pdata, &scanned);
3020542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!rec)
3022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
3023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3024542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3025542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann  end:
3026542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
3027542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
3028542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rsp_concat_buf.data)
3029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rsp_concat_buf.data);
3030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
3031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
3032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
3033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
30368be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * SDP transaction structure for asynchronous search
30378be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */
30388be090b298a02108146d3bf48271f8408ac31917Claudio Takahasistruct sdp_transaction {
30398be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	sdp_callback_t *cb;
30408be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	void *udata;
30418be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	sdp_cstate_t *cstate;
30428be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	uint8_t *reqbuf;
30438be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	sdp_buf_t rsp_concat_buf;
30448be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	uint32_t reqsize;
30458be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	int cstate_len;
30468be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	int attr_list_len;
30478be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi};
30488be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
30498be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/*
30508be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * Creates a new sdp session for asynchronous search
30518be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * INPUT:
30528be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  int sk
30538be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *	non-blocking L2CAP socket
30548be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *
30558be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * RETURN:
30568be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  sdp_session_t *
30578be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  NULL - On memory allocation failure
30588be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */
30598be090b298a02108146d3bf48271f8408ac31917Claudio Takahasisdp_session_t *sdp_create(int sk, uint32_t flags)
30608be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi{
30618be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
30628be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	struct sdp_transaction *t;
30638be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	sdp_session_t *session = malloc(sizeof(sdp_session_t));
30648be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!session) {
30658be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		errno = ENOMEM;
30668be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return NULL;
30678be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
30688be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
30698be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	memset(session, 0, sizeof(*session));
30708be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
30718be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->flags = flags;
30728be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->sock = sk;
30738be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
30748be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	t = malloc(sizeof(struct sdp_transaction));
30758be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!t) {
30768be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		errno = ENOMEM;
30778be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		free(session);
30788be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return NULL;
30798be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
30808be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
30818be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	memset(t, 0, sizeof(*t));
30828be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
30838be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->priv = t;
30848be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
30858be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	return session;
30868be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi}
30878be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
30888be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/*
3089dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * Set the callback function to called when the transaction finishes
3090dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *
3091dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * INPUT:
3092dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  sdp_session_t *session
3093dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *	Current sdp session to be handled
3094dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  sdp_callback_t *cb
3095dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *      callback to be called when the transaction finishes
3096dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  void *udata
3097dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *      user data passed to callback
3098dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * RETURN:
3099dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * 	0  - Success
3100dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * 	-1 - Failure
3101dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann */
3102dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmannint sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata)
3103dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann{
3104dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	struct sdp_transaction *t;
3105dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3106dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	if (!session || !session->priv)
3107dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann		return -1;
3108dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3109dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t = session->priv;
3110dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t->cb = func;
3111dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t->udata = udata;
3112dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3113dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	return 0;
3114dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann}
3115dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3116453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmannint sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search_list, uint16_t max_rec_num)
3117453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{
3118453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	/* FIXME: implement! */
3119453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	return 0;
3120453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann}
3121453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3122453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmannint sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
3123453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{
3124453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	/* FIXME: implement! */
3125453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	return 0;
3126453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann}
3127453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3128dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann/*
3129f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * Set the callback function to called when the transaction finishes and send the
3130f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * service search attribute request PDU.
3131f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *
3132f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT:
3133f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *  sdp_session_t *session
3134f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *	Current sdp session to be handled
3135453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3136453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *   sdp_list_t *search
3137453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Singly linked list containing elements of the search
3138453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
3139453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     of the service to be searched
3140453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3141453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *   AttributeSpecification attrSpec
3142453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
3143453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     in one of 2 ways described below :
3144453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3145453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        They are the actual attribute identifiers in ascending order
3146453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3147453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3148453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        The high-order 16bits is the start of range
3149453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        the low-order 16bits are the end of range
3150453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        0x0000 to 0xFFFF gets all attributes
3151453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3152453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *   sdp_list_t *attrids
3153453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Singly linked list containing attribute identifiers desired.
3154453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3155453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3156453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3157453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3158f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN:
3159f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	0  - if the request has been sent properly
3160f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	-1 - On any failure
3161f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */
3162453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmannint sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search_list, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
3163f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{
3164f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	struct sdp_transaction *t;
3165f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3166f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	uint8_t *pdata;
3167f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	int seqlen = 0;
3168f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3169f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (!session || !session->priv) {
3170f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		errno = EINVAL;
3171f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		return -1;
3172f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3173f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3174f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t = session->priv;
3175f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3176f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (!t->reqbuf) {
3177f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		errno = ENOMEM;
3178f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
3179f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3180f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3181f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3182f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	memset((char *)&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
3183f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3184f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3185f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3186f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
3187f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3188f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// generate PDU
3189f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3190f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3191f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3192f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// add service class IDs for search
3193453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	seqlen = gen_searchseq_pdu(pdata, search_list);
3194f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3195f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Data seq added : %d\n", seqlen);
3196f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3197f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// now set the length and increment the pointer
3198f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += seqlen;
3199f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += seqlen;
3200f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3201f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
3202f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += sizeof(uint16_t);
3203f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += sizeof(uint16_t);
3204f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3205f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
3206f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3207f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// get attr seq PDU form
3208453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrid_list,
3209453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann			reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
3210f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (seqlen == -1) {
3211f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		errno = EINVAL;
3212f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
3213f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3214f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3215f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += seqlen;
3216f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Attr list length : %d\n", seqlen);
3217f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += seqlen;
3218f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3219f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// set the request header's param length
3220f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->cstate_len = copy_cstate(pdata, t->cstate);
3221f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3222f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr->plen = htons((t->reqsize + t->cstate_len) - sizeof(sdp_pdu_hdr_t));
3223f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3224f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (sdp_send_req(session, t->reqbuf, t->reqsize + t->cstate_len) < 0) {
3225f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
3226f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
3227f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3228f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3229f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	session->priv = t;
3230f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3231f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	return 0;
3232f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend:
3233f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3234f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (t) {
3235f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (t->reqbuf)
3236f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi			free(t->reqbuf);
3237f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		free(t);
3238f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3239f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3240f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	return -1;
3241f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi}
3242f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3243f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/*
3244f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * Receive the incomming SDP PDU. This function must be called when there is data
3245f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * available to be read. On continuation state, the original request (with a new
3246f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * transaction ID) and the continuation state data will be appended in the initial PDU.
3247f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * If an error happens or the transaction finishes the callback function will be called.
3248f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *
3249f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT:
3250f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *  sdp_session_t *session
3251f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *	Current sdp session to be handled
3252f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN:
3253f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	0  - if the transaction is on continuation state
3254f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	-1 - On any failure or the transaction finished
3255f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */
3256f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiint sdp_process(sdp_session_t *session)
3257f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{
3258f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	struct sdp_transaction *t = NULL;
3259f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	sdp_pdu_hdr_t *reqhdr = NULL;
3260f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	sdp_pdu_hdr_t *rsphdr = NULL;
3261f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	uint8_t *pdata = NULL, *rspbuf = NULL;
3262c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	int rsp_count = 0, err = -1;
3263c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	uint16_t status = 0;
3264f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3265f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (!session || !session->priv) {
3266c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		SDPERR("Invalid session");
3267c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		return -1;
3268f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3269f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3270f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3271c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	if (!rspbuf)
3272c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		return -1;
3273c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi
3274c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE);
3275f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3276f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t = session->priv;
3277f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *)t->reqbuf;
3278f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	rsphdr = (sdp_pdu_hdr_t *)rspbuf;
3279f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3280c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	if (sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE) <= 0)
3281f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
3282f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3283c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	if (reqhdr->tid != rsphdr->tid)
3284f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
3285f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3286f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3287343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi
3288343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi        if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3289c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		status = ntohs(bt_get_unaligned((uint16_t *) pdata));
3290343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi		goto end;
3291343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi	}
3292343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi
3293f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3294f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->attr_list_len += rsp_count;
3295f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += sizeof(uint16_t);      // pdata points to attribute list
3296f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3297f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->cstate_len = *(uint8_t *) (pdata + rsp_count);
3298f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3299f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Attrlist byte count : %d\n", t->attr_list_len);
3300f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Response byte count : %d\n", rsp_count);
3301f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Cstate length : %d\n", t->cstate_len);
3302f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	/*
3303f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	 * This is a split response, need to concatenate intermediate
3304f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	 * responses and the last one which will have cstate_len == 0
3305f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	 */
3306f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (t->cstate_len > 0 || t->rsp_concat_buf.data_size != 0) {
3307f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		uint8_t *targetPtr = NULL;
3308f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3309f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		t->cstate = t->cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
3310f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3311f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		// build concatenated response buffer
3312f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count);
3313f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size;
3314f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count;
3315f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		memcpy(targetPtr, pdata, rsp_count);
3316f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		t->rsp_concat_buf.data_size += rsp_count;
3317f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3318f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3319f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (t->cstate) {
3320f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		int reqsize;
3321f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		reqhdr->tid = htons(sdp_gen_tid(session));
3322f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3323f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		// add continuation state (can be null)
3324f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		t->cstate_len = copy_cstate(t->reqbuf + t->reqsize, t->cstate);
3325f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3326f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		reqsize = t->reqsize + t->cstate_len;
3327f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3328f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		// set the request header's param length
3329f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3330f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3331f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (sdp_send_req(session, t->reqbuf, reqsize) < 0) {
3332c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi			SDPERR("Error sendind data:%s", strerror(errno));
3333f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi			goto end;
3334f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		}
3335c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		err = 0;
3336f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3337f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3338f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend:
3339c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	if (err) {
3340f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (t->rsp_concat_buf.data_size != 0)
3341f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi			pdata = t->rsp_concat_buf.data;
3342f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3343f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (t->cb)
3344c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi			t->cb(rsphdr->pdu_id, status, pdata,
3345f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi				t->attr_list_len, t->udata);
3346f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3347f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3348f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (rspbuf)
3349f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		free(rspbuf);
3350f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3351c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	return err;
3352f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi}
3353f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3354f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/*
3355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service search request combined with the service
3356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attribute request. First a service class match is done and
3357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * for matching service, requested attributes are extracted
3358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
3360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *search
3362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing elements of the search
3363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
3364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     of the service to be searched
3365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   AttributeSpecification attrSpec
3367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
3368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     in one of 2 ways described below :
3369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        They are the actual attribute identifiers in ascending order
3371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        The high-order 16bits is the start of range
3374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        the low-order 16bits are the end of range
3375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        0x0000 to 0xFFFF gets all attributes
3376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *attrids
3378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing attribute identifiers desired.
3379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
3383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   int return value
3384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
3385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       The request completed successfully. This does not
3386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       mean the requested services were found
3387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     -1:
3388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any error and sets errno
3389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t **rsp
3391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     This variable is set on a successful return to point to
3392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     service(s) found. Each element of this list is of type
3393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     sdp_record_t* (of the services which matched the search list)
3394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint 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)
3396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
3398cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
3399cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0;
3400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0, attr_list_len = 0;
3401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int rsp_count = 0, cstate_len = 0;
3402cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
3403cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
3404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dataType;
3406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *rec_list = NULL;
3407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t rsp_concat_buf;
3408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
3409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
3411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
3412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
3413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3414cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3415cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
3417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
3419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t));
3423aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
3425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// generate PDU
3427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
3429542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add service class IDs for search
3431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_searchseq_pdu(pdata, search);
3432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data seq added : %d\n", seqlen);
3434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// now set the length and increment the pointer
3436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
3437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
3438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3439aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
3440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
3441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
3442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
3444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// get attr seq PDU form
3446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrids,
3447aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
3448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seqlen == -1) {
3449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = EINVAL;
3450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
3453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Attr list length : %d\n", seqlen);
3454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
3455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rsp = 0;
3456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// save before Continuation State
3458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata = pdata;
3459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
3460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
3462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid = htons(sdp_gen_tid(session));
3463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// add continuation state (can be null)
3465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata, cstate);
3466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// set the request header's param length
3468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3469aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0) {
3472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
3473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
3478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3482aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		attr_list_len += rsp_count;
3484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);	// pdata points to attribute list
3485aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		cstate_len = *(uint8_t *) (pdata + rsp_count);
3486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attrlist byte count : %d\n", attr_list_len);
3488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Response byte count : %d\n", rsp_count);
3489542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Cstate length : %d\n", cstate_len);
3490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
3491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * This is a split response, need to concatenate intermediate
3492542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * responses and the last one which will have cstate_len == 0
3493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3494542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
3495cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			uint8_t *targetPtr = NULL;
3496542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3497aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
3498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			// build concatenated response buffer
3500cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
3501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
3502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
3503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(targetPtr, pdata, rsp_count);
3504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.data_size += rsp_count;
3505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
3507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (attr_list_len > 0) {
3509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int scanned = 0;
3510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsp_concat_buf.data_size != 0)
3512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rsp_concat_buf.data;
3513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
3515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Response is a sequence of sequence(s) for one or
3516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * more data element sequence(s) representing services
3517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * for which attributes are returned
3518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned = sdp_extract_seqtype(pdata, &dataType, &seqlen);
3520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Bytes scanned : %d\n", scanned);
3522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Seq length : %d\n", seqlen);
3523542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (scanned && seqlen) {
3525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata += scanned;
3526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			do {
3527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				int recsize = 0;
3528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				sdp_record_t *rec = sdp_extract_pdu(pdata, &recsize);
3529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				if (rec == NULL) {
3530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					SDPERR("SVC REC is null\n");
3531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					status = -1;
3532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					goto end;
3533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				}
35348db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann				if (!recsize) {
35358db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann					sdp_record_free(rec);
35368db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann					break;
35378db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann				}
3538542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				scanned += recsize;
3539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				pdata += recsize;
3540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Loc seq length : %d\n", recsize);
3542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle);
3543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Bytes scanned : %d\n", scanned);
3544542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Attrlist byte count : %d\n", attr_list_len);
3545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				rec_list = sdp_list_append(rec_list, rec);
3546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			} while (scanned < attr_list_len);
3547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Successful scan of service attr lists\n");
3549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*rsp = rec_list;
3550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann  end:
3553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rsp_concat_buf.data)
3554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rsp_concat_buf.data);
3555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
3556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
3557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
3558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
3559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
3560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Find devices in the piconet.
3564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3565542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found)
3566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0);
3568542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (n < 0) {
3569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Inquiry failed:%s", strerror(errno));
3570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
3571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*found = n;
3573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
3574542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3575542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_close(sdp_session_t *session)
3577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
35788be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	struct sdp_transaction *t;
35798be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	int ret;
35808be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
35818be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!session)
35828be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return -1;
35838be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
35848be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	ret = close(session->sock);
35858be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
35868be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	t = session->priv;
35878be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
35888be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (t) {
35898be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		if (t->reqbuf)
35908be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi			free(t->reqbuf);
35918be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
35928be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		if (t->rsp_concat_buf.data)
35938be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi			free(t->rsp_concat_buf.data);
35948be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
35958be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		free(t);
35968be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
3597542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(session);
3598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return ret;
3599542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3600542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3601542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int sdp_is_local(const bdaddr_t *device)
3602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0;
3604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3605542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t flags)
3607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
360812862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann	int err;
3609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_session_t *session = malloc(sizeof(sdp_session_t));
3610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session)
3611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return session;
3612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(session, 0, sizeof(*session));
3613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	session->flags = flags;
3614542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdp_is_local(dst)) {
3615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		struct sockaddr_un sa;
3616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// create local unix connection
3618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		session->sock = socket(PF_UNIX, SOCK_STREAM, 0);
3619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		session->local = 1;
3620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (session->sock >= 0) {
3621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sa.sun_family = AF_UNIX;
3622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			strcpy(sa.sun_path, SDP_UNIX_PATH);
3623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)) == 0)
3624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return session;
3625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
3627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		struct sockaddr_l2 sa;
3628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// create L2CAP connection
3630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
3631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		session->local = 0;
3632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (session->sock >= 0) {
3633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sa.l2_family = AF_BLUETOOTH;
3634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sa.l2_psm = 0;
3635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (bacmp(src, BDADDR_ANY) != 0) {
3636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				sa.l2_bdaddr = *src;
36370a2a889c91f9b671b7c31bcb6e4e53daf306fb7eMarcel Holtmann				if (bind(session->sock, (struct sockaddr *) &sa, sizeof(sa)) < 0)
3638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					goto fail;
3639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
36400a2a889c91f9b671b7c31bcb6e4e53daf306fb7eMarcel Holtmann			if (flags & SDP_WAIT_ON_CLOSE) {
36410a2a889c91f9b671b7c31bcb6e4e53daf306fb7eMarcel Holtmann				struct linger l = { .l_onoff = 1, .l_linger = 1 };
36420a2a889c91f9b671b7c31bcb6e4e53daf306fb7eMarcel Holtmann				setsockopt(session->sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
36430a2a889c91f9b671b7c31bcb6e4e53daf306fb7eMarcel Holtmann			}
3644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sa.l2_psm = htobs(SDP_PSM);
3645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sa.l2_bdaddr = *dst;
3646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			do
36470a2a889c91f9b671b7c31bcb6e4e53daf306fb7eMarcel Holtmann				if (connect(session->sock, (struct sockaddr *) &sa, sizeof(sa)) == 0)
3648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					return session;
3649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY));
3650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3651542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail:
365312862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann	err = errno;
3654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (session->sock >= 0)
3655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		close(session->sock);
3656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(session);
365712862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann	errno = err;
3658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
3659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
36608f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann
36618f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannint sdp_get_socket(const sdp_session_t *session)
36628f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{
36638f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann	return session->sock;
36648f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann}
36658f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann
36668f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannuint16_t sdp_gen_tid(sdp_session_t *session)
36678f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{
36688f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann	return session->tid++;
36698f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann}
3670