sdp.c revision 82817924a25fb0eaaeb9824372106870c45c9db9
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>
341be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim#include <fcntl.h>
35542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <stdlib.h>
36542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <malloc.h>
37654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#include <syslog.h>
38542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <sys/un.h>
39542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <sys/socket.h>
408bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann#include <sys/time.h>
418bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann#include <sys/types.h>
42542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4351e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/bluetooth.h>
4451e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/hci.h>
4551e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/hci_lib.h>
4651e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/l2cap.h>
4751e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/sdp.h>
4851e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/sdp_lib.h>
49654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
50654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#include <netinet/in.h>
51654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
52654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg)
53654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg)
54654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
55654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#ifdef SDP_DEBUG
56654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg)
57654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#else
58654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPDBG(fmt...)
59654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#endif
60654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
61654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#if __BYTE_ORDER == __BIG_ENDIAN
62654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define ntoh64(x) (x)
63654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmannstatic inline void ntoh128(uint128_t *src, uint128_t *dst)
64654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann{
65654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	int i;
66654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	for (i = 0; i < 16; i++)
67654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann		dst->data[i] = src->data[i];
68654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann}
69654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#else
70654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmannstatic inline uint64_t ntoh64(uint64_t n)
71654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann{
72654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	uint64_t h;
73654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
74654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	h = ntohl(n >> 32);
75654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	h |= tmp << 32;
76654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	return h;
77654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann}
78654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmannstatic inline void ntoh128(uint128_t *src, uint128_t *dst)
79654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann{
80654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	int i;
81654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann	for (i = 0; i < 16; i++)
82654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann		dst->data[15 - i] = src->data[i];
83654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann}
84654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#endif
85654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
86654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define hton64(x)     ntoh64(x)
87654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define hton128(x, y) ntoh128(x, y)
88542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
89542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB"
90542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
91542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic uint128_t *bluetooth_base_uuid = NULL;
92542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
93654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDP_MAX_ATTR_LEN 65535
94654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
95542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* Message structure. */
96542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstruct tupla {
97542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int index;
98542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *str;
99542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann};
100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic struct tupla Protocol[] = {
1026864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SDP_UUID,		"SDP"		},
1036864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDP_UUID,		"UDP"		},
1046864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ RFCOMM_UUID,		"RFCOMM"	},
1056864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ TCP_UUID,		"TCP"		},
1066864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ TCS_BIN_UUID,		"TCS-BIN"	},
1076864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ TCS_AT_UUID,		"TCS-AT"	},
1086864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ OBEX_UUID,		"OBEX"		},
1096864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IP_UUID,		"IP"		},
1106864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ FTP_UUID,		"FTP"		},
1116864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HTTP_UUID,		"HTTP"		},
1126864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ WSP_UUID,		"WSP"		},
1136864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ BNEP_UUID,		"BNEP"		},
1146864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_UUID,		"UPNP"		},
1156864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HIDP_UUID,		"HIDP"		},
1166864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCRP_CTRL_UUID,	"HCRP-Ctrl"	},
1176864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCRP_DATA_UUID,	"HCRP-Data"	},
1186864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCRP_NOTE_UUID,	"HCRP-Notify"	},
1196864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AVCTP_UUID,		"AVCTP"		},
1206864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AVDTP_UUID,		"AVDTP"		},
1216864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ CMTP_UUID,		"CMTP"		},
1226864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDI_UUID,		"UDI"		},
1236864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ L2CAP_UUID,		"L2CAP"		},
124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	{ 0 }
125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann};
126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic struct tupla ServiceClass[] = {
1286864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SDP_SERVER_SVCLASS_ID,		"SDP Server"			},
1296864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ BROWSE_GRP_DESC_SVCLASS_ID,		"Browse Group Descriptor"	},
1306864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PUBLIC_BROWSE_GROUP,			"Public Browse Group"		},
1316864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SERIAL_PORT_SVCLASS_ID,		"Serial Port"			},
1326864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ LAN_ACCESS_SVCLASS_ID,		"LAN Access Using PPP"		},
1336864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ DIALUP_NET_SVCLASS_ID,		"Dialup Networking"		},
1346864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IRMC_SYNC_SVCLASS_ID,			"IrMC Sync"			},
1356864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ OBEX_OBJPUSH_SVCLASS_ID,		"OBEX Object Push"		},
1366864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ OBEX_FILETRANS_SVCLASS_ID,		"OBEX File Transfer"		},
1376864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IRMC_SYNC_CMD_SVCLASS_ID,		"IrMC Sync Command"		},
1386864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HEADSET_SVCLASS_ID,			"Headset"			},
1396864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ CORDLESS_TELEPHONY_SVCLASS_ID,	"Cordless Telephony"		},
1406864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AUDIO_SOURCE_SVCLASS_ID,		"Audio Source"			},
1416864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AUDIO_SINK_SVCLASS_ID,		"Audio Sink"			},
1426864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AV_REMOTE_TARGET_SVCLASS_ID,		"AV Remote Target"		},
1436864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ ADVANCED_AUDIO_SVCLASS_ID,		"Advanced Audio"		},
1446864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AV_REMOTE_SVCLASS_ID,			"AV Remote"			},
1456864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_CONF_SVCLASS_ID,		"Video Conferencing"		},
1466864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ INTERCOM_SVCLASS_ID,			"Intercom"			},
1476864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ FAX_SVCLASS_ID,			"Fax"				},
1486864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HEADSET_AGW_SVCLASS_ID,		"Headset Audio Gateway"		},
1496864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ WAP_SVCLASS_ID,			"WAP"				},
1506864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ WAP_CLIENT_SVCLASS_ID,		"WAP Client"			},
1516864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PANU_SVCLASS_ID,			"PAN User"			},
1526864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ NAP_SVCLASS_ID,			"Network Access Point"		},
1536864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GN_SVCLASS_ID,			"PAN Group Network"		},
1546864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ DIRECT_PRINTING_SVCLASS_ID,		"Direct Printing"		},
1556864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ REFERENCE_PRINTING_SVCLASS_ID,	"Reference Printing"		},
1566864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_SVCLASS_ID,			"Imaging"			},
1576864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_RESPONDER_SVCLASS_ID,		"Imaging Responder"		},
1586864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_ARCHIVE_SVCLASS_ID,		"Imaging Automatic Archive"	},
1596864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_REFOBJS_SVCLASS_ID,		"Imaging Referenced Objects"	},
1606864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HANDSFREE_SVCLASS_ID,			"Handsfree"			},
1616864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HANDSFREE_AGW_SVCLASS_ID,		"Handfree Audio Gateway"	},
1626864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ DIRECT_PRT_REFOBJS_SVCLASS_ID,	"Direct Printing Ref. Objects"	},
1636864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ REFLECTED_UI_SVCLASS_ID,		"Reflected UI"			},
1646864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ BASIC_PRINTING_SVCLASS_ID,		"Basic Printing"		},
1656864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PRINTING_STATUS_SVCLASS_ID,		"Printing Status"		},
1666864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HID_SVCLASS_ID,			"Human Interface Device"	},
1676864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCR_SVCLASS_ID,			"Hardcopy Cable Replacement"	},
1686864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCR_PRINT_SVCLASS_ID,			"HCR Print"			},
1696864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCR_SCAN_SVCLASS_ID,			"HCR Scan"			},
1706864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ CIP_SVCLASS_ID,			"Common ISDN Access"		},
1716864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_CONF_GW_SVCLASS_ID,		"Video Conferencing Gateway"	},
1726864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDI_MT_SVCLASS_ID,			"UDI MT"			},
1736864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDI_TA_SVCLASS_ID,			"UDI TA"			},
1746864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AV_SVCLASS_ID,			"Audio/Video"			},
1756864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SAP_SVCLASS_ID,			"SIM Access"			},
1768ce8108e712e40e1b9530c96f7ff6cbb32b5cb8bMarcel Holtmann	{ PBAP_PCE_SVCLASS_ID,			"Phonebook Access - PCE"	},
1778ce8108e712e40e1b9530c96f7ff6cbb32b5cb8bMarcel Holtmann	{ PBAP_PSE_SVCLASS_ID,			"Phonebook Access - PSE"	},
17873f2fe893f6801358ea4fb88dc8d24050c7d0ca5Marcel Holtmann	{ PBAP_SVCLASS_ID,			"Phonebook Access"		},
1796864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PNP_INFO_SVCLASS_ID,			"PnP Information"		},
1806864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_NETWORKING_SVCLASS_ID,	"Generic Networking"		},
1816864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_FILETRANS_SVCLASS_ID,		"Generic File Transfer"		},
1826864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_AUDIO_SVCLASS_ID,		"Generic Audio"			},
1836864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_TELEPHONY_SVCLASS_ID,		"Generic Telephony"		},
1846864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_SVCLASS_ID,			"UPnP"				},
1856864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_IP_SVCLASS_ID,			"UPnP IP"			},
1866864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_PAN_SVCLASS_ID,			"UPnP PAN"			},
1876864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_LAP_SVCLASS_ID,			"UPnP LAP"			},
1886864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_L2CAP_SVCLASS_ID,		"UPnP L2CAP"			},
1896864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_SOURCE_SVCLASS_ID,		"Video Source"			},
1906864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_SINK_SVCLASS_ID,		"Video Sink"			},
1912fa38208982e7c7bb55ae97acd13dbf82dd24e88Marcel Holtmann	{ VIDEO_DISTRIBUTION_SVCLASS_ID,	"Video Distribution"		},
19242e0ce5b430ac5e36c0d21bdddcaf1fe83e025f5Marcel Holtmann	{ APPLE_AGENT_SVCLASS_ID,		"Apple Agent"			},
193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	{ 0 }
194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann};
195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1966864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann#define Profile ServiceClass
197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic char *string_lookup(struct tupla *pt0, int index)
199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	struct tupla *pt;
2016864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (pt = pt0; pt->index; pt++)
2036864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann		if (pt->index == index)
204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return pt->str;
2056864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return "";
207542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2093df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmannstatic char *string_lookup_uuid(struct tupla *pt0, const uuid_t* uuid)
2103df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann{
2113df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	uuid_t tmp_uuid;
2123df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
2133df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid));
2143df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
2153df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	if (sdp_uuid128_to_uuid(&tmp_uuid)) {
2163df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		switch (tmp_uuid.type) {
2173df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		case SDP_UUID16:
2183df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann			return string_lookup(pt0, tmp_uuid.value.uuid16);
2193df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		case SDP_UUID32:
2203df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann			return string_lookup(pt0, tmp_uuid.value.uuid32);
2213df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		}
2223df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	}
2233df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
2243df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	return "";
2253df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann}
2263df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Prints into a string the Protocol UUID
229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * coping a maximum of n characters.
230542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n)
232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *str2;
234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!uuid) {
236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "NULL");
237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -2;
238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2396864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		str2 = string_lookup(message, uuid->value.uuid16);
243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, str2);
244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
2460e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann		str2 = string_lookup(message, uuid->value.uuid32);
2470e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann		snprintf(str, n, str2);
2480e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann		break;
249542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
2503df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		str2 = string_lookup_uuid(message, uuid);
2513df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		snprintf(str, n, str2);
2523df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		break;
253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2576864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n)
262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid2str(Protocol, uuid, str, n);
264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n)
267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid2str(ServiceClass, uuid, str, n);
269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n)
272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid2str(Profile, uuid, str, n);
274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * convert the UUID to string, copying a maximum of n characters.
278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n)
280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!uuid) {
282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "NULL");
283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -2;
284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "%.4x", uuid->value.uuid16);
288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "%.8x", uuid->value.uuid32);
291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:{
293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int   data0;
294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data1;
295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data2;
296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data3;
297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int   data4;
298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data5;
299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				ntohl(data0), ntohs(data1),
309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				ntohs(data2), ntohs(data3),
310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				ntohl(data4), ntohs(data5));
311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;	// Enum type of UUID not set
316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Function prints the UUID in hex as per defined syntax -
323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 4bytes-2bytes-2bytes-2bytes-6bytes
325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * There is some ugly code, including hardcoding, but
327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * that is just the way it is converting 16 and 32 bit
328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUIDs to 128 bit as defined in the SDP doc
329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid_print(const uuid_t *uuid)
331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid == NULL) {
333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Null passed to print UUID\n");
334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return;
335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid->type == SDP_UUID16) {
337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("  uint16_t : 0x%.4x\n", uuid->value.uuid16);
338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else if (uuid->type == SDP_UUID32) {
339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("  uint32_t : 0x%.8x\n", uuid->value.uuid32);
340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else if (uuid->type == SDP_UUID128) {
341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int data0;
342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data1;
343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data2;
344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data3;
345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int data4;
346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data5;
347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("  uint128_t : 0x%.8x-", ntohl(data0));
356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x-", ntohs(data1));
357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x-", ntohs(data2));
358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x-", ntohs(data3));
359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.8x", ntohl(data4));
360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x\n", ntohs(data5));
361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else
362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Enum type of UUID not set\n");
363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
366641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, uint32_t length)
367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *seq;
36921f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!d)
372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->dtd = dtd;
376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->unitSize = sizeof(uint8_t);
377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
382aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint8 = *(uint8_t *) value;
383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint8_t);
384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
387aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int8 = *(int8_t *) value;
388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int8_t);
389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
391aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint16 = bt_get_unaligned((uint16_t *) value);
392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint16_t);
393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
395aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int16 = bt_get_unaligned((int16_t *) value);
396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int16_t);
397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
399aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint32 = bt_get_unaligned((uint32_t *) value);
400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint32_t);
401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
403aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int32 = bt_get_unaligned((int32_t *) value);
404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int32_t);
405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
407aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int64 = bt_get_unaligned((int64_t *) value);
408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int64_t);
409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
411aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint64 = bt_get_unaligned((uint64_t *) value);
412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint64_t);
413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&d->val.uint128.data, value, sizeof(uint128_t));
416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint128_t);
417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&d->val.int128.data, value, sizeof(uint128_t));
420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint128_t);
421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
423aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value));
424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint16_t);
425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
427aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value));
428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint32_t);
429542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid128_create(&d->val.uuid, value);
432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint128_t);
433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
436641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_TEXT_STR8:
437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
438641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (!value) {
439641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			free(d);
440641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			return NULL;
441641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		}
442641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
443641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		d->unitSize += length;
444641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (length <= USHRT_MAX) {
445641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			d->val.str = malloc(length);
446641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			if (!d->val.str) {
447641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann				free(d);
448641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann				return NULL;
449641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			}
450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
451641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			memcpy(d->val.str, value, length);
452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		} else {
453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPERR("Strings of size > USHRT_MAX not supported\n");
454641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			free(d);
455641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			d = NULL;
456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Strings of size > USHRT_MAX not supported\n");
461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (dtd == SDP_ALT8 || dtd == SDP_SEQ8)
469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += sizeof(uint8_t);
470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16)
471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += sizeof(uint16_t);
472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32)
473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += sizeof(uint32_t);
474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = (sdp_data_t *)value;
475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->val.dataseq = seq;
476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (; seq; seq = seq->next)
477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += seq->unitSize;
478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
480641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		free(d);
481641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		d = NULL;
482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
483641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
485641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann}
486641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
487641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value)
488641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann{
489641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	uint32_t length;
490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
491641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	switch (dtd) {
492641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR8:
493641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR16:
494641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_TEXT_STR8:
495641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_TEXT_STR16:
496641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (!value)
497641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			return NULL;
498641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
499641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		length = strlen((char *) value);
500641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		break;
501641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	default:
502641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		length = 0;
503641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		break;
504641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	}
505641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
506641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	return sdp_data_alloc_with_length(dtd, value, length);
507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d)
510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seq) {
512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *p;
513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = seq; p->next; p = p->next);
514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p->next = d;
515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else
516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = d;
517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->next = NULL;
518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seq;
519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
521641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length, int len)
522641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann{
523641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	sdp_data_t *curr = NULL, *seq = NULL;
524641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	int i;
525641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
526641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	for (i = 0; i < len; i++) {
527641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		sdp_data_t *data;
528641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		int8_t dtd = *(uint8_t *) dtds[i];
529641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
530641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
531641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			data = (sdp_data_t *) values[i];
532641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		else
533641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			data = sdp_data_alloc_with_length(dtd, values[i], length[i]);
534641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
535641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (!data)
536641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			return NULL;
537641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
538641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (curr)
539641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			curr->next = data;
540641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		else
541641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			seq = data;
542641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
543641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		curr = data;
544641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	}
545641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
546641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	return sdp_data_alloc_with_length(SDP_SEQ8, seq, length[i]);
547641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann}
548641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len)
550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *curr = NULL, *seq = NULL;
552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i;
553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0; i < len; i++) {
555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data;
556641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		uint8_t dtd = *(uint8_t *) dtds[i];
557641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
559641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			data = (sdp_data_t *) values[i];
560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			data = sdp_data_alloc(dtd, values[i]);
562641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!data)
564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
565641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (curr)
567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			curr->next = data;
568542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seq = data;
570641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		curr = data;
572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
573641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
574542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return sdp_data_alloc(SDP_SEQ8, seq);
575542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
579542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *p = sdp_data_get(rec, attr);
580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (p)
582542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->attrId = attr;
584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_attr_remove(sdp_record_t *rec, uint16_t attr)
589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_get(rec, attr);
591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->attrlist = sdp_list_remove(rec->attrlist, d);
593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
595cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannvoid sdp_set_seq_len(uint8_t *ptr, uint32_t length)
596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
597aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	uint8_t dtd = *(uint8_t *) ptr++;
598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
599542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
600542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
601542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
604aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*(uint8_t *)ptr = (uint8_t) length;
605542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
610aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htons(length), (uint16_t *) ptr);
611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
614542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
616aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htonl(length), (uint32_t *) ptr);
617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd)
622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int orig = buf->data_size;
624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t *p = buf->data + buf->data_size;
625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*p++ = dtd;
627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf->data_size += sizeof(uint8_t);
628641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		buf->data_size += sizeof(uint8_t);
635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		buf->data_size += sizeof(uint16_t);
641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		buf->data_size += sizeof(uint32_t);
647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
649641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return buf->data_size - orig;
651542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_attrid(sdp_buf_t *buf, uint16_t attr)
654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t *p = buf->data;
656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// data type for attr
658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*p++ = SDP_UINT16;
659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf->data_size = sizeof(uint8_t);
660aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(attr), (uint16_t *) p);
661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint16_t);
662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf->data_size += sizeof(uint16_t);
663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata)
666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d;
668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = 0;
669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (d = sdpdata->val.dataseq; d; d = d->next)
671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += sdp_gen_pdu(buf, d);
672641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return n;
674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
678cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t pdu_size = 0, data_size = 0;
679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned char *src = NULL, is_seq = 0, is_alt = 0;
680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd = d->dtd;
681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint16_t u16;
682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t u32;
683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint64_t u64;
684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t u128;
685cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *seqp = buf->data + buf->data_size;
686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
687542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdu_size = sdp_set_data_type(buf, dtd);
688641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
690542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = &d->val.uint8;
694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint8_t);
695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.uint16);
698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u16;
699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint16_t);
700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.uint32);
703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u32;
704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint32_t);
705542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u64 = hton64(d->val.uint64);
708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u64;
709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint64_t);
710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
711542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		hton128(&d->val.uint128, &u128);
713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u128;
714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint128_t);
715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&d->val.int8;
719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(int8_t);
720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
722542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.int16);
723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u16;
724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(int16_t);
725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.int32);
728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u32;
729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(int32_t);
730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u64 = hton64(d->val.int64);
733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u64;
734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(int64_t);
735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		hton128(&d->val.int128, &u128);
738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u128;
739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint128_t);
740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
744641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		src = (unsigned char *)d->val.str;
745641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		data_size = d->unitSize - sizeof(uint8_t);
746641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		sdp_set_seq_len(seqp, data_size);
747641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		break;
748641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR8:
749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)d->val.str;
752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = strlen(d->val.str);
753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		is_seq = 1;
759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = get_data_size(buf, d);
760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		is_alt = 1;
766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = get_data_size(buf, d);
767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.uuid.value.uuid16);
771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u16;
772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint16_t);
773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.uuid.value.uuid32);
776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&u32;
777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint32_t);
778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = (unsigned char *)&d->val.uuid.value.uuid128;
781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_size = sizeof(uint128_t);
782542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
786641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!is_seq && !is_alt) {
788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (src && buf) {
789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(buf->data + buf->data_size, src, data_size);
790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			buf->data_size += data_size;
791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		} else if (dtd != SDP_DATA_NIL)
792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Gen PDU : Cant copy from NULL source or dest\n");
793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
794641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdu_size += data_size;
796641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return pdu_size;
798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void sdp_attr_pdu(void *value, void *udata)
801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);
803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf)
806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
807cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	buf->data = malloc(SDP_PDU_CHUNK_SIZE);
808997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	if (!buf->data)
809997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann		return -ENOMEM;
810997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann
811997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	buf->buf_size = SDP_PDU_CHUNK_SIZE;
812997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	buf->data_size = 0;
813997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	memset(buf->data, 0, buf->buf_size);
814997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf);
815997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann
816997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	return 0;
817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *p = sdp_data_get(rec, attr);
822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (p) {
824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->attrlist = sdp_list_remove(rec->attrlist, p);
825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_free(p);
826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->attrId = attr;
828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, (void *)d, sdp_attrid_comp_func);
829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attrid_comp_func(const void *key1, const void *key2)
832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_data_t *d1 = (const sdp_data_t *)key1;
834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_data_t *d2 = (const sdp_data_t *)key2;
835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d1 && d2)
837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return d1->attrId - d2->attrId;
838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void data_seq_free(sdp_data_t *seq)
842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = seq->val.dataseq;
844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (d) {
846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *next = d->next;
847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_free(d);
848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d = next;
849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_free(sdp_data_t *d)
853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_seq_free(d);
859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
863542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d->val.str);
867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(d);
870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *extract_int(const void *p, int *len)
873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
87421f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting integer\n");
877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
878aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += sizeof(uint8_t);
881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint8_t);
889aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint8 = *(uint8_t *) p;
890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint16_t);
894aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p));
895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint32_t);
899aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p));
900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint64_t);
904aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p));
905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
907542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint128_t);
909aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		ntoh128((uint128_t *) p, &d->val.uint128);
910542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
911542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d = NULL;
914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
918cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic sdp_data_t *extract_uuid(const uint8_t *p, int *len, sdp_record_t *rec)
919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
92021f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
921542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting UUID");
923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
92421f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	if (sdp_uuid_extract(p, &d->val.uuid, len) < 0) {
925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
928aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
929542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &d->val.uuid);
930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
931542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
932542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
933542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
934542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract strings from the PDU (could be service description and similar info)
935542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *extract_str(const void *p, int *len)
937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *s;
939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
94021f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
943aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += sizeof(uint8_t);
946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
950aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		n = *(uint8_t *) p;
951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint8_t) + n;
953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
956aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		n = ntohs(bt_get_unaligned((uint16_t *) p));
957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint16_t);
958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint16_t) + n;
959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Sizeof text string > UINT16_MAX\n");
962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
966ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann	s = malloc(n + 1);
967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(s, 0, n + 1);
968ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann	memcpy(s, p, n);
969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Len : %d\n", n);
971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Str : %s\n", s);
972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->val.str = s;
9740ed4f8572e1b32b4dd57304db14351f0e0c59119Marcel Holtmann	d->unitSize = n + sizeof(uint8_t);
975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec)
979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen, n = 0;
981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *curr, *prev;
98221f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting SEQ");
985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len = sdp_extract_seqtype(p, &d->dtd, &seqlen);
987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen);
988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (*len == 0)
990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return d;
991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += *len;
993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	curr = prev = NULL;
994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (n < seqlen) {
995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int attrlen = 0;
996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		curr = sdp_extract_attr(p, &attrlen, rec);
997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (curr == NULL)
998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (prev)
1001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			prev->next = curr;
1002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
1003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->val.dataseq = curr;
1004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		prev = curr;
1005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += attrlen;
1006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += attrlen;
1007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen);
1009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += n;
1012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1015cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannsdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec)
1016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *elem;
1018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = 0;
1019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd = *(const uint8_t *)p;
1020542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("extract_attr: dtd=0x%x", dtd);
1022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
1023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1024542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1025542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1026542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1027542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1028542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		elem = extract_int(p, &n);
1036542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1039542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		elem = extract_uuid(p, &n, rec);
1041542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
1045542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
1048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		elem = extract_str(p, &n);
1049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		elem = extract_seq(p, &n, rec);
1057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd);
1060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
1061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*size += n;
1063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return elem;
1064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void attr_print_func(void *value, void *userData)
1068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = (sdp_data_t *)value;
1070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("=====================================\n");
1072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n",  d->attrId);
1073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value);
1074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
1075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_print(d);
1076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
1077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("NULL value\n");
1078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("=====================================\n");
1079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1080542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_print_service_attr(sdp_list_t *svcAttrList)
1082542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
10838bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann	SDPDBG("Printing service attr list %p\n", svcAttrList);
1084542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_foreach(svcAttrList, attr_print_func, NULL);
10858bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann	SDPDBG("Printed service attr list %p\n", svcAttrList);
1086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1089cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannsdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned)
1090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int extracted = 0, seqlen = 0;
1092542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd;
1093542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint16_t attr;
1094542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_record_t *rec = sdp_record_alloc();
1095cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	const uint8_t *p = buf;
1096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1097542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*scanned = sdp_extract_seqtype(buf, &dtd, &seqlen);
1098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += *scanned;
1099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->attrlist = NULL;
1100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (extracted < seqlen) {
1101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int n = sizeof(uint8_t), attrlen = 0;
1102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data = NULL;
1103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, extracted);
1105aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		dtd = *(uint8_t *) p;
1106aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		attr = ntohs(bt_get_unaligned((uint16_t *) (p + n)));
1107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += sizeof(uint16_t);
1108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr);
1110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1111aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		data = sdp_extract_attr(p + n, &attrlen, rec);
1112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1113542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen);
1114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += attrlen;
1116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (data == NULL) {
1117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Terminating extraction of attributes");
1118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (attr == SDP_ATTR_RECORD_HANDLE)
1121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rec->handle = data->val.uint32;
1122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		extracted += n;
1123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += n;
1124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, attr, data);
1125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",
1126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					seqlen, extracted);
1127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Successful extracting of Svc Rec attributes\n");
1130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_print_service_attr(rec->attrlist);
1131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*scanned += seqlen;
1133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
1134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void print_dataseq(sdp_data_t *p)
1138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d;
1140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (d = p; d; d = d->next)
1142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_print(d);
1143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_print(const sdp_record_t *rec)
1147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
1149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
11506d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann		printf("Service Name: %.*s\n", d->unitSize, d->val.str);
1151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
1152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
11536d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann		printf("Service Description: %.*s\n", d->unitSize, d->val.str);
1154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
1155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
11566d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann		printf("Service Provider: %.*s\n", d->unitSize, d->val.str);
1157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_print(sdp_data_t *d)
1161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
1163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("NIL\n");
1165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1174542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1176542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1177542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Integer : 0x%x\n", d->val.uint32);
1178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1181542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("UUID\n");
1183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid_print(&d->val.uuid);
1184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1185542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
1188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Text : %s\n", d->val.str);
1189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
1193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("URL : %s\n", d->val.str);
1194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		print_dataseq(d->val.dataseq);
1199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Data Sequence Alternates\n");
1204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		print_dataseq(d->val.dataseq);
1205542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1207542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1210542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId)
1211542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1212542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rec->attrlist) {
1213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t sdpTemplate;
1214542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpTemplate.attrId = attrId;
1217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func);
1218542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (p)
1219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return (sdp_data_t *)p->data;
1220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1222542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract the sequence type and its length, and return offset into buf
1226542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * or 0 on failure.
1227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1228cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_extract_seqtype(const uint8_t *buf, uint8_t *dtdp, int *size)
1229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1230aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	uint8_t dtd = *(uint8_t *) buf;
1231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int scanned = sizeof(uint8_t);
1232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf += sizeof(uint8_t);
1234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*dtdp = dtd;
1235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
1236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1238aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*size = *(uint8_t *) buf;
1239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint8_t);
1240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1243aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*size = ntohs(bt_get_unaligned((uint16_t *) buf));
1244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
1245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1248aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*size = ntohl(bt_get_unaligned((uint32_t *) buf));
1249542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint32_t);
1250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Unknown sequence type, aborting\n");
1253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return scanned;
1256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1258cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size)
1259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1260cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t sent = 0;
1261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (sent < size) {
1263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int n = send(session->sock, buf + sent, size - sent, 0);
1264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (n < 0)
1265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return -1;
1266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sent += n;
1267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1271cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size)
1272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	fd_set readFds;
1274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 };
1275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
127673fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann	FD_ZERO(&readFds);
1277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	FD_SET(session->sock, &readFds);
1278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Waiting for response\n");
127973fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann	if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) {
1280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Client timed out\n");
1281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ETIMEDOUT;
1282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return recv(session->sock, buf, size, 0);
1285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * generic send request, wait for response method.
1289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1290cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf, uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize)
1291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
1293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)reqbuf;
1294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *)rspbuf;
1295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
1297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > sdp_send_req(session, reqbuf, reqsize)) {
1298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Error sending data:%s", strerror(errno));
1299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
1302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > n)
1303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Read : %d\n", n);
1305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (n == 0 || reqhdr->tid != rsphdr->tid) {
1306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EPROTO;
1307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rspsize = n;
1310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * singly-linked lists (after openobex implementation)
1315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_append(sdp_list_t *p, void *d)
1317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
131821f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_list_t *q, *n = malloc(sizeof(sdp_list_t));
1319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!n)
1321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->data = d;
1324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->next = 0;
1325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!p)
1327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return n;
1328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = p; q->next; q = q->next);
1330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	q->next = n;
1331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return p;
1333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_remove(sdp_list_t *list, void *d)
1336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p, *q;
1338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = 0, p = list; p; q = p, p = p->next)
1340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (p->data == d) {
1341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (q)
1342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				q->next = p->next;
1343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			else
1344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				list = p->next;
1345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			free(p);
1346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return list;
1350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d, sdp_comp_func_t f)
1353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *q, *p, *n;
1355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
135621f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	n = malloc(sizeof(sdp_list_t));
1357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!n)
1358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->data = d;
1360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = 0, p = list; p; q = p, p = p->next)
1361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (f(p->data, d) >= 0)
1362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// insert between q and p; if !q insert at head
1364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (q)
1365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		q->next = n;
1366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
1367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		list = n;
1368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->next = p;
1369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return list;
1370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Every element of the list points to things which need
1374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to be free()'d. This method frees the list's contents
1375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_list_free(sdp_list_t *list, sdp_free_func_t f)
1377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *next;
1379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (list) {
1380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		next = list->next;
1381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (f)
1382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			f(list->data);
1383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(list);
1384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		list = next;
1385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int __find_port(sdp_data_t *seq, int proto)
1389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!seq || !seq->next)
1391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) {
1394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = seq->next;
1395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		switch (seq->dtd) {
1396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UINT8:
1397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return seq->val.uint8;
1398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UINT16:
1399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return seq->val.uint16;
1400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_proto_port(const sdp_list_t *list, int proto)
1406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (proto != L2CAP_UUID && proto != RFCOMM_UUID) {
1408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
1409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; list; list = list->next) {
1413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = list->data; p; p = p->next) {
1415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_data_t *seq = (sdp_data_t *) p->data;
1416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			int port = __find_port(seq, proto);
1417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (port)
1418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return port;
1419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto)
1425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; list; list = list->next) {
1427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = list->data; p; p = p->next) {
1429542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_data_t *seq = (sdp_data_t *) p->data;
1430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (SDP_IS_UUID(seq->dtd) &&
1431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					sdp_uuid_to_proto(&seq->val.uuid) == proto)
1432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return seq->next;
1433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return NULL;
1436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *pdlist, *curr;
1441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *ap = 0;
1442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdlist = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
1444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (pdlist == NULL) {
1445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; pdlist; pdlist = pdlist->next) {
1451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *pds = 0;
1452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pds = sdp_list_append(pds, curr->val.dataseq);
1454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		ap = sdp_list_append(ap, pds);
1455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*pap = ap;
1457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1460233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmannint sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1461233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann{
1462233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	sdp_data_t *pdlist, *curr;
1463233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	sdp_list_t *ap = 0;
1464233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1465233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
1466233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	if (pdlist == NULL) {
1467233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		errno = ENODATA;
1468233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		return -1;
1469233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	}
1470233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1471233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1472233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	pdlist = pdlist->val.dataseq;
1473233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1474233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	for (; pdlist; pdlist = pdlist->next) {
1475233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		sdp_list_t *pds = 0;
1476233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1477233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann			pds = sdp_list_append(pds, curr->val.dataseq);
1478233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		ap = sdp_list_append(ap, pds);
1479233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	}
1480233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	*pap = ap;
1481233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	return 0;
1482233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann}
1483233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **seqp)
1485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attr);
1487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*seqp = NULL;
1489542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) {
1490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *d;
1491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (d = sdpdata->val.dataseq; d; d = d->next) {
149221f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann			uuid_t *u = malloc(sizeof(uuid_t));
1493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memset((char *)u, 0, sizeof(uuid_t));
1494542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (d->dtd >= SDP_UUID16 && d->dtd <= SDP_UUID128) {
1495542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			  	*u = d->val.uuid;
1496542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			  	*seqp = sdp_list_append(*seqp, u);
1497542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			} else
1498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				goto fail;
1499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1500542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail:
1503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(*seqp, free);
1504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
1505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq)
1509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0, i, len;
1511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **dtds, **values;
1512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid16 = SDP_UUID16;
1513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid32 = SDP_UUID32;
1514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid128 = SDP_UUID128;
1515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p;
1516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	len = sdp_list_len(seq);
1518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!seq || len == 0)
1519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dtds = (void **)malloc(len * sizeof(void *));
1521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	values = (void **)malloc(len * sizeof(void *));
1522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = seq, i = 0; i < len; i++, p = p->next) {
1523542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid_t *uuid = (uuid_t *)p->data;
1524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (uuid)
1525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			switch (uuid->type) {
1526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID16:
1527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid16;
1528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid16;
1529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID32:
1531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid32;
1532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid32;
1533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1534542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID128:
1535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid128;
1536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid128;
1537542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1538542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			default:
1539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				status = -1;
1540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
1542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else {
1543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1544542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
1548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data = sdp_seq_alloc(dtds, values, len);
1549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, aid, data);
1550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_pattern_add_uuidseq(rec, seq);
1551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(dtds);
1553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
1554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
1555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq)
1558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_lang_attr_t *lang;
1560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata, *curr_data;
1561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*langSeq = NULL;
1563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST);
1564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata == NULL) {
1565542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1568542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	curr_data = sdpdata->val.dataseq;
1569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (curr_data) {
1570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pCode = curr_data;
1571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pEncoding = pCode->next;
1572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pOffset = pEncoding->next;
1573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (pCode && pEncoding && pOffset) {
157421f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann			lang = malloc(sizeof(sdp_lang_attr_t));
1575542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			lang->code_ISO639 = pCode->val.uint16;
1576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			lang->encoding = pEncoding->val.uint16;
1577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			lang->base_offset = pOffset->val.uint16;
1578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("code_ISO639 :  0x%02x\n", lang->code_ISO639);
1579542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("encoding :     0x%02x\n", lang->encoding);
1580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("base_offfset : 0x%02x\n", lang->base_offset);
1581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*langSeq = sdp_list_append(*langSeq, lang);
1582542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		curr_data = pOffset->next;
1584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq)
1589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_profile_desc_t *profDesc;
1591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata, *seq;
1592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*profDescSeq = NULL;
1594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST);
1595542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!sdpdata || !sdpdata->val.dataseq) {
1596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1597542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1599542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) {
16000f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		uuid_t *uuid = NULL;
16010f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		uint16_t version = 0x100;
16020f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann
16030f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		if (SDP_IS_UUID(seq->dtd)) {
16040f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			uuid = &seq->val.uuid;
16050f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		} else {
16060f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			sdp_data_t *puuid = seq->val.dataseq;
16070f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			sdp_data_t *pVnum = seq->val.dataseq->next;
16080f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			if (puuid && pVnum) {
16090f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann				uuid = &puuid->val.uuid;
16100f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann				version = pVnum->val.uint16;
16110f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			}
16120f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		}
16130f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann
16140f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		if (uuid != NULL) {
161521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann			profDesc = malloc(sizeof(sdp_profile_desc_t));
16160f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			profDesc->uuid = *uuid;
16170f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			profDesc->version = version;
1618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_uuid_print(&profDesc->uuid);
1620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Vnum : 0x%04x\n", profDesc->version);
1621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*profDescSeq = sdp_list_append(*profDescSeq, profDesc);
1623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16)
1629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d, *curr;
1631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*u16 = NULL;
1633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST);
1634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d == NULL) {
1635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (curr = d->val.dataseq; curr; curr = curr->next)
1639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*u16 = sdp_list_append(*u16, &curr->val.uint16);
1640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* flexible extraction of basic attributes - Jean II */
1644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* How do we expect caller to extract predefined data sequences? */
1645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value)
1646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
1648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata)
1650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/* Verify that it is what the caller expects */
1651542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 ||
1652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 ||
1653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 ||
1654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_INT32) {
1655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*value = sdpdata->val.uint32;
1656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return 0;
1657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
1659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value, int valuelen)
1663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
1665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata)
1666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/* Verify that it is what the caller expects */
1667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (sdpdata->dtd == SDP_TEXT_STR8 || sdpdata->dtd == SDP_TEXT_STR16 || sdpdata->dtd == SDP_TEXT_STR32)
1668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (strlen(sdpdata->val.str) < valuelen) {
1669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				strcpy(value, sdpdata->val.str);
1670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return 0;
1671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
1672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
1673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#define get_basic_attr(attrID, pAttrValue, fieldName)		\
1677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *data = sdp_data_get(rec, attrID);		\
1678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (data) {						\
1679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*pAttrValue = data->val.fieldName;		\
1680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;					\
1681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}							\
1682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;						\
1683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1685542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid)
1686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1687542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);
1688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1690542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid)
1691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);
1693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState)
1696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);
1698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail)
1701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);
1703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1705542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo)
1706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);
1708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState)
1711542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);
1713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * NOTE that none of the setXXX() functions below will
1717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * actually update the SDP server, unless the
1718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * {register, update}sdp_record_t() function is invoked.
1719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd, const void *value)
1722542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_alloc(dtd, value);
1724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d) {
1725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, attr, d);
1726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Set the information attributes of the service
1733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by rec. The attributes are
1734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * service name, description and provider name
1735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov, const char *desc)
1737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (name)
1739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY, SDP_TEXT_STR8, (void *)name);
1740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (prov)
1741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY, SDP_TEXT_STR8, (void *)prov);
1742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (desc)
1743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY, SDP_TEXT_STR8, (void *)desc);
1744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto)
1747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *seq = NULL;
1749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void *dtds[10], *values[10];
1750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **seqDTDs, **seqs;
1751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i, seqlen;
1752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p;
1753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = sdp_list_len(proto);
1755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqDTDs = (void **)malloc(seqlen * sizeof(void *));
1756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqs = (void **)malloc(seqlen * sizeof(void *));
1757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0, p = proto; p; p = p->next, i++) {
1758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *elt = (sdp_list_t *)p->data;
1759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *s;
1760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int pslen = 0;
1761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (; elt && pslen < sizeof(dtds); elt = elt->next, pslen++) {
1762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_data_t *d = (sdp_data_t *)elt->data;
1763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[pslen] = &d->dtd;
1764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			switch (d->dtd) {
1765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID16:
1766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &((uuid_t *)d)->value.uuid16;
1767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID32:
1769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &((uuid_t *)d)->value.uuid32;
1770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID128:
1772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &((uuid_t *)d)->value.uuid128;
1773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UINT8:
1775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &d->val.uint8;
1776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UINT16:
1778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &d->val.uint16;
1779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ8:
1781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ16:
1782542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ32:
1783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = d;
1784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			// FIXME: more
1786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
1787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		s = sdp_seq_alloc(dtds, values, pslen);
1789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (s) {
1790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqDTDs[i] = &s->dtd;
1791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqs[i] = s;
1792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
1795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqDTDs);
1796542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqs);
1797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seq;
1798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets the access protocols of the service specified
1802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to the value specified in "access_proto"
1803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Note that if there are alternate mechanisms by
1805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * which the service is accessed, then they should
1806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * be specified as sequences
1807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for accessProtocols has
1809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
1810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the existing sdp_access_proto_t
1812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
1813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
1817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
1819aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_data_t *protos = NULL;
1820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = ap; p; p = p->next) {
1822aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann		sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data);
1823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		protos = sdp_seq_append(protos, seq);
1824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1825aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos);
1827aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1828aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	return 0;
1829aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann}
1830aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1831aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmannint sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
1832aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann{
1833aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	const sdp_list_t *p;
1834aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_data_t *protos = NULL;
1835aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1836aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	for (p = ap; p; p = p->next) {
1837aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann		sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data);
1838aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann		protos = sdp_seq_append(protos, seq);
1839aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	}
1840aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1841aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST,
1842aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann			protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL);
1843aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
1844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the "LanguageBase" attributes of the service record
1849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * record to the value specified in "langAttrList".
1850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * "langAttrList" is a linked list of "sdp_lang_attr_t"
1852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * objects, one for each language in which user visible
1853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attributes are present in the service record.
1854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for langAttrList has
1856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
1857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting sdp_lang_attr_t
1859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
1860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1863542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq)
1864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uint16 = SDP_UINT16;
1866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0, i = 0, seqlen = sdp_list_len(seq);
1867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **dtds = (void **)malloc(3 * seqlen * sizeof(void *));
1868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **values = (void **)malloc(3 * seqlen * sizeof(void *));
1869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
1870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = seq; p; p = p->next) {
1872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_lang_attr_t *lang = (sdp_lang_attr_t *)p->data;
1873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!lang) {
1874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
1878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->code_ISO639;
1879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
1880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
1881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->encoding;
1882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
1883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
1884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->base_offset;
1885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
1886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
1888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen);
1889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq);
1890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(dtds);
1892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
1893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
1894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the "ServiceID" attribute of the service.
1898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is the UUID of the service.
1900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_service_id(sdp_record_t *rec, uuid_t uuid)
1904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid.type) {
1906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1907542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16, &uuid.value.uuid16);
1908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1909542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1910542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32, &uuid.value.uuid32);
1911542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128, &uuid.value.uuid128);
1914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &uuid);
1917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the GroupID attribute of the service record defining a group.
1921542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is the UUID of the group.
1923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_group_id(sdp_record_t *rec, uuid_t uuid)
1927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1928542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid.type) {
1929542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16, &uuid.value.uuid16);
1931542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1932542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1933542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32, &uuid.value.uuid32);
1934542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1935542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128, &uuid.value.uuid128);
1937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &uuid);
1940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the ProfileDescriptorList attribute of the service record
1944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record to the value specified in "profileDesc".
1945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Each element in the list is an object of type
1947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_profile_desc_t which is a definition of the
1948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Bluetooth profile that this service conforms to.
1949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for profileDesc has
1951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
1952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting ProfileDescriptorList
1954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
1955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
1956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
1957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles)
1959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
1961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid16 = SDP_UUID16;
1962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid32 = SDP_UUID32;
1963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid128 = SDP_UUID128;
1964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uint16 = SDP_UINT16;
1965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i = 0, seqlen = sdp_list_len(profiles);
1966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **seqDTDs = (void **)malloc(seqlen * sizeof(void *));
1967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **seqs = (void **)malloc(seqlen * sizeof(void *));
1968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
1969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = profiles; p; p = p->next) {
1971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *seq;
1972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		void *dtds[2], *values[2];
1973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_profile_desc_t *profile = (sdp_profile_desc_t *)p->data;
1974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!profile) {
1975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		switch (profile->uuid.type) {
1979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID16:
1980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid16;
1981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid16;
1982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID32:
1984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid32;
1985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid32;
1986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID128:
1988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid128;
1989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid128;
1990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		default:
1992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[1] = &uint16;
1996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[1] = &profile->version;
1997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = sdp_seq_alloc(dtds, values, 2);
1998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (seq) {
1999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqDTDs[i] = &seq->dtd;
2000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqs[i] = seq;
2001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_pattern_add_uuid(rec, &profile->uuid);
2002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq);
2008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqDTDs);
2010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqs);
2011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets various URL attributes of the service
2016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record. The URL include
2017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * client: a URL to the client's
2019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   platform specific (WinCE, PalmOS) executable
2020542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   code that can be used to access this service.
2021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * doc: a URL pointing to service documentation
2023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2024542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * icon: a URL to an icon that can be used to represent
2025542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   this service.
2026542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2027542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Note that you need to pass NULL for any URLs
2028542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * that you don't want to set or remove
2029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc, const char *icon)
2031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client);
2033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc);
2034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon);
2035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2036542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The code in this function is executed only once per
2039542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * thread. We compute the actual bit value of the Bluetooth
2040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * base UUID which is a string defined in bt_std_values.h
2041542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * and is assumed to be of the standard form with "-" separators.
2042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The algorithm however converts the string to 4 unsigned longs
2044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * using the strtoul() and assigns the values in sequence to
2045542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * the 128bit value
2046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuint128_t *sdp_create_base_uuid(void)
2048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char baseStr[128];
2050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int delim = '-';
2051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned long dataLongValue;
2052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *delimPtr;
2053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *dataPtr;
2054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char temp[10];
2055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int toBeCopied;
2056cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *data;
2057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (bluetooth_base_uuid == NULL) {
2059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strcpy(baseStr, BASE_UUID);
206021f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann		bluetooth_base_uuid = malloc(sizeof(uint128_t));
2061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data = bluetooth_base_uuid->data;
2062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memset(data, '\0', sizeof(uint128_t));
2063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memset(temp, '\0', 10);
2064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = baseStr;
2065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = NULL;
2066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = strchr(dataPtr, delim);
2067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		toBeCopied = delimPtr - dataPtr;
2068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (toBeCopied != 8) {
2069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("To be copied(1) : %d\n", toBeCopied);
2070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
2071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncpy(temp, dataPtr, toBeCopied);
2073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataLongValue = htonl(strtoul(temp, NULL, 16));
2074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data[0], &dataLongValue, 4);
2075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
2077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Get the next 4 bytes (note that there is a "-"
2078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * between them now)
2079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
2080542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memset(temp, '\0', 10);
2081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = delimPtr + 1;
2082542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = strchr(dataPtr, delim);
2083542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		toBeCopied = delimPtr - dataPtr;
2084542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (toBeCopied != 4) {
2085542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("To be copied(2) : %d\n", toBeCopied);
2086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
2087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncpy(temp, dataPtr, toBeCopied);
2089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = delimPtr + 1;
2090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = strchr(dataPtr, delim);
2091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		toBeCopied = delimPtr - dataPtr;
2092542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (toBeCopied != 4) {
2093542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("To be copied(3) : %d\n", toBeCopied);
2094542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
2095542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncat(temp, dataPtr, toBeCopied);
2097542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataLongValue = htonl(strtoul(temp, NULL, 16));
2098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data[4], &dataLongValue, 4);
2099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
2101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Get the last 4 bytes (note that there are 6 bytes
2102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * after the last separator, which is truncated (2+4)
2103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
2104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memset(temp, '\0', 10);
2105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = delimPtr + 1;
2106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataPtr = delimPtr + 1;
2107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		delimPtr = strchr(dataPtr, delim);
2108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		toBeCopied = delimPtr - dataPtr;
2109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (toBeCopied != 4) {
2110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("To be copied(4) : %d\n", toBeCopied);
2111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
2112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2113542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncpy(temp, dataPtr, toBeCopied);
2114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		strncat(temp, (delimPtr + 1), 4);
2115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataLongValue = htonl(strtoul(temp, NULL, 16));
2116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data[8], &dataLongValue, 4);
2117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dataLongValue = htonl(strtoul(delimPtr + 5, NULL, 16));
2118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data[12], &dataLongValue, 4);
2119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return bluetooth_base_uuid;
2121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val)
2124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID16;
2127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->value.uuid16 = val;
2128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val)
2132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID32;
2135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->value.uuid32 = val;
2136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid128_create(uuid_t *u, const void *val)
2140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID128;
2143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&u->value.uuid128, val, sizeof(uint128_t));
2144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function
2149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1
2150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid16_cmp(const void *p1, const void *p2)
2152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const uuid_t *u1 = (const uuid_t *)p1;
2154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const uuid_t *u2 = (const uuid_t *)p2;
2155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t));
2156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function
2160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1
2161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_cmp(const void *p1, const void *p2)
2163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const uuid_t *u1 = (const uuid_t *)p1;
2165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const uuid_t *u2 = (const uuid_t *)p2;
2166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t));
2167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 128 to 16 bit and 32 to 16 bit UUID conversion functions
2171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * yet to be implemented. Note that the input is in NBO in
2172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * both 32 and 128 bit UUIDs and conversion is needed
2173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2174542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid16_to_uuid128(uuid_t *uuid128, uuid_t *uuid16)
2175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2176542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	/*
2177542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * We have a 16 bit value, which needs to be added to
2178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base
2179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 */
2180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned short data1;
2181542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// allocate a 128bit UUID and init to the Bluetooth base UUID
2183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *pBTBase128Bit = sdp_create_base_uuid();
2184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->value.uuid128 = *pBTBase128Bit;
2185542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->type = SDP_UUID128;
2186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// extract bytes 2 and 3 of 128bit BT base UUID
2188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&data1, &pBTBase128Bit->data[2], 2);
2189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add the given UUID (16 bits)
2191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data1 += htons(uuid16->value.uuid16);
2192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// set bytes 2 and 3 of the 128 bit value
2194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&uuid128->value.uuid128.data[2], &data1, 2);
2195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid32_to_uuid128(uuid_t *uuid128, uuid_t *uuid32)
2198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	/*
2200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * We have a 32 bit value, which needs to be added to
2201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base
2202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 */
2203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned int data0;
2204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2205542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// allocate a 128bit UUID and init to the Bluetooth base UUID
2206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *pBTBase128Bit = sdp_create_base_uuid();
2207542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->value.uuid128 = *pBTBase128Bit;
2208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->type = SDP_UUID128;
2209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2210542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// extract first 4 bytes
2211542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&data0, &pBTBase128Bit->data[0], 4);
2212542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add the given UUID (32bits)
2214542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data0 += htonl(uuid32->value.uuid32);
2215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// set the 4 bytes of the 128 bit value
2217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&uuid128->value.uuid128.data[0], &data0, 4);
2218542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid_to_uuid128(uuid_t *uuid)
2221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
222221f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	uuid_t *uuid128 = bt_malloc(sizeof(uuid_t));
2223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(uuid128, 0, sizeof(uuid_t));
2224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
2225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
2226542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*uuid128 = *uuid;
2227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
2229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid32_to_uuid128(uuid128, uuid);
2230542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
2232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid16_to_uuid128(uuid128, uuid);
2233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid128;
2236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * converts a 128-bit uuid to a 16/32-bit one if possible
2240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns true if uuid contains a 16/32-bit UUID at exit
2241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_to_uuid(uuid_t *uuid)
2243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	extern uint128_t *sdp_create_base_uuid();
2245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i;
2246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *b = sdp_create_base_uuid();
2247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *u = &uuid->value.uuid128;
2248542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t data;
2249a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid->type != SDP_UUID128)
2251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 1;
2252a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 4; i < sizeof(b->data); i++)
2254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (b->data[i] != u->data[i])
2255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return 0;
2256a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&data, u->data, 4);
2258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data = htonl(data);
2259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (data <= 0xffff) {
2260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->type = SDP_UUID16;
2261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->value.uuid16 = (uint16_t)data;
2262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
2263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->type = SDP_UUID32;
2264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->value.uuid32 = data;
2265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 1;
2267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * convert a UUID to the 16-bit short-form
2271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid_to_proto(uuid_t *uuid)
2273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid_t u = *uuid;
2275a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann	if (sdp_uuid128_to_uuid(&u)) {
2276a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		switch (u.type) {
2277a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		case SDP_UUID16:
2278a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann			return u.value.uuid16;
2279a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		case SDP_UUID32:
2280a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann			return u.value.uuid32;
2281a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		}
2282a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann	}
2283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2286cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_uuid_extract(const uint8_t *p, uuid_t *uuid, int *scanned)
2287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2288aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	uint8_t type = *(const uint8_t *) p;
2289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!SDP_IS_UUID(type)) {
2291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Unknown data type : %d expecting a svc UUID\n", type);
2292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
2295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*scanned += sizeof(uint8_t);
2296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (type == SDP_UUID16) {
2297aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p)));
2298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint16_t);
2299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint16_t);
2300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else if (type == SDP_UUID32) {
2301aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p)));
2302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint32_t);
2303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint32_t);
2304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
2305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid128_create(uuid, p);
2306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint128_t);
2307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint128_t);
2308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function appends data to the PDU buffer "dst" from source "src".
2314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The data length is also computed and set.
2315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Should the PDU length exceed 2^8, then sequence type is
2316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set accordingly and the data is memmove()'d.
2317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2318cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannvoid sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len)
2319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2320cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *p = dst->data;
2321aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	uint8_t dtd = *(uint8_t *) p;
2322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Append src size: %d\n", len);
2324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Append dst size: %d\n", dst->data_size);
2325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Dst buffer size: %d\n", dst->buf_size);
2326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size + len > dst->buf_size) {
2327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int need = SDP_PDU_CHUNK_SIZE * ((len / SDP_PDU_CHUNK_SIZE) + 1);
2328cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann		dst->data = realloc(dst->data, dst->buf_size + need);
2329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Realloc'ing : %d\n", need);
2331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (dst->data == NULL) {
2333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPERR("Realloc fails \n");
2334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->buf_size += need;
2336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size == 0 && dtd == 0) {
2338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// create initial sequence
2339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*(uint8_t *)p = SDP_SEQ8;
2340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
2341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += sizeof(uint8_t);
2342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// reserve space for sequence size
2343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
2344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += sizeof(uint8_t);
2345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(dst->data + dst->data_size, data, len);
2348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dst->data_size += len;
2349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dtd = *(uint8_t *)dst->data;
2351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) {
2352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		short offset = sizeof(uint8_t) + sizeof(uint8_t);
2353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memmove(dst->data + offset + 1, dst->data + offset, dst->data_size - offset);
2354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = dst->data;
2355aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*(uint8_t *) p = SDP_SEQ16;
2356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
2357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += 1;
2358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = dst->data;
2360aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	dtd = *(uint8_t *) p;
2361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
2362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
2363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
2364aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t);
2365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
2367aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *) p);
2368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
2370aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *) p);
2371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d)
2376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2377997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	uint8_t buf[256];
2378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t append;
2379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2380997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	memset(&append, 0, sizeof(sdp_buf_t));
2381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	append.data = buf;
2382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	append.buf_size = sizeof(buf);
2383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	append.data_size = 0;
2384997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann
2385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_set_attrid(&append, d->attrId);
2386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_gen_pdu(&append, d);
2387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_append_to_buf(pdu, append.data, append.data_size);
2388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Registers an sdp record.
2392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * It is incorrect to call this method on a record that
2394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * has been already registered with the server.
2395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
23968b11908eac4e0b4e14534ec2d44ae62806fdfd2fStephen Crane * Returns zero on success, otherwise -1 (and sets errno).
2397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
239882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, uint8_t *data, uint32_t size, uint8_t flags, uint32_t *handle)
2399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2400cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *req, *rsp, *p;
2401cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize, rspsize;
2402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
240382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int status;
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	}
241882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *)req;
2420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_REGISTER_REQ;
2421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t) + 1;
2423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = req + sizeof(sdp_pdu_hdr_t);
242482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2425fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann	if (bacmp(device, BDADDR_ANY)) {
2426fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		*p++ = flags | SDP_DEVICE_RECORD;
2427fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		bacpy((bdaddr_t *) p, device);
2428fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		p += sizeof(bdaddr_t);
24296db62cfa3a8de69270cc5e5689b633f43c02e041Marcel Holtmann		reqsize += sizeof(bdaddr_t);
2430fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann	} else
2431fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		*p++ = flags;
243282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
243382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	memcpy(p, data, size);
243482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	reqsize += size;
2435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize);
2438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status < 0)
2439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
244082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2441aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	rsphdr = (sdp_pdu_hdr_t *) rsp;
2442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = rsp + sizeof(sdp_pdu_hdr_t);
244382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rsphdr->pdu_id == SDP_SVC_REGISTER_RSP) {
244582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		if (handle)
244682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann			*handle  = ntohl(bt_get_unaligned((uint32_t *) p));
2447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
244882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
2450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (req)
2451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(req);
245282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rsp)
2454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rsp);
245582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
245982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags)
246082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{
246182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	sdp_buf_t pdu;
246282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	uint32_t handle;
246382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int err;
246482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
246582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	SDPDBG("");
246682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
246782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (rec->handle && rec->handle != 0xffffffff) {
246882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		uint32_t handle = rec->handle;
246982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
247082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
247182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	}
247282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
247382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
247482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		errno = ENOMEM;
247582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		return -1;
247682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	}
247782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
247882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	err = sdp_device_record_register_binary(session, device,
247982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann				pdu.data, pdu.data_size, flags, &handle);
248082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
248182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	free(pdu.data);
248282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
248382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (err == 0) {
248482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
248582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		rec->handle = handle;
248682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
248782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	}
248882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
248982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	return err;
249082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann}
249182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2492a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags)
2493a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
2494a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_register(session, BDADDR_ANY, rec, flags);
2495a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
2496a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
2497542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * unregister a service record
2499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
250082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle)
2501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2502cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf, *p;
2503cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, rspsize = 0;
2504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
250582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int status;
2506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (handle == SDP_SERVER_RECORD_HANDLE) {
2510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
2511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
251382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
2515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
2516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
251882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2519cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2520cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2523542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2526aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_REMOVE_REQ;
2528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = reqbuf + sizeof(sdp_pdu_hdr_t);
2531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2532aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) p);
2533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
2534542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2537542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2538aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = rspbuf + sizeof(sdp_pdu_hdr_t);
2540aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		status = bt_get_unaligned((uint16_t *) p);
254182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		if (status != 0 || rsphdr->pdu_id != SDP_SVC_REMOVE_RSP)
254282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann			status = -1;
2543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
254482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
2546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
2547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
254882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
2550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
255182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
255582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec)
255682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{
255782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int err;
255882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
255982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	err = sdp_device_record_unregister_binary(session, device, rec->handle);
256082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (err == 0)
256182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_record_free(rec);
256282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
256382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	return err;
256482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann}
256582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2566a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec)
2567a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
2568a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_unregister(session, BDADDR_ANY, rec);
2569a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
2570a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
2571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * modify an existing service record
2573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
257482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size)
257582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{
257682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	return -1;
257782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann}
257882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2579a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec)
2580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2581cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf, *p;
2582cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize, rspsize;
2583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t handle;
2585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t pdu;
258682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int status;
2587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
258982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	handle = rec->handle;
2591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (handle == SDP_SERVER_RECORD_HANDLE) {
2593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
2594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2595542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
2597542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
2598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2599542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2600cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2601cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2605542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2607aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_UPDATE_REQ;
2609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2611cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	p = reqbuf + sizeof(sdp_pdu_hdr_t);
2612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2614aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) p);
2615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
2616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint32_t);
2617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > sdp_gen_record_pdu(rec, &pdu)) {
2619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(p, pdu.data, pdu.data_size);
2624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += pdu.data_size;
2625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Send req status : %d\n", status);
2630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2632aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = rspbuf + sizeof(sdp_pdu_hdr_t);
2634aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		status = bt_get_unaligned((uint16_t *) p);
2635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
2637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
2638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
2639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
2640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
2641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2644a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_update(sdp_session_t *session, const sdp_record_t *rec)
2645a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
2646a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_update(session, BDADDR_ANY, rec);
2647a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
2648a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
2649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_record_t *sdp_record_alloc()
2650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
265121f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_record_t *rec = malloc(sizeof(sdp_record_t));
2652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset((void *)rec, 0, sizeof(sdp_record_t));
2653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->handle = 0xffffffff;
2654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
2655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Free the contents of a service record
2659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_free(sdp_record_t *rec)
2661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(rec->attrlist, (sdp_free_func_t)sdp_data_free);
2663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(rec->pattern, free);
2664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(rec);
2665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid)
2668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid);
2670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("SvcRec : 0x%lx\n", (unsigned long)rec);
2672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
2673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Trying to add : 0x%lx\n", (unsigned long)uuid128);
2674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL)
2676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp);
2677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
267821f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann		bt_free(uuid128);
2679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
2681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq)
2684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2685542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; seq; seq = seq->next) {
2686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid_t *uuid = (uuid_t *)seq->data;
2687542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_pattern_add_uuid(rec, uuid);
2688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2690542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract a sequence of service record handles from a PDU buffer
2693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * and add the entries to a sdp_list_t. Note that the service record
2694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * handles are not in "data element sequence" form, but just like
2695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * an array of service handles
2696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2697cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic void extract_record_handle_seq(uint8_t *pdu, sdp_list_t **seq, int count, int *scanned)
2698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *pSeq = *seq;
2700cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata = pdu;
2701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
2702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (n = 0; n < count; n++) {
270421f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann		uint32_t *pSvcRec = malloc(sizeof(uint32_t));
2705aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata));
2706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pSeq = sdp_list_append(pSeq, pSvcRec);
2707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint32_t);
2708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint32_t);
2709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*seq = pSeq;
2711542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Generate the attribute sequence pdu form
2714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * from sdp_list_t elements. Return length of attr seq
2715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2716cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd)
2717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *dataseq;
2719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **types, **values;
2720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t buf;
2721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i, seqlen = sdp_list_len(seq);
2722542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// Fill up the value and the dtd arrays
2724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(&buf, 0, sizeof(sdp_buf_t));
2727997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	buf.data = malloc(256);
2728997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	buf.buf_size = 256;
2729997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann
2730997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	if (!buf.data)
2731997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann		return -ENOMEM;
2732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Seq length : %d\n", seqlen);
2734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	types = malloc(seqlen * sizeof(void *));
2736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	values = malloc(seqlen * sizeof(void *));
2737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0; i < seqlen; i++) {
2738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		void *data = seq->data;
2739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		types[i] = &dtd;
2740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (SDP_IS_UUID(dtd))
2741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			data = &((uuid_t *)data)->value;
2742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = data;
2743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = seq->next;
2744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dataseq = sdp_seq_alloc(types, values, seqlen);
2747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data Seq : 0x%p\n", seq);
2748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = sdp_gen_pdu(&buf, dataseq);
2749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Copying : %d\n", buf.data_size);
2750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(dst, buf.data, buf.data_size);
2751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_free(dataseq);
2753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(types);
2755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
2756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(buf.data);
2757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seqlen;
2758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2760cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq)
2761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2762cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uuid_t *uuid = (uuid_t *) seq->data;
2763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return gen_dataseq_pdu(dst, seq, uuid->type);
2764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2766cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType)
2767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return gen_dataseq_pdu(dst, seq, dataType);
2769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2771113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmanntypedef struct {
2772113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann	uint8_t length;
2773113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann	unsigned char data[16];
2774113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann} __attribute__ ((packed)) sdp_cstate_t;
2775113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann
2776cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int copy_cstate(uint8_t *pdata, const sdp_cstate_t *cstate)
2777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (cstate) {
2779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*pdata++ = cstate->length;
2780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(pdata, cstate->data, cstate->length);
2781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return cstate->length + 1;
2782542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*pdata = 0;
2784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 1;
2785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service search request.
2789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
2791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
279241064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim *   sdp_list_t *search
2793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing elements of the search
2794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
2795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     of the service to be searched
2796542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   uint16_t max_rec_num
2798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      A 16 bit integer which tells the service, the maximum
2799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      entries that the client can handle in the response. The
2800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      server is obliged not to return > max_rec_num entries
2801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
2803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   int return value
2805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
2806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       The request completed successfully. This does not
2807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       mean the requested services were found
2808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     -1:
2809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any failure and sets errno
2810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t **rsp_list
2812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     This variable is set on a successful return if there are
2813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     non-zero service handles. It is a singly linked list of
281428b4f0aea5b15ed7c0acd17ab79705a38ffe7c2fStephen Crane *     service record handles (uint16_t)
2815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search,
2817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			uint16_t max_rec_num, sdp_list_t **rsp)
2818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
2820cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
2821cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0, rsplen;
2822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0;
2823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int scanned, total_rec_count, rec_count;
2824cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
2825cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
2826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
2828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2836aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
2838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
2839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add service class IDs for search
2842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_searchseq_pdu(pdata, search);
2843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data seq added : %d\n", seqlen);
2845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// set the length and increment the pointer
2847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
2848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
2849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// specify the maximum svc rec count that client expects
2851aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
2852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
2853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
2854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
2856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata   = pdata;
2857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rsp = NULL;
2858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
2860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// Add continuation state or NULL (first time)
2861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata, cstate);
2862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2863542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// Set the request header's param length
2864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid  = htons(sdp_gen_tid(session));
2867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
2868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Send the request, wait for response and if
2869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * no error, set the appropriate values and return
2870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
2871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0)
2873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
2874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rsplen = 0;
2876aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rsplen = ntohs(rsphdr->plen);
2878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
2881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
2883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned = 0;
2885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
2886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// net service record match count
2888aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
2889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
2890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
2891aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
2892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
2893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
2894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Total svc count: %d\n", total_rec_count);
2896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Current svc count: %d\n", rec_count);
2897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("ResponseLength: %d\n", rsplen);
2898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!rec_count) {
2900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
2902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		extract_record_handle_seq(pdata, rsp, rec_count, &scanned);
2904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("BytesScanned : %d\n", scanned);
2905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsplen > scanned) {
2907542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			uint8_t cstate_len;
2908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2909542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned;
2910aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate_len = *(uint8_t *) pdata;
2911542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (cstate_len > 0) {
2912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				cstate = (sdp_cstate_t *)pdata;
2913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Cont state length: %d\n", cstate_len);
2914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			} else
2915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				cstate = NULL;
2916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
2918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann  end:
2920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
2921542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
2922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
2923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
2924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2928542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2929542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service attribute request.
2930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2931542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
2932542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2933542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   uint32_t handle
2934542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     The handle of the service for which the attribute(s) are
2935542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     requested
2936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_attrreq_type_t reqtype
2938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
2939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     in one of 2 ways described below :
2940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
2941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        They are the actual attribute identifiers in ascending order
2942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
2944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        The high-order 16bits is the start of range
2945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        the low-order 16bits are the end of range
2946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        0x0000 to 0xFFFF gets all attributes
2947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *attrid
2949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing attribute identifiers desired.
2950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
2951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
2952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
2954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   return sdp_record_t *
2955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
2956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any error and sets errno
2957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     !0:
2958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *	 The service record
2959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle,
2961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_attrreq_type_t reqtype, const sdp_list_t *attrids)
2962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
2964cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
2965cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0, rsp_count;
2966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int attr_list_len = 0;
2967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0;
2968cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
2969cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
2970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
2971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
2972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t cstate_len = 0;
2973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t rsp_concat_buf;
2974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_record_t *rec = 0;
2975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
2977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
2978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
2979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2981cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2982cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2988aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	memset((char *) &rsp_concat_buf, 0, sizeof(sdp_buf_t));
2989aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
2991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
2993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add the service record handle
2996aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
2997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
2998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint32_t);
2999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// specify the response limit
3001aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
3002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
3003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
3004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// get attr seq PDU form
3006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrids,
3007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seqlen == -1) {
3009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
3010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
3011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
3014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
3015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Attr list length : %d\n", seqlen);
3016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// save before Continuation State
3018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata = pdata;
3019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
3020542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
3022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// add NULL continuation state
3023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata, cstate);
3024542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3025542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// set the request header's param length
3026542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid  = htons(sdp_gen_tid(session));
3027542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3028542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0)
3031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rsp_count = 0;
3033aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id);
3036542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
3037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3039542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3040aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3041542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		attr_list_len += rsp_count;
3042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
3043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// if continuation state set need to re-issue request before parsing
3045aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		cstate_len = *(uint8_t *) (pdata + rsp_count);
3046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Response id : %d\n", rsphdr->pdu_id);
3048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attrlist byte count : %d\n", rsp_count);
3049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("sdp_cstate_t length : %d\n", cstate_len);
3050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
3052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * a split response: concatenate intermediate responses
3053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * and the last one (which has cstate_len == 0)
3054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
3056cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			uint8_t *targetPtr = NULL;
3057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3058aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
3059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			// build concatenated response buffer
3061cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
3062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
3063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
3064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(targetPtr, pdata, rsp_count);
3065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.data_size += rsp_count;
3066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
3068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (attr_list_len > 0) {
3070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int scanned = 0;
3071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsp_concat_buf.data_size != 0)
3072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rsp_concat_buf.data;
3073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec = sdp_extract_pdu(pdata, &scanned);
3074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!rec)
3076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
3077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann  end:
3080542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
3081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
3082542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rsp_concat_buf.data)
3083542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rsp_concat_buf.data);
3084542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
3085542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
3086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
3087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
30908be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * SDP transaction structure for asynchronous search
30918be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */
30928be090b298a02108146d3bf48271f8408ac31917Claudio Takahasistruct sdp_transaction {
3093c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	sdp_callback_t *cb;	/* called when the transaction finishes */
3094c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	void *udata;		/* client user data */
3095c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	uint8_t *reqbuf;	/* pointer to request PDU */
30968be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	sdp_buf_t rsp_concat_buf;
3097c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	uint32_t reqsize;	/* without cstate */
30985ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	int err;		/* ZERO if success or the errno if failed */
30998be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi};
31008be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
31018be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/*
31028be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * Creates a new sdp session for asynchronous search
31038be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * INPUT:
31048be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  int sk
31051be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim *     non-blocking L2CAP socket
31061be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim *
31078be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * RETURN:
31088be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  sdp_session_t *
31098be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  NULL - On memory allocation failure
31108be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */
31118be090b298a02108146d3bf48271f8408ac31917Claudio Takahasisdp_session_t *sdp_create(int sk, uint32_t flags)
31128be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi{
3113a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	sdp_session_t *session;
31148be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	struct sdp_transaction *t;
3115a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
3116a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	session = malloc(sizeof(sdp_session_t));
31178be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!session) {
31188be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		errno = ENOMEM;
31198be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return NULL;
31208be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
31218be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	memset(session, 0, sizeof(*session));
31228be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
31238be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->flags = flags;
31248be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->sock = sk;
31258be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
31268be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	t = malloc(sizeof(struct sdp_transaction));
31278be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!t) {
31288be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		errno = ENOMEM;
31298be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		free(session);
31308be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return NULL;
31318be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
31328be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	memset(t, 0, sizeof(*t));
31338be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
31348be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->priv = t;
31358be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
31368be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	return session;
31378be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi}
31388be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
31398be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/*
3140adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Sets the callback function/user data used to notify the application
3141adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * that the asynchronous transaction finished. This function must be
3142adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called before request an asynchronous search.
3143dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *
3144dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * INPUT:
3145dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  sdp_session_t *session
3146dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *	Current sdp session to be handled
3147dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  sdp_callback_t *cb
3148dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *      callback to be called when the transaction finishes
3149dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  void *udata
3150dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *      user data passed to callback
3151dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * RETURN:
3152adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	 0 - Success
3153dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * 	-1 - Failure
3154dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann */
3155dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmannint sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata)
3156dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann{
3157dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	struct sdp_transaction *t;
3158dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3159dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	if (!session || !session->priv)
3160dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann		return -1;
3161dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3162dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t = session->priv;
3163dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t->cb = func;
3164dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t->udata = udata;
3165dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3166dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	return 0;
3167dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann}
3168dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3169adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi/*
3170adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service search request.
3171adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * The incomming and outgoing data are stored in the transaction structure
3172adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * buffers. When there is incomming data the sdp_process function must be
3173adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called to get the data and handle the continuation state.
3174adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3175adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * INPUT :
3176adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *  sdp_session_t *session
3177adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Current sdp session to be handled
3178adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
317941064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim *   sdp_list_t *search
3180adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Singly linked list containing elements of the search
3181adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
3182adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     of the service to be searched
3183adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3184adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   uint16_t max_rec_num
3185adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *      A 16 bit integer which tells the service, the maximum
3186adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *      entries that the client can handle in the response. The
3187adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *      server is obliged not to return > max_rec_num entries
3188adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3189adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * OUTPUT :
3190adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3191adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   int return value
3192adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	0  - if the request has been sent properly
3193adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	-1 - On any failure and sets errno
3194adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi */
3195adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi
319641064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquimint sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num)
3197453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{
3198e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	struct sdp_transaction *t;
3199e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3200e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	uint8_t *pdata;
3201c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	int cstate_len, seqlen = 0;
3202e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
320312f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi	if (!session || !session->priv)
3204e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi		return -1;
3205e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3206e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t = session->priv;
320718a82a6fce76be0883a431380495510010515fffClaudio Takahasi
320818a82a6fce76be0883a431380495510010515fffClaudio Takahasi	/* check if the buffer is already allocated */
320918a82a6fce76be0883a431380495510010515fffClaudio Takahasi	if (t->rsp_concat_buf.data)
321018a82a6fce76be0883a431380495510010515fffClaudio Takahasi		free(t->rsp_concat_buf.data);
321118a82a6fce76be0883a431380495510010515fffClaudio Takahasi	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
321218a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3213e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	if (!t->reqbuf) {
321418a82a6fce76be0883a431380495510010515fffClaudio Takahasi		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
321518a82a6fce76be0883a431380495510010515fffClaudio Takahasi		if (!t->reqbuf) {
321618a82a6fce76be0883a431380495510010515fffClaudio Takahasi			t->err = ENOMEM;
321718a82a6fce76be0883a431380495510010515fffClaudio Takahasi			goto end;
321818a82a6fce76be0883a431380495510010515fffClaudio Takahasi		}
3219e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	}
3220e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3221e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3222e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3223e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3224e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
3225e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3226e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	// generate PDU
3227e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3228e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3229e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3230e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	// add service class IDs for search
323141064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim	seqlen = gen_searchseq_pdu(pdata, search);
3232e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3233e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	SDPDBG("Data seq added : %d\n", seqlen);
3234e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3235e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	// now set the length and increment the pointer
3236e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t->reqsize += seqlen;
3237e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	pdata += seqlen;
3238e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3239e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
3240e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t->reqsize += sizeof(uint16_t);
3241e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	pdata += sizeof(uint16_t);
3242e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3243e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	// set the request header's param length
3244c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	cstate_len = copy_cstate(pdata, NULL);
3245c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3246e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3247c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3248e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
324912f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = errno;
3250e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi		goto end;
3251e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	}
3252e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3253453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	return 0;
3254e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasiend:
3255e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3256f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi	if (t->reqbuf) {
3257f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi		free(t->reqbuf);
3258f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi		t->reqbuf = NULL;
3259e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	}
3260e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3261e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	return -1;
3262453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann}
3263453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3264adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi/*
3265adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service attribute request.
3266adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * The incomming and outgoing data are stored in the transaction structure
3267adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * buffers. When there is incomming data the sdp_process function must be
3268adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called to get the data and handle the continuation state.
3269adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3270adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * INPUT :
3271adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *  sdp_session_t *session
3272adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *	Current sdp session to be handled
3273adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3274adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   uint32_t handle
3275adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     The handle of the service for which the attribute(s) are
3276adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     requested
3277adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3278adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   sdp_attrreq_type_t reqtype
3279adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Attribute identifiers are 16 bit unsigned integers specified
3280adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     in one of 2 ways described below :
3281adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3282adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        They are the actual attribute identifiers in ascending order
3283adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3284adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3285adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        The high-order 16bits is the start of range
3286adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        the low-order 16bits are the end of range
3287adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        0x0000 to 0xFFFF gets all attributes
3288adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3289adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   sdp_list_t *attrid_list
3290adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Singly linked list containing attribute identifiers desired.
3291adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3292adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3293adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3294adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * OUTPUT :
3295adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   int return value
3296adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	 0 - if the request has been sent properly
3297adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	-1 - On any failure and sets errno
3298adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi */
3299adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi
3300453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmannint sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
3301453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{
3302ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	struct sdp_transaction *t;
3303ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3304ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	uint8_t *pdata;
3305c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	int cstate_len, seqlen = 0;
3306ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
330712f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi	if (!session || !session->priv)
3308ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		return -1;
3309ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3310ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t = session->priv;
331118a82a6fce76be0883a431380495510010515fffClaudio Takahasi
331218a82a6fce76be0883a431380495510010515fffClaudio Takahasi	/* check if the buffer is already allocated */
331318a82a6fce76be0883a431380495510010515fffClaudio Takahasi	if (t->rsp_concat_buf.data)
331418a82a6fce76be0883a431380495510010515fffClaudio Takahasi		free(t->rsp_concat_buf.data);
331518a82a6fce76be0883a431380495510010515fffClaudio Takahasi	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
331618a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3317ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	if (!t->reqbuf) {
331818a82a6fce76be0883a431380495510010515fffClaudio Takahasi		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
331918a82a6fce76be0883a431380495510010515fffClaudio Takahasi		if (!t->reqbuf) {
332018a82a6fce76be0883a431380495510010515fffClaudio Takahasi			t->err = ENOMEM;
332118a82a6fce76be0883a431380495510010515fffClaudio Takahasi			goto end;
332218a82a6fce76be0883a431380495510010515fffClaudio Takahasi		}
3323ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3324ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3325ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3326ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3327ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3328ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
3329ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3330ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	// generate PDU
3331ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3332ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3333ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3334ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	// add the service record handle
3335ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
3336ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize += sizeof(uint32_t);
3337ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata += sizeof(uint32_t);
3338ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3339ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	// specify the response limit
3340ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
3341ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize += sizeof(uint16_t);
3342ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata += sizeof(uint16_t);
3343ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3344ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	// get attr seq PDU form
3345ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	seqlen = gen_attridseq_pdu(pdata, attrid_list,
3346ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi			reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3347ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	if (seqlen == -1) {
334812f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = EINVAL;
3349ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		goto end;
3350ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3351ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3352ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	// now set the length and increment the pointer
3353ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize += seqlen;
3354ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata += seqlen;
3355ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	SDPDBG("Attr list length : %d\n", seqlen);
3356ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3357ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	// set the request header's param length
3358c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	cstate_len = copy_cstate(pdata, NULL);
3359c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3360ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3361c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3362ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
336312f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = errno;
3364ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		goto end;
3365ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3366ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3367453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	return 0;
3368ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasiend:
3369ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3370f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi	if (t->reqbuf) {
3371f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi		free(t->reqbuf);
3372f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi		t->reqbuf = NULL;
3373ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3374ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3375ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	return -1;
3376453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann}
3377453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3378dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann/*
3379adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service search attributes.
3380adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * It is a service search request combined with attribute request. The incomming
3381adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * and outgoing data are stored in the transaction structure buffers. When there
3382adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * is incomming data the sdp_process function must be called to get the data
3383adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * and handle the continuation state.
3384f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *
3385f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT:
3386f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *  sdp_session_t *session
3387f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *	Current sdp session to be handled
3388453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3389453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *   sdp_list_t *search
3390453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Singly linked list containing elements of the search
3391453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
3392453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     of the service to be searched
3393453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3394453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *   AttributeSpecification attrSpec
3395453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
3396453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     in one of 2 ways described below :
3397453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3398453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        They are the actual attribute identifiers in ascending order
3399453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3400453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3401453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        The high-order 16bits is the start of range
3402453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        the low-order 16bits are the end of range
3403453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        0x0000 to 0xFFFF gets all attributes
3404453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3405adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   sdp_list_t *attrid_list
3406453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Singly linked list containing attribute identifiers desired.
3407453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3408453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3409453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3410453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3411f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN:
3412adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	 0 - if the request has been sent properly
3413f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	-1 - On any failure
3414f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */
341541064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquimint sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
3416f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{
3417f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	struct sdp_transaction *t;
3418f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3419f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	uint8_t *pdata;
3420c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	int cstate_len, seqlen = 0;
3421f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
342212f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi	if (!session || !session->priv)
3423f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		return -1;
3424f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3425f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t = session->priv;
342618a82a6fce76be0883a431380495510010515fffClaudio Takahasi
342718a82a6fce76be0883a431380495510010515fffClaudio Takahasi	/* check if the buffer is already allocated */
342818a82a6fce76be0883a431380495510010515fffClaudio Takahasi	if (t->rsp_concat_buf.data)
342918a82a6fce76be0883a431380495510010515fffClaudio Takahasi		free(t->rsp_concat_buf.data);
343018a82a6fce76be0883a431380495510010515fffClaudio Takahasi	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
343118a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3432f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (!t->reqbuf) {
343318a82a6fce76be0883a431380495510010515fffClaudio Takahasi		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
343418a82a6fce76be0883a431380495510010515fffClaudio Takahasi		if (!t->reqbuf) {
343518a82a6fce76be0883a431380495510010515fffClaudio Takahasi			t->err = ENOMEM;
343618a82a6fce76be0883a431380495510010515fffClaudio Takahasi			goto end;
343718a82a6fce76be0883a431380495510010515fffClaudio Takahasi		}
3438f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3439f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3440f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3441f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3442f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3443f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
3444f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3445f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// generate PDU
3446f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3447f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3448f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3449f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// add service class IDs for search
345041064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim	seqlen = gen_searchseq_pdu(pdata, search);
3451f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3452f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Data seq added : %d\n", seqlen);
3453f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3454f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// now set the length and increment the pointer
3455f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += seqlen;
3456f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += seqlen;
3457f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3458f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
3459f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += sizeof(uint16_t);
3460f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += sizeof(uint16_t);
3461f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3462f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
3463f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3464f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// get attr seq PDU form
3465453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrid_list,
3466453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann			reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
3467f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (seqlen == -1) {
346812f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = EINVAL;
3469f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
3470f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3471f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3472f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += seqlen;
3473f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Attr list length : %d\n", seqlen);
3474f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += seqlen;
3475f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3476f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	// set the request header's param length
3477c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	cstate_len = copy_cstate(pdata, NULL);
3478c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3479f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3480c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3481f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
348212f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = errno;
3483f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
3484f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3485f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3486f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	return 0;
3487f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend:
3488f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3489f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi	if (t->reqbuf) {
3490f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi		free(t->reqbuf);
3491f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi		t->reqbuf = NULL;
3492f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3493f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3494f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	return -1;
3495f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi}
3496f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3497f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/*
34985ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * Function used to get the error reason after sdp_callback_t function has been called
349912f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1.
350012f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly
350112f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * is not safe because multiple transactions can be triggered.
35025ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * This function must be used with asynchronous sdp functions only.
35035ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *
35045ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * INPUT:
35055ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *  sdp_session_t *session
35065ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *	Current sdp session to be handled
35075ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * RETURN:
35085ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 	 0 = No error in the current transaction
35095ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 	-1 - if the session is invalid
35105ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 	positive value - the errno value
35115ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *
35125ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi */
35135ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasiint sdp_get_error(sdp_session_t *session)
35145ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi{
35155ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	struct sdp_transaction *t;
35165ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
35175ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	if (!session || !session->priv) {
35185ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Invalid session");
35195ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		return -1;
35205ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	}
35215ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
35225ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	t = session->priv;
35235ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
35245ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	return t->err;
35255ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi}
35265ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
35275ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi/*
3528f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * Receive the incomming SDP PDU. This function must be called when there is data
3529f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * available to be read. On continuation state, the original request (with a new
3530f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * transaction ID) and the continuation state data will be appended in the initial PDU.
3531f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * If an error happens or the transaction finishes the callback function will be called.
3532f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *
3533f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT:
3534f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *  sdp_session_t *session
3535f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *	Current sdp session to be handled
3536f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN:
3537f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	0  - if the transaction is on continuation state
3538f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	-1 - On any failure or the transaction finished
3539f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */
3540f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiint sdp_process(sdp_session_t *session)
3541f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{
35425ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	struct sdp_transaction *t;
35435ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	sdp_pdu_hdr_t *reqhdr, *rsphdr;
35445ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	sdp_cstate_t *pcstate;
35455ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	uint8_t *pdata, *rspbuf, *targetPtr;
35465ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	int rsp_count, err = -1;
3547c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	size_t size = 0;
35489203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	int n, plen;
35495ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	uint16_t status = 0xffff;
35505ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	uint8_t pdu_id = 0x00;
3551f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3552f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (!session || !session->priv) {
3553c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		SDPERR("Invalid session");
3554c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		return -1;
3555f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3556f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3557f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
35585ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	if (!rspbuf) {
35595ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Response buffer alloc failure:%s (%d)",
35605ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi				strerror(errno), errno);
3561c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		return -1;
35625ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	}
3563c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi
3564c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE);
3565f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3566f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t = session->priv;
3567f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *)t->reqbuf;
3568f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	rsphdr = (sdp_pdu_hdr_t *)rspbuf;
3569f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
35705ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3571f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
35729203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
35739203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	if (n < 0) {
35745ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Read response:%s (%d)", strerror(errno), errno);
35755ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		t->err = errno;
3576f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
35775ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	}
3578f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
35799203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	if (n == 0 || reqhdr->tid != rsphdr->tid ||
35809203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		(n != (ntohs(rsphdr->plen) + sizeof(sdp_pdu_hdr_t)))) {
35815ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		t->err = EPROTO;
35829203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPERR("Protocol error.");
3583343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi		goto end;
3584343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi	}
3585343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi
35865ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	pdu_id = rsphdr->pdu_id;
358758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	switch (rsphdr->pdu_id) {
358858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	uint8_t *ssr_pdata;
358958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	uint16_t tsrc, csrc;
359058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	case SDP_SVC_SEARCH_RSP:
359158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		/*
35929203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * TSRC: Total Service Record Count (2 bytes)
35939203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * CSRC: Current Service Record Count (2 bytes)
359458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		 */
359558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		ssr_pdata = pdata;
359658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));
35979203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		ssr_pdata += sizeof(uint16_t);
359858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));
359958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi
36009203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		/* csrc should never be larger than tsrc */
36019203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		if (csrc > tsrc) {
36029203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi			t->err = EPROTO;
36039203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi			SDPERR("Protocol error: wrong current service record count value.");
36049203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi			goto end;
36059203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		}
36069203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
36079203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPDBG("Total svc count: %d\n", tsrc);
36089203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPDBG("Current svc count: %d\n", csrc);
36099203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
36109203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		/* parameter length without continuation state */
36119203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
36129203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
3613c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann		if (t->rsp_concat_buf.data_size == 0) {
361458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi			/* first fragment */
361558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi			rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
361658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		} else {
3617e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			/* point to the first csrc */
3618e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			uint16_t *pcsrc = (uint16_t *) (t->rsp_concat_buf.data + 2);
3619e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
3620e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			/* FIXME: update the interface later. csrc doesn't need be passed to clients */
3621e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
3622e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			pdata += sizeof(uint16_t); /* point to csrc */
3623e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
3624e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			/* the first csrc contains the sum of partial csrc responses */
3625e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			*pcsrc += bt_get_unaligned((uint16_t *) pdata);
3626e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
3627e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			pdata += sizeof(uint16_t); /* point to the first handle */
362858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi			rsp_count = csrc * 4;
362958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		}
36305ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		status = 0x0000;
363158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		break;
363258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	case SDP_SVC_ATTR_RSP:
363358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	case SDP_SVC_SEARCH_ATTR_RSP:
363458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
363558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		SDPDBG("Attrlist byte count : %d\n", rsp_count);
36369203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
36379203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		/*
36389203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * Number of bytes in the AttributeLists parameter(without
36399203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * continuation state) + AttributeListsByteCount field size.
36409203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 */
36419203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		plen = sizeof(uint16_t) + rsp_count;
3642f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
364358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		pdata += sizeof(uint16_t); // points to attribute list
36445ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		status = 0x0000;
364558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		break;
36465ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	case SDP_ERROR_RSP:
36475ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		status = ntohs(bt_get_unaligned((uint16_t *) pdata));
36489203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		size = ntohs(rsphdr->plen);
36499203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
36509203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		/* error code + error info */
36519203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		plen = size;
36525ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		goto end;
365358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	default:
36545ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		t->err = EPROTO;
36555ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id);
365658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		goto end;
365758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	}
3658f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
365958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	pcstate = (sdp_cstate_t *) (pdata + rsp_count);
366058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi
366158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	SDPDBG("Cstate length : %d\n", pcstate->length);
36629203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
36639203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	/*
36649203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	 * Check out of bound. Continuation state must have at least
36659203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	 * 1 byte: ZERO to indicate that it is not a partial response.
36669203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	 */
36679203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	if ((n - sizeof(sdp_pdu_hdr_t))  != (plen + pcstate->length + 1)) {
36689203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		t->err = EPROTO;
36699203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPERR("Protocol error: wrong PDU size.");
36709203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		status = 0xffff;
36719203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		goto end;
36729203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	}
36739203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
3674f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	/*
3675f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	 * This is a split response, need to concatenate intermediate
36765ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	 * responses and the last one which will have cstate length == 0
3677f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	 */
367858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count);
367958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size;
368058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count;
368158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	memcpy(targetPtr, pdata, rsp_count);
368258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	t->rsp_concat_buf.data_size += rsp_count;
368358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi
368458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	if (pcstate->length > 0) {
368558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		int reqsize, cstate_len;
3686f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3687f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		reqhdr->tid = htons(sdp_gen_tid(session));
3688f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
36895ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		// add continuation state
369058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		cstate_len = copy_cstate(t->reqbuf + t->reqsize, pcstate);
3691f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
369258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		reqsize = t->reqsize + cstate_len;
3693f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3694f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		// set the request header's param length
3695f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3696f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3697f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (sdp_send_req(session, t->reqbuf, reqsize) < 0) {
36985ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			SDPERR("Error sendind data:%s(%d)", strerror(errno), errno);
36995ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			status = 0xffff;
37005ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			t->err = errno;
3701f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi			goto end;
3702f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		}
3703c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		err = 0;
3704f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3705f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3706f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend:
3707c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	if (err) {
3708c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann		if (t->rsp_concat_buf.data_size != 0) {
3709f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi			pdata = t->rsp_concat_buf.data;
3710c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann			size = t->rsp_concat_buf.data_size;
3711c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann		}
3712f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (t->cb)
37135ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			t->cb(pdu_id, status, pdata, size, t->udata);
3714f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3715f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3716f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (rspbuf)
3717f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		free(rspbuf);
3718f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3719c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	return err;
3720f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi}
3721f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3722f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/*
3723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service search request combined with the service
3724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attribute request. First a service class match is done and
3725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * for matching service, requested attributes are extracted
3726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
3728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *search
3730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing elements of the search
3731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
3732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     of the service to be searched
3733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   AttributeSpecification attrSpec
3735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
3736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     in one of 2 ways described below :
3737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        They are the actual attribute identifiers in ascending order
3739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        The high-order 16bits is the start of range
3742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        the low-order 16bits are the end of range
3743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        0x0000 to 0xFFFF gets all attributes
3744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *attrids
3746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing attribute identifiers desired.
3747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
3751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   int return value
3752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
3753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       The request completed successfully. This does not
3754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       mean the requested services were found
3755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     -1:
3756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any error and sets errno
3757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t **rsp
3759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     This variable is set on a successful return to point to
3760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     service(s) found. Each element of this list is of type
3761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     sdp_record_t* (of the services which matched the search list)
3762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3763542fc57346fbb329934152f446f58cc61a5d5d00Marcel 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)
3764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
3766cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
3767cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0;
3768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0, attr_list_len = 0;
3769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int rsp_count = 0, cstate_len = 0;
3770cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
3771cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
3772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dataType;
3774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *rec_list = NULL;
3775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t rsp_concat_buf;
3776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
3777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
3779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
3780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
3781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3782cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3783cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
3785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
3787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t));
3791aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
3793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// generate PDU
3795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3796542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
3797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// add service class IDs for search
3799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_searchseq_pdu(pdata, search);
3800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data seq added : %d\n", seqlen);
3802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// now set the length and increment the pointer
3804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
3805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
3806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3807aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
3808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
3809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
3810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
3812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// get attr seq PDU form
3814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrids,
3815aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
3816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seqlen == -1) {
3817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = EINVAL;
3818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
3821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Attr list length : %d\n", seqlen);
3822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
3823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rsp = 0;
3824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	// save before Continuation State
3826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata = pdata;
3827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
3828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
3830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid = htons(sdp_gen_tid(session));
3831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// add continuation state (can be null)
3833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata, cstate);
3834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		// set the request header's param length
3836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3837aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0) {
3840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
3841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
3846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3850aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		attr_list_len += rsp_count;
3852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);	// pdata points to attribute list
3853aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		cstate_len = *(uint8_t *) (pdata + rsp_count);
3854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attrlist byte count : %d\n", attr_list_len);
3856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Response byte count : %d\n", rsp_count);
3857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Cstate length : %d\n", cstate_len);
3858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
3859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * This is a split response, need to concatenate intermediate
3860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * responses and the last one which will have cstate_len == 0
3861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
3863cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			uint8_t *targetPtr = NULL;
3864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3865aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
3866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			// build concatenated response buffer
3868cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
3869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
3870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
3871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(targetPtr, pdata, rsp_count);
3872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.data_size += rsp_count;
3873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
3875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (attr_list_len > 0) {
3877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int scanned = 0;
3878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsp_concat_buf.data_size != 0)
3880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rsp_concat_buf.data;
3881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
3883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Response is a sequence of sequence(s) for one or
3884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * more data element sequence(s) representing services
3885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * for which attributes are returned
3886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned = sdp_extract_seqtype(pdata, &dataType, &seqlen);
3888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Bytes scanned : %d\n", scanned);
3890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Seq length : %d\n", seqlen);
3891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (scanned && seqlen) {
3893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata += scanned;
3894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			do {
3895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				int recsize = 0;
3896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				sdp_record_t *rec = sdp_extract_pdu(pdata, &recsize);
3897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				if (rec == NULL) {
3898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					SDPERR("SVC REC is null\n");
3899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					status = -1;
3900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					goto end;
3901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				}
39028db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann				if (!recsize) {
39038db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann					sdp_record_free(rec);
39048db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann					break;
39058db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann				}
3906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				scanned += recsize;
3907542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				pdata += recsize;
3908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3909542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Loc seq length : %d\n", recsize);
3910542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle);
3911542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Bytes scanned : %d\n", scanned);
3912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Attrlist byte count : %d\n", attr_list_len);
3913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				rec_list = sdp_list_append(rec_list, rec);
3914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			} while (scanned < attr_list_len);
3915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Successful scan of service attr lists\n");
3917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*rsp = rec_list;
3918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann  end:
3921542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rsp_concat_buf.data)
3922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rsp_concat_buf.data);
3923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqbuf)
3924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(reqbuf);
3925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rspbuf)
3926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(rspbuf);
3927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
3928542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3929542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3931542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Find devices in the piconet.
3932542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3933542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found)
3934542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3935542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0);
3936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (n < 0) {
3937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Inquiry failed:%s", strerror(errno));
3938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
3939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*found = n;
3941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
3942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_close(sdp_session_t *session)
3945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
39468be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	struct sdp_transaction *t;
39478be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	int ret;
39488be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
39498be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!session)
39508be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return -1;
39518be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
39528be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	ret = close(session->sock);
39538be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
39548be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	t = session->priv;
39558be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
39568be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (t) {
39578be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		if (t->reqbuf)
39588be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi			free(t->reqbuf);
39598be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
39608be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		if (t->rsp_concat_buf.data)
39618be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi			free(t->rsp_concat_buf.data);
39628be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
39638be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		free(t);
39648be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
3965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(session);
3966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return ret;
3967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int sdp_is_local(const bdaddr_t *device)
3970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0;
3972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
39741be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimstatic int sdp_connect_local(sdp_session_t *session)
3975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
39761be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	struct sockaddr_un sa;
3977a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
39781be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->sock = socket(PF_UNIX, SOCK_STREAM, 0);
39791be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (session->sock < 0)
39801be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return -1;
39811be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->local = 1;
3982a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
39831be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.sun_family = AF_UNIX;
39841be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	strcpy(sa.sun_path, SDP_UNIX_PATH);
3985a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
3986aa7577018bb1faac4b67b52dc8b003663cdd03adUlisses Furquim	return connect(session->sock, (struct sockaddr *)&sa, sizeof(sa));
39871be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim}
39881be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
39891be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimstatic int sdp_connect_l2cap(const bdaddr_t *src,
39901be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			     const bdaddr_t *dst, sdp_session_t *session)
39911be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim{
39921be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	uint32_t flags = session->flags;
39931be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	struct sockaddr_l2 sa;
39941be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	int sk;
39951be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
39961be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
39971be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (session->sock < 0)
39981be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return -1;
39991be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->local = 0;
40001be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40011be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sk = session->sock;
40021be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40031be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (flags & SDP_NON_BLOCKING) {
40041be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		long arg = fcntl(sk, F_GETFL, 0);
40051be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		fcntl(sk, F_SETFL, arg | O_NONBLOCK);
4006a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	}
4007a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
40081be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_family = AF_BLUETOOTH;
40091be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_psm = 0;
4010a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
40111be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (bacmp(src, BDADDR_ANY)) {
40121be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		sa.l2_bdaddr = *src;
40131be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0)
40141be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			return -1;
40151be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	}
4016a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
40171be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (flags & SDP_WAIT_ON_CLOSE) {
40181be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		struct linger l = { .l_onoff = 1, .l_linger = 1 };
40191be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
40201be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	}
40211be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40221be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_psm = htobs(SDP_PSM);
40231be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_bdaddr = *dst;
40241be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40251be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	do {
40261be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa));
4027aa7577018bb1faac4b67b52dc8b003663cdd03adUlisses Furquim		if (!ret)
40281be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			return 0;
40291be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (ret < 0 && (flags & SDP_NON_BLOCKING) &&
40301be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		    (errno == EAGAIN || errno == EINPROGRESS))
40311be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			return 0;
40321be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	} while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY));
40331be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40341be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	return -1;
40351be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim}
40361be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40371be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimsdp_session_t *sdp_connect(const bdaddr_t *src,
40381be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			   const bdaddr_t *dst, uint32_t flags)
40391be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim{
40401be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sdp_session_t *session;
40411be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	int err;
40421be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40431be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) {
40441be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		errno = EINVAL;
40451be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return NULL;
40461be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	}
40471be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40481be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session = sdp_create(-1, flags);
40491be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (!session)
40501be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return NULL;
40511be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40521be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (sdp_is_local(dst)) {
40531be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (sdp_connect_local(session) < 0)
40541be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			goto fail;
4055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
40561be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (sdp_connect_l2cap(src, dst, session) < 0)
40571be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			goto fail;
4058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
4059a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
40601be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	return session;
40611be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
4062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail:
406312862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann	err = errno;
4064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (session->sock >= 0)
4065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		close(session->sock);
4066a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	if (session->priv)
4067a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann		free(session->priv);
4068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(session);
406912862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann	errno = err;
40701be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
40711be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	return NULL;
4072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
40738f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann
40748f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannint sdp_get_socket(const sdp_session_t *session)
40758f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{
40768f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann	return session->sock;
40778f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann}
40788f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann
40798f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannuint16_t sdp_gen_tid(sdp_session_t *session)
40808f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{
40818f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann	return session->tid++;
40828f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann}
4083