sdp.c revision 0f27847ff8ab48d06d5abd6e5bf35e315cf16457
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>
79184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2002-2010  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>
331be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim#include <fcntl.h>
34b393cdff611943a05ec598048b5c4be8130151ddMarcel Holtmann#include <unistd.h>
35542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <stdlib.h>
36b393cdff611943a05ec598048b5c4be8130151ddMarcel Holtmann#include <limits.h>
37bb45b882917f26aaa26b2b903b70d622b39cce84Marcel Holtmann#include <string.h>
38654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#include <syslog.h>
398bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann#include <sys/time.h>
408bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann#include <sys/types.h>
41924fa35c97929ff95590a1f33cc2bd8cca7cf1f2Marcel Holtmann#include <sys/socket.h>
42924fa35c97929ff95590a1f33cc2bd8cca7cf1f2Marcel Holtmann#include <sys/un.h>
43654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#include <netinet/in.h>
44654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
45a5b1e3d02c8b356bb167dd7e4b6ab54edf271e7bMarcel Holtmann#include "bluetooth.h"
46a5b1e3d02c8b356bb167dd7e4b6ab54edf271e7bMarcel Holtmann#include "hci.h"
47a5b1e3d02c8b356bb167dd7e4b6ab54edf271e7bMarcel Holtmann#include "hci_lib.h"
48a5b1e3d02c8b356bb167dd7e4b6ab54edf271e7bMarcel Holtmann#include "l2cap.h"
49a5b1e3d02c8b356bb167dd7e4b6ab54edf271e7bMarcel Holtmann#include "sdp.h"
50a5b1e3d02c8b356bb167dd7e4b6ab54edf271e7bMarcel Holtmann#include "sdp_lib.h"
51a5b1e3d02c8b356bb167dd7e4b6ab54edf271e7bMarcel 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
55206da78a25ae175741a7444edd13dcf67bbdf059Luiz Augusto von Dentz#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
56206da78a25ae175741a7444edd13dcf67bbdf059Luiz Augusto von Dentz
57654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#ifdef SDP_DEBUG
58654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg)
59654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#else
60654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPDBG(fmt...)
61654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#endif
62654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
63542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB"
64542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
653f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmannstatic uint128_t bluetooth_base_uuid = {
663f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	.data = {	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
67c30706178221e3df5dfe82eb5c91f39fe118eb78Marcel Holtmann			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
683f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann};
69542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
70654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDP_MAX_ATTR_LEN 65535
71654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann
72e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentzstatic sdp_data_t *sdp_copy_seq(sdp_data_t *data);
73eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocerastatic int sdp_attr_add_new_with_length(sdp_record_t *rec,
74eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	uint16_t attr, uint8_t dtd, const void *value, uint32_t len);
756996a497c429be009a9f522c3a28ad777d2ba3b5Luiz Augusto von Dentzstatic int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d);
76e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
77542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* Message structure. */
78542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstruct tupla {
79542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int index;
80542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *str;
81542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann};
82542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
83542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic struct tupla Protocol[] = {
846864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SDP_UUID,		"SDP"		},
856864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDP_UUID,		"UDP"		},
866864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ RFCOMM_UUID,		"RFCOMM"	},
876864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ TCP_UUID,		"TCP"		},
886864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ TCS_BIN_UUID,		"TCS-BIN"	},
896864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ TCS_AT_UUID,		"TCS-AT"	},
906864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ OBEX_UUID,		"OBEX"		},
916864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IP_UUID,		"IP"		},
926864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ FTP_UUID,		"FTP"		},
936864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HTTP_UUID,		"HTTP"		},
946864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ WSP_UUID,		"WSP"		},
956864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ BNEP_UUID,		"BNEP"		},
966864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_UUID,		"UPNP"		},
976864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HIDP_UUID,		"HIDP"		},
986864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCRP_CTRL_UUID,	"HCRP-Ctrl"	},
996864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCRP_DATA_UUID,	"HCRP-Data"	},
1006864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCRP_NOTE_UUID,	"HCRP-Notify"	},
1016864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AVCTP_UUID,		"AVCTP"		},
1026864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AVDTP_UUID,		"AVDTP"		},
1036864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ CMTP_UUID,		"CMTP"		},
1046864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDI_UUID,		"UDI"		},
105f767416e71484be2463caa6482dc978e165cabaeMarcel Holtmann	{ MCAP_CTRL_UUID,	"MCAP-Ctrl"	},
106f767416e71484be2463caa6482dc978e165cabaeMarcel Holtmann	{ MCAP_DATA_UUID,	"MCAP-Data"	},
1076864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ L2CAP_UUID,		"L2CAP"		},
108df3c8e1ebb8d6cdf0e3cfe1cde16d2db8a75871cClaudio Takahasi	{ ATT_UUID,		"ATT"		},
109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	{ 0 }
110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann};
111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic struct tupla ServiceClass[] = {
1136864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SDP_SERVER_SVCLASS_ID,		"SDP Server"			},
1146864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ BROWSE_GRP_DESC_SVCLASS_ID,		"Browse Group Descriptor"	},
1156864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PUBLIC_BROWSE_GROUP,			"Public Browse Group"		},
1166864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SERIAL_PORT_SVCLASS_ID,		"Serial Port"			},
1176864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ LAN_ACCESS_SVCLASS_ID,		"LAN Access Using PPP"		},
1186864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ DIALUP_NET_SVCLASS_ID,		"Dialup Networking"		},
1196864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IRMC_SYNC_SVCLASS_ID,			"IrMC Sync"			},
1206864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ OBEX_OBJPUSH_SVCLASS_ID,		"OBEX Object Push"		},
1216864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ OBEX_FILETRANS_SVCLASS_ID,		"OBEX File Transfer"		},
1226864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IRMC_SYNC_CMD_SVCLASS_ID,		"IrMC Sync Command"		},
1236864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HEADSET_SVCLASS_ID,			"Headset"			},
1246864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ CORDLESS_TELEPHONY_SVCLASS_ID,	"Cordless Telephony"		},
1256864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AUDIO_SOURCE_SVCLASS_ID,		"Audio Source"			},
1266864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AUDIO_SINK_SVCLASS_ID,		"Audio Sink"			},
1276864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AV_REMOTE_TARGET_SVCLASS_ID,		"AV Remote Target"		},
1286864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ ADVANCED_AUDIO_SVCLASS_ID,		"Advanced Audio"		},
1296864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AV_REMOTE_SVCLASS_ID,			"AV Remote"			},
1306864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_CONF_SVCLASS_ID,		"Video Conferencing"		},
1316864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ INTERCOM_SVCLASS_ID,			"Intercom"			},
1326864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ FAX_SVCLASS_ID,			"Fax"				},
1336864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HEADSET_AGW_SVCLASS_ID,		"Headset Audio Gateway"		},
1346864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ WAP_SVCLASS_ID,			"WAP"				},
1356864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ WAP_CLIENT_SVCLASS_ID,		"WAP Client"			},
1366864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PANU_SVCLASS_ID,			"PAN User"			},
1376864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ NAP_SVCLASS_ID,			"Network Access Point"		},
1386864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GN_SVCLASS_ID,			"PAN Group Network"		},
1396864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ DIRECT_PRINTING_SVCLASS_ID,		"Direct Printing"		},
1406864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ REFERENCE_PRINTING_SVCLASS_ID,	"Reference Printing"		},
1416864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_SVCLASS_ID,			"Imaging"			},
1426864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_RESPONDER_SVCLASS_ID,		"Imaging Responder"		},
1436864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_ARCHIVE_SVCLASS_ID,		"Imaging Automatic Archive"	},
1446864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ IMAGING_REFOBJS_SVCLASS_ID,		"Imaging Referenced Objects"	},
1456864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HANDSFREE_SVCLASS_ID,			"Handsfree"			},
146bd32ca373cd507d9c9746bde40b0e7bb4034adbeMarcel Holtmann	{ HANDSFREE_AGW_SVCLASS_ID,		"Handsfree Audio Gateway"	},
1476864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ DIRECT_PRT_REFOBJS_SVCLASS_ID,	"Direct Printing Ref. Objects"	},
1486864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ REFLECTED_UI_SVCLASS_ID,		"Reflected UI"			},
1496864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ BASIC_PRINTING_SVCLASS_ID,		"Basic Printing"		},
1506864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PRINTING_STATUS_SVCLASS_ID,		"Printing Status"		},
1516864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HID_SVCLASS_ID,			"Human Interface Device"	},
1526864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCR_SVCLASS_ID,			"Hardcopy Cable Replacement"	},
1536864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCR_PRINT_SVCLASS_ID,			"HCR Print"			},
1546864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ HCR_SCAN_SVCLASS_ID,			"HCR Scan"			},
1556864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ CIP_SVCLASS_ID,			"Common ISDN Access"		},
1566864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_CONF_GW_SVCLASS_ID,		"Video Conferencing Gateway"	},
1576864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDI_MT_SVCLASS_ID,			"UDI MT"			},
1586864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UDI_TA_SVCLASS_ID,			"UDI TA"			},
1596864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ AV_SVCLASS_ID,			"Audio/Video"			},
1606864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ SAP_SVCLASS_ID,			"SIM Access"			},
1618ce8108e712e40e1b9530c96f7ff6cbb32b5cb8bMarcel Holtmann	{ PBAP_PCE_SVCLASS_ID,			"Phonebook Access - PCE"	},
1628ce8108e712e40e1b9530c96f7ff6cbb32b5cb8bMarcel Holtmann	{ PBAP_PSE_SVCLASS_ID,			"Phonebook Access - PSE"	},
16373f2fe893f6801358ea4fb88dc8d24050c7d0ca5Marcel Holtmann	{ PBAP_SVCLASS_ID,			"Phonebook Access"		},
1646864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ PNP_INFO_SVCLASS_ID,			"PnP Information"		},
1656864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_NETWORKING_SVCLASS_ID,	"Generic Networking"		},
1666864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_FILETRANS_SVCLASS_ID,		"Generic File Transfer"		},
1676864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_AUDIO_SVCLASS_ID,		"Generic Audio"			},
1686864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ GENERIC_TELEPHONY_SVCLASS_ID,		"Generic Telephony"		},
1696864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_SVCLASS_ID,			"UPnP"				},
1706864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_IP_SVCLASS_ID,			"UPnP IP"			},
1716864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_PAN_SVCLASS_ID,			"UPnP PAN"			},
1726864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_LAP_SVCLASS_ID,			"UPnP LAP"			},
1736864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ UPNP_L2CAP_SVCLASS_ID,		"UPnP L2CAP"			},
1746864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_SOURCE_SVCLASS_ID,		"Video Source"			},
1756864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann	{ VIDEO_SINK_SVCLASS_ID,		"Video Sink"			},
1762fa38208982e7c7bb55ae97acd13dbf82dd24e88Marcel Holtmann	{ VIDEO_DISTRIBUTION_SVCLASS_ID,	"Video Distribution"		},
177d48df6f540535a0dc9eafb9555916e9a4dba7780Elvis Pfützenreuter	{ HDP_SVCLASS_ID,			"HDP"				},
178d48df6f540535a0dc9eafb9555916e9a4dba7780Elvis Pfützenreuter	{ HDP_SOURCE_SVCLASS_ID,		"HDP Source"			},
179d48df6f540535a0dc9eafb9555916e9a4dba7780Elvis Pfützenreuter	{ HDP_SINK_SVCLASS_ID,			"HDP Sink"			},
18042e0ce5b430ac5e36c0d21bdddcaf1fe83e025f5Marcel Holtmann	{ APPLE_AGENT_SVCLASS_ID,		"Apple Agent"			},
181df3c8e1ebb8d6cdf0e3cfe1cde16d2db8a75871cClaudio Takahasi	{ GENERIC_ATTRIB_SVCLASS_ID,		"Generic Attribute"		},
182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	{ 0 }
183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann};
184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1856864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann#define Profile ServiceClass
186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic char *string_lookup(struct tupla *pt0, int index)
188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	struct tupla *pt;
1906864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (pt = pt0; pt->index; pt++)
1926864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann		if (pt->index == index)
193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return pt->str;
1946864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return "";
196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1983df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmannstatic char *string_lookup_uuid(struct tupla *pt0, const uuid_t* uuid)
1993df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann{
2003df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	uuid_t tmp_uuid;
2013df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
2023df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid));
2033df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
2043df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	if (sdp_uuid128_to_uuid(&tmp_uuid)) {
2053df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		switch (tmp_uuid.type) {
2063df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		case SDP_UUID16:
2073df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann			return string_lookup(pt0, tmp_uuid.value.uuid16);
2083df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		case SDP_UUID32:
2093df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann			return string_lookup(pt0, tmp_uuid.value.uuid32);
2103df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		}
2113df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	}
2123df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
2133df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann	return "";
2143df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann}
2153df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann
216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Prints into a string the Protocol UUID
218542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * coping a maximum of n characters.
219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2208f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergstatic int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n)
221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
222542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *str2;
223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!uuid) {
225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "NULL");
226542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -2;
227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2286864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
230542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		str2 = string_lookup(message, uuid->value.uuid16);
232efcfad7c009502b2951a2408df3a94b83934e288Johan Hedberg		snprintf(str, n, "%s", str2);
233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
2350e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann		str2 = string_lookup(message, uuid->value.uuid32);
236efcfad7c009502b2951a2408df3a94b83934e288Johan Hedberg		snprintf(str, n, "%s", str2);
2370e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann		break;
238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
2393df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		str2 = string_lookup_uuid(message, uuid);
240efcfad7c009502b2951a2408df3a94b83934e288Johan Hedberg		snprintf(str, n, "%s", str2);
2413df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann		break;
242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2466864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann
247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
248542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
249542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n)
251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid2str(Protocol, uuid, str, n);
253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n)
256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid2str(ServiceClass, uuid, str, n);
258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n)
261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid2str(Profile, uuid, str, n);
263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * convert the UUID to string, copying a maximum of n characters.
267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n)
269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!uuid) {
271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "NULL");
272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -2;
273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "%.4x", uuid->value.uuid16);
277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "%.8x", uuid->value.uuid32);
280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:{
282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int   data0;
283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data1;
284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data2;
285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data3;
286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int   data4;
287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data5;
288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2968f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
2978f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg				ntohl(data0), ntohs(data1),
2988f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg				ntohs(data2), ntohs(data3),
299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				ntohl(data4), ntohs(data5));
300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
3048f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		return -1;	/* Enum type of UUID not set */
305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Function prints the UUID in hex as per defined syntax -
312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 4bytes-2bytes-2bytes-2bytes-6bytes
314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * There is some ugly code, including hardcoding, but
316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * that is just the way it is converting 16 and 32 bit
317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUIDs to 128 bit as defined in the SDP doc
318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid_print(const uuid_t *uuid)
320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid == NULL) {
322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Null passed to print UUID\n");
323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return;
324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid->type == SDP_UUID16) {
326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("  uint16_t : 0x%.4x\n", uuid->value.uuid16);
327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else if (uuid->type == SDP_UUID32) {
328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("  uint32_t : 0x%.8x\n", uuid->value.uuid32);
329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else if (uuid->type == SDP_UUID128) {
330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int data0;
331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data1;
332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data2;
333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data3;
334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned int data4;
335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		unsigned short data5;
336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("  uint128_t : 0x%.8x-", ntohl(data0));
345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x-", ntohs(data1));
346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x-", ntohs(data2));
347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x-", ntohs(data3));
348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.8x", ntohl(data4));
349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("%.4x\n", ntohs(data5));
350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else
351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Enum type of UUID not set\n");
352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3558f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergsdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value,
3568f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							uint32_t length)
357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *seq;
35921f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!d)
362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->dtd = dtd;
366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->unitSize = sizeof(uint8_t);
367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
372aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint8 = *(uint8_t *) value;
373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint8_t);
374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
377aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int8 = *(int8_t *) value;
378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int8_t);
379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
381aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint16 = bt_get_unaligned((uint16_t *) value);
382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint16_t);
383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
385aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int16 = bt_get_unaligned((int16_t *) value);
386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int16_t);
387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
389aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint32 = bt_get_unaligned((uint32_t *) value);
390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint32_t);
391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
393aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int32 = bt_get_unaligned((int32_t *) value);
394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int32_t);
395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
397aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.int64 = bt_get_unaligned((int64_t *) value);
398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(int64_t);
399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
401aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint64 = bt_get_unaligned((uint64_t *) value);
402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint64_t);
403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&d->val.uint128.data, value, sizeof(uint128_t));
406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint128_t);
407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		memcpy(&d->val.int128.data, value, sizeof(uint128_t));
410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint128_t);
411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
413aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value));
414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint16_t);
415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
417aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value));
418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint32_t);
419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid128_create(&d->val.uuid, value);
422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->unitSize += sizeof(uint128_t);
423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
426641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_TEXT_STR8:
427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
428641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (!value) {
429641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			free(d);
430641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			return NULL;
431641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		}
432641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
433641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		d->unitSize += length;
434641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (length <= USHRT_MAX) {
435641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			d->val.str = malloc(length);
436641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			if (!d->val.str) {
437641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann				free(d);
438641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann				return NULL;
439641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			}
440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
441641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			memcpy(d->val.str, value, length);
442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		} else {
443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPERR("Strings of size > USHRT_MAX not supported\n");
444641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			free(d);
445641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			d = NULL;
446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Strings of size > USHRT_MAX not supported\n");
451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (dtd == SDP_ALT8 || dtd == SDP_SEQ8)
459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += sizeof(uint8_t);
460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16)
461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += sizeof(uint16_t);
462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32)
463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += sizeof(uint32_t);
464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = (sdp_data_t *)value;
465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d->val.dataseq = seq;
466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (; seq; seq = seq->next)
467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->unitSize += seq->unitSize;
468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
470641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		free(d);
471641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		d = NULL;
472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
473641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
475641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann}
476641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
477641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value)
478641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann{
479641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	uint32_t length;
480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
481641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	switch (dtd) {
482641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR8:
483641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR16:
484641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_TEXT_STR8:
485641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_TEXT_STR16:
486641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (!value)
487641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			return NULL;
488641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
489641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		length = strlen((char *) value);
490641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		break;
491641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	default:
492641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		length = 0;
493641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		break;
494641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	}
495641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
496641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	return sdp_data_alloc_with_length(dtd, value, length);
497542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d)
500542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seq) {
502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *p;
503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = seq; p->next; p = p->next);
504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p->next = d;
505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else
506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = d;
507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->next = NULL;
508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seq;
509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
5118f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergsdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length,
5128f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg								int len)
513641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann{
514641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	sdp_data_t *curr = NULL, *seq = NULL;
515641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	int i;
516641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
517641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	for (i = 0; i < len; i++) {
518641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		sdp_data_t *data;
519641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		int8_t dtd = *(uint8_t *) dtds[i];
520641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
521641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
522641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			data = (sdp_data_t *) values[i];
523641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		else
524641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			data = sdp_data_alloc_with_length(dtd, values[i], length[i]);
525641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
526641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (!data)
527641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			return NULL;
528641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
529641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		if (curr)
530641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			curr->next = data;
531641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		else
532641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			seq = data;
533641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
534641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		curr = data;
535641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	}
536641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
537641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	return sdp_data_alloc_with_length(SDP_SEQ8, seq, length[i]);
538641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann}
539641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len)
541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *curr = NULL, *seq = NULL;
543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i;
544542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0; i < len; i++) {
546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data;
547641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann		uint8_t dtd = *(uint8_t *) dtds[i];
548641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32)
550641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann			data = (sdp_data_t *) values[i];
551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			data = sdp_data_alloc(dtd, values[i]);
553641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!data)
555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return NULL;
556641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (curr)
558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			curr->next = data;
559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seq = data;
561641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		curr = data;
563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
564641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
565542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return sdp_data_alloc(SDP_SEQ8, seq);
566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
5684c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmannstatic void extract_svclass_uuid(sdp_data_t *data, uuid_t *uuid)
5694c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann{
5704c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	sdp_data_t *d;
5714c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
5724c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	if (!data || data->dtd < SDP_SEQ8 || data->dtd > SDP_SEQ32)
5734c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann		return;
5744c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
5754c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	d = data->val.dataseq;
5764c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	if (!d)
5774c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann		return;
5784c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
5794c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128)
5804c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann		return;
5814c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
5824c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	*uuid = d->val.uuid;
5834c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann}
5844c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *p = sdp_data_get(rec, attr);
588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (p)
590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
5914c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->attrId = attr;
593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
5944c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
5954c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
5964c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann		extract_svclass_uuid(d, &rec->svclass);
5974c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
599542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
600542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
601542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_attr_remove(sdp_record_t *rec, uint16_t attr)
602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_get(rec, attr);
6044c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
605542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->attrlist = sdp_list_remove(rec->attrlist, d);
6074c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
6084c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
6094c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann		memset(&rec->svclass, 0, sizeof(rec->svclass));
610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
612cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannvoid sdp_set_seq_len(uint8_t *ptr, uint32_t length)
613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
614d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	uint8_t dtd = *ptr++;
615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
621d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		*ptr = (uint8_t) length;
622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
627aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htons(length), (uint16_t *) ptr);
628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
633aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htonl(length), (uint32_t *) ptr);
634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
6382db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentzstatic int sdp_get_data_type(sdp_buf_t *buf, uint8_t dtd)
639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
6402db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	int data_type = 0;
641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
6422db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	data_type += sizeof(uint8_t);
643641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
6492db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_type += sizeof(uint8_t);
650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
651542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
6552db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_type += sizeof(uint16_t);
656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
6612db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_type += sizeof(uint32_t);
662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
664641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
6652db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	if (!buf->data)
6662db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		buf->buf_size += data_type;
6672db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
6682db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	return data_type;
6692db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz}
6702db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
6712db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentzstatic int sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd)
6722db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz{
6732db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	int data_type = 0;
6742db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	uint8_t *p = buf->data + buf->data_size;
6752db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
6762db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	*p++ = dtd;
6772db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	data_type = sdp_get_data_type(buf, dtd);
6782db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	buf->data_size += data_type;
6792db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
6802db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	return data_type;
681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_attrid(sdp_buf_t *buf, uint16_t attr)
684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
685542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t *p = buf->data;
686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
6878f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* data type for attr */
688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*p++ = SDP_UINT16;
689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf->data_size = sizeof(uint8_t);
690aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(attr), (uint16_t *) p);
691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint16_t);
692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	buf->data_size += sizeof(uint16_t);
693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata)
696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d;
698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = 0;
699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
7002db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	for (d = sdpdata->val.dataseq; d; d = d->next) {
7012db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		if (buf->data)
7022db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz			n += sdp_gen_pdu(buf, d);
7032db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		else
7042db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz			n += sdp_gen_buffer(buf, d);
7052db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	}
706641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return n;
708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
7102db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentzstatic int sdp_get_data_size(sdp_buf_t *buf, sdp_data_t *d)
7112db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz{
7122db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	uint32_t data_size = 0;
7132db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	uint8_t dtd = d->dtd;
7142db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7152db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	switch (dtd) {
7162db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_DATA_NIL:
7172db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7182db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT8:
7192db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint8_t);
7202db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7212db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT16:
7222db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint16_t);
7232db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7242db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT32:
7252db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint32_t);
7262db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7272db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT64:
7282db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint64_t);
7292db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7302db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT128:
7312db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint128_t);
7322db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7332db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT8:
7342db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_BOOL:
7352db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(int8_t);
7362db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7372db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT16:
7382db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(int16_t);
7392db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7402db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT32:
7412db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(int32_t);
7422db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7432db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT64:
7442db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(int64_t);
7452db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7462db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT128:
7472db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint128_t);
7482db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7492db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_TEXT_STR8:
7502db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_TEXT_STR16:
7512db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_TEXT_STR32:
7522db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_URL_STR8:
7532db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_URL_STR16:
7542db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_URL_STR32:
7552db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = d->unitSize - sizeof(uint8_t);
7562db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7572db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_SEQ8:
7582db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_SEQ16:
7592db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_SEQ32:
7602db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = get_data_size(buf, d);
7612db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7622db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_ALT8:
7632db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_ALT16:
7642db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_ALT32:
7652db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = get_data_size(buf, d);
7662db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7672db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UUID16:
7682db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint16_t);
7692db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7702db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UUID32:
7712db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint32_t);
7722db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7732db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UUID128:
7742db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint128_t);
7752db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7762db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	default:
7772db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7782db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	}
7792db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7802db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	if (!buf->data)
7812db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		buf->buf_size += data_size;
7822db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7832db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	return data_size;
7842db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz}
7852db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7866996a497c429be009a9f522c3a28ad777d2ba3b5Luiz Augusto von Dentzstatic int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d)
7872db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz{
7882db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	int orig = buf->buf_size;
7892db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7902db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	if (buf->buf_size == 0 && d->dtd == 0) {
7912db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		/* create initial sequence */
7922db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		buf->buf_size += sizeof(uint8_t);
7932db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7942db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		/* reserve space for sequence size */
7952db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		buf->buf_size += sizeof(uint8_t);
7962db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	}
7972db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7982db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	/* attribute length */
7992db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	buf->buf_size += sizeof(uint8_t) + sizeof(uint16_t);
8002db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
8012db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_get_data_type(buf, d->dtd);
8022db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_get_data_size(buf, d);
8032db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
8042db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	if (buf->buf_size > UCHAR_MAX && d->dtd == SDP_SEQ8)
8052db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		buf->buf_size += sizeof(uint8_t);
8062db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
8072db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	return buf->buf_size - orig;
8082db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz}
8092db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
812cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t pdu_size = 0, data_size = 0;
813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned char *src = NULL, is_seq = 0, is_alt = 0;
814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd = d->dtd;
815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint16_t u16;
816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t u32;
817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint64_t u64;
818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t u128;
819cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *seqp = buf->data + buf->data_size;
820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdu_size = sdp_set_data_type(buf, dtd);
8222db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	data_size = sdp_get_data_size(buf, d);
823641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = &d->val.uint8;
829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.uint16);
832cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u16;
833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.uint32);
836cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u32;
837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u64 = hton64(d->val.uint64);
840cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u64;
841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		hton128(&d->val.uint128, &u128);
844cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u128;
845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
848cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &d->val.int8;
849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.int16);
852cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u16;
853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.int32);
856cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u32;
857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u64 = hton64(d->val.int64);
860cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u64;
861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
863542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		hton128(&d->val.int128, &u128);
864cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u128;
865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
869641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR8:
870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
872cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) d->val.str;
873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		is_seq = 1;
879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		is_alt = 1;
885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.uuid.value.uuid16);
889cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u16;
890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.uuid.value.uuid32);
893cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u32;
894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
896cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &d->val.uuid.value.uuid128;
897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
901641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!is_seq && !is_alt) {
9030477cf9b6c61ab1f329206f8b40bcf8e8bfbaad5Vinicius Costa Gomes		if (src && buf && buf->buf_size >= buf->data_size + data_size) {
904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(buf->data + buf->data_size, src, data_size);
905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			buf->data_size += data_size;
90666dcd1342d3f9bf08dfc476df121c7355c84427aMarcel Holtmann		} else if (dtd != SDP_DATA_NIL) {
9070477cf9b6c61ab1f329206f8b40bcf8e8bfbaad5Vinicius Costa Gomes			SDPDBG("Gen PDU : Can't copy from invalid source or dest\n");
90866dcd1342d3f9bf08dfc476df121c7355c84427aMarcel Holtmann		}
909542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
910641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
911542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdu_size += data_size;
912641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return pdu_size;
914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void sdp_attr_pdu(void *value, void *udata)
917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);
919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
9212db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentzstatic void sdp_attr_size(void *value, void *udata)
9222db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz{
9232db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_gen_buffer((sdp_buf_t *)udata, (sdp_data_t *)value);
9242db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz}
9252db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf)
927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
9282db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	memset(buf, 0, sizeof(sdp_buf_t));
9292db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_list_foreach(rec->attrlist, sdp_attr_size, buf);
9302db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
9312db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	buf->data = malloc(buf->buf_size);
932997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	if (!buf->data)
933997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann		return -ENOMEM;
934997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	buf->data_size = 0;
935997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	memset(buf->data, 0, buf->buf_size);
9362db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
937997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf);
938997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann
939997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	return 0;
940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *p = sdp_data_get(rec, attr);
945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (p) {
947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->attrlist = sdp_list_remove(rec->attrlist, p);
948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_free(p);
949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
9504c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->attrId = attr;
9524c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
9534c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
9544c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
9554c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann		extract_svclass_uuid(d, &rec->svclass);
956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attrid_comp_func(const void *key1, const void *key2)
959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_data_t *d1 = (const sdp_data_t *)key1;
961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_data_t *d2 = (const sdp_data_t *)key2;
962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d1 && d2)
964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return d1->attrId - d2->attrId;
965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void data_seq_free(sdp_data_t *seq)
969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = seq->val.dataseq;
971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (d) {
973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *next = d->next;
974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_free(d);
975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d = next;
976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_free(sdp_data_t *d)
980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_seq_free(d);
986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d->val.str);
994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(d);
997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
999d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmannint sdp_uuid_extract(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned)
1000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1001a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	uint8_t type;
1002a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1003cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1004a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1005a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return -1;
1006a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1007a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1008a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	type = *(const uint8_t *) p;
1009a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1010a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (!SDP_IS_UUID(type)) {
1011a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unknown data type : %d expecting a svc UUID\n", type);
1012a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return -1;
1013a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1014a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	p += sizeof(uint8_t);
1015a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	*scanned += sizeof(uint8_t);
1016a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= sizeof(uint8_t);
1017a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (type == SDP_UUID16) {
1018cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint16_t)) {
1019a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Not enough room for 16-bit UUID");
1020a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return -1;
1021a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1022a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p)));
1023a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*scanned += sizeof(uint16_t);
1024a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		p += sizeof(uint16_t);
1025a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	} else if (type == SDP_UUID32) {
1026cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint32_t)) {
1027a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Not enough room for 32-bit UUID");
1028a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return -1;
1029a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1030a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p)));
1031a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*scanned += sizeof(uint32_t);
1032a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		p += sizeof(uint32_t);
1033a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	} else {
1034cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint128_t)) {
1035a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Not enough room for 128-bit UUID");
1036a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return -1;
1037a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1038a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		sdp_uuid128_create(uuid, p);
1039a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*scanned += sizeof(uint128_t);
1040a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		p += sizeof(uint128_t);
1041a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1042a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	return 0;
1043a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann}
1044a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1045a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannstatic sdp_data_t *extract_int(const void *p, int bufsize, int *len)
1046a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann{
1047a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	sdp_data_t *d;
1048a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1049cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1050a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1051a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1052a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1053a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1054a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	d = malloc(sizeof(sdp_data_t));
1055114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!d)
1056114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
1057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting integer\n");
1059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
1060aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
1061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
1062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += sizeof(uint8_t);
1063a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= sizeof(uint8_t);
1064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
1066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1071cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint8_t)) {
1072a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1073a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1074a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1075a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint8_t);
1077aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint8 = *(uint8_t *) p;
1078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1080542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1081cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint16_t)) {
1082a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1083a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1084a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1085a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint16_t);
1087aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p));
1088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1091cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint32_t)) {
1092a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1093a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1094a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1095a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint32_t);
1097aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p));
1098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1101cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint64_t)) {
1102a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1103a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1104a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1105a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint64_t);
1107aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p));
1108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1111cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint128_t)) {
1112a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1113a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1114a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1115a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint128_t);
1117aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		ntoh128((uint128_t *) p, &d->val.uint128);
1118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
1121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d = NULL;
1122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
11268f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergstatic sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len,
11278f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_record_t *rec)
1128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
112921f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
1130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1131114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!d)
1132114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
1133114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
1134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting UUID");
1135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
1136d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann	if (sdp_uuid_extract(p, bufsize, &d->val.uuid, len) < 0) {
1137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
1138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
1139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1140d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	d->dtd = *p;
11419d9a7646b189cc2471b925cc448862e14c10c0c4Marcel Holtmann	if (rec)
11429d9a7646b189cc2471b925cc448862e14c10c0c4Marcel Holtmann		sdp_pattern_add_uuid(rec, &d->val.uuid);
1143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
11478f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * Extract strings from the PDU (could be service description and similar info)
1148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1149a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannstatic sdp_data_t *extract_str(const void *p, int bufsize, int *len)
1150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *s;
1152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
1153a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	sdp_data_t *d;
1154a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1155cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1156a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1157a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1158a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1159a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1160a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	d = malloc(sizeof(sdp_data_t));
1161114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!d)
1162114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
1163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
1165aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
1166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
1167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += sizeof(uint8_t);
1168a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= sizeof(uint8_t);
1169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
1171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1173cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint8_t)) {
1174a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1175a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1176a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1177a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1178aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		n = *(uint8_t *) p;
1179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
1180a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*len += sizeof(uint8_t);
1181a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		bufsize -= sizeof(uint8_t);
1182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1185cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint16_t)) {
1186a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1187a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1188a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1189a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1190aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		n = ntohs(bt_get_unaligned((uint16_t *) p));
1191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint16_t);
1192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint16_t) + n;
1193a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		bufsize -= sizeof(uint16_t);
1194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Sizeof text string > UINT16_MAX\n");
1197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
1198f58df2db7a606fcd13a36824bdb4fc3440d9a71eSantiago Carot-Nemesio		return NULL;
1199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1201a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (bufsize < n) {
1202a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("String too long to fit in packet");
1203a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		free(d);
1204a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1205a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1206a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1207ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann	s = malloc(n + 1);
1208a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (!s) {
1209a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Not enough memory for incoming string");
1210a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		free(d);
1211a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1212a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(s, 0, n + 1);
1214ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann	memcpy(s, p, n);
1215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1216a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	*len += n;
1217a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1218542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Len : %d\n", n);
1219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Str : %s\n", s);
1220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->val.str = s;
12220ed4f8572e1b32b4dd57304db14351f0e0c59119Marcel Holtmann	d->unitSize = n + sizeof(uint8_t);
1223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1226a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann/*
1227a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann * Extract the sequence type and its length, and return offset into buf
1228a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann * or 0 on failure.
1229a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann */
1230d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmannint sdp_extract_seqtype(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size)
1231a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann{
1232a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	uint8_t dtd;
1233a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	int scanned = sizeof(uint8_t);
1234a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1235cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1236a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1237a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return 0;
1238a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1239a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1240a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	dtd = *(uint8_t *) buf;
1241a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	buf += sizeof(uint8_t);
1242a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= sizeof(uint8_t);
1243a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	*dtdp = dtd;
1244a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	switch (dtd) {
1245a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_SEQ8:
1246a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_ALT8:
1247cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint8_t)) {
1248a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1249a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return 0;
1250a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1251a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*size = *(uint8_t *) buf;
1252a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		scanned += sizeof(uint8_t);
1253a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		break;
1254a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_SEQ16:
1255a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_ALT16:
1256cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint16_t)) {
1257a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1258a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return 0;
1259a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1260a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*size = ntohs(bt_get_unaligned((uint16_t *) buf));
1261a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		scanned += sizeof(uint16_t);
1262a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		break;
1263a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_SEQ32:
1264a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_ALT32:
1265cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint32_t)) {
1266a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1267a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return 0;
1268a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1269a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*size = ntohl(bt_get_unaligned((uint32_t *) buf));
1270a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		scanned += sizeof(uint32_t);
1271a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		break;
1272a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	default:
1273a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unknown sequence type, aborting\n");
1274a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return 0;
1275a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1276a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	return scanned;
1277a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann}
1278a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
12798f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergstatic sdp_data_t *extract_seq(const void *p, int bufsize, int *len,
12808f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_record_t *rec)
1281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen, n = 0;
1283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *curr, *prev;
128421f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
1285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1286114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!d)
1287114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
1288114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
1289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting SEQ");
1290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
1291d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann	*len = sdp_extract_seqtype(p, bufsize, &d->dtd, &seqlen);
1292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen);
1293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (*len == 0)
1295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return d;
1296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1297a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (*len > bufsize) {
1298a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Packet not big enough to hold sequence.");
1299a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		free(d);
1300a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1301a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1302a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += *len;
1304a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= *len;
130558a7ff1f9e789b7354bb1feb02f9b7ca5198ec65Luiz Augusto von Dentz	prev = NULL;
1306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (n < seqlen) {
1307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int attrlen = 0;
1308d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann		curr = sdp_extract_attr(p, bufsize, &attrlen, rec);
1309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (curr == NULL)
1310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (prev)
1313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			prev->next = curr;
1314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
1315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->val.dataseq = curr;
1316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		prev = curr;
1317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += attrlen;
1318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += attrlen;
1319a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		bufsize -= attrlen;
1320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen);
1322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += n;
1325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
13288f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergsdp_data_t *sdp_extract_attr(const uint8_t *p, int bufsize, int *size,
13298f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_record_t *rec)
1330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *elem;
1332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = 0;
1333a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	uint8_t dtd;
1334a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1335cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1336a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1337a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1338a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1339a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1340a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	dtd = *(const uint8_t *)p;
1341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("extract_attr: dtd=0x%x", dtd);
1343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
1344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1356a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		elem = extract_int(p, bufsize, &n);
1357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1361a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		elem = extract_uuid(p, bufsize, &n, rec);
1362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
1366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
1369a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		elem = extract_str(p, bufsize, &n);
1370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1377a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		elem = extract_seq(p, bufsize, &n, rec);
1378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd);
1381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
1382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*size += n;
1384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return elem;
1385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void attr_print_func(void *value, void *userData)
1389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = (sdp_data_t *)value;
1391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("=====================================\n");
1393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n",  d->attrId);
1394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value);
1395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
1396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_print(d);
1397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
1398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("NULL value\n");
1399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("=====================================\n");
1400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_print_service_attr(sdp_list_t *svcAttrList)
1403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
14048bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann	SDPDBG("Printing service attr list %p\n", svcAttrList);
1405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_foreach(svcAttrList, attr_print_func, NULL);
14068bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann	SDPDBG("Printed service attr list %p\n", svcAttrList);
1407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1410d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmannsdp_record_t *sdp_extract_pdu(const uint8_t *buf, int bufsize, int *scanned)
1411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int extracted = 0, seqlen = 0;
1413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd;
1414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint16_t attr;
1415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_record_t *rec = sdp_record_alloc();
1416cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	const uint8_t *p = buf;
1417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1418d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann	*scanned = sdp_extract_seqtype(buf, bufsize, &dtd, &seqlen);
1419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += *scanned;
14200e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann	bufsize -= *scanned;
1421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->attrlist = NULL;
14220e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann
14230e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann	while (extracted < seqlen && bufsize > 0) {
1424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int n = sizeof(uint8_t), attrlen = 0;
1425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data = NULL;
1426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
14270e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann		SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d",
14280e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann							seqlen, extracted);
14290e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann
1430cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < n + (int) sizeof(uint16_t)) {
14310e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann			SDPERR("Unexpected end of packet");
14320e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann			break;
14330e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann		}
14340e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann
1435aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		dtd = *(uint8_t *) p;
1436aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		attr = ntohs(bt_get_unaligned((uint16_t *) (p + n)));
1437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += sizeof(uint16_t);
1438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr);
1440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1441d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann		data = sdp_extract_attr(p + n, bufsize - n, &attrlen, rec);
1442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen);
1444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += attrlen;
1446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (data == NULL) {
1447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Terminating extraction of attributes");
1448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
14504c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
1451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (attr == SDP_ATTR_RECORD_HANDLE)
1452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rec->handle = data->val.uint32;
14534c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
14544c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann		if (attr == SDP_ATTR_SVCLASS_ID_LIST)
14554c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann			extract_svclass_uuid(data, &rec->svclass);
14564c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
1457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		extracted += n;
1458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += n;
14590e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann		bufsize -= n;
1460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, attr, data);
14610e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann
1462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",
14630e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann							seqlen, extracted);
1464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Successful extracting of Svc Rec attributes\n");
1467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_print_service_attr(rec->attrlist);
1468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*scanned += seqlen;
1470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
1471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1473e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentzstatic void sdp_copy_pattern(void *value, void *udata)
1474e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1475e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	uuid_t *uuid = value;
1476e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_record_t *rec = udata;
1477e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1478e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_pattern_add_uuid(rec, uuid);
1479e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1480e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1481eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocerastatic void *sdp_data_value(sdp_data_t *data, uint32_t *len)
1482e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1483e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	void *val = NULL;
1484e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1485e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	switch (data->dtd) {
1486e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_DATA_NIL:
1487e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1488e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT8:
1489e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint8;
1490e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1491e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT8:
1492e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_BOOL:
1493e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int8;
1494e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1495e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT16:
1496e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint16;
1497e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1498e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT16:
1499e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int16;
1500e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1501e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT32:
1502e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint32;
1503e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1504e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT32:
1505e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int32;
1506e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1507e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT64:
1508e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int64;
1509e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1510e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT64:
1511e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint64;
1512e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1513e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT128:
1514e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint128;
1515e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1516e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT128:
1517e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int128;
1518e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1519e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UUID16:
15200472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		val = &data->val.uuid.value.uuid16;
15210472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		break;
1522e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UUID32:
15230472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		val = &data->val.uuid.value.uuid32;
15240472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		break;
1525e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UUID128:
15260472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		val = &data->val.uuid.value.uuid128;
1527e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1528e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_URL_STR8:
1529e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_URL_STR16:
1530e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_TEXT_STR8:
1531e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_TEXT_STR16:
1532e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_URL_STR32:
1533e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_TEXT_STR32:
1534e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = data->val.str;
1535eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		if (len)
1536eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera			*len = data->unitSize - 1;
1537e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1538e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_ALT8:
1539e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_ALT16:
1540e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_ALT32:
1541e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_SEQ8:
1542e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_SEQ16:
1543e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_SEQ32:
1544e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = sdp_copy_seq(data->val.dataseq);
1545e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1546e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	}
1547e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1548e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	return val;
1549e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1550e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1551e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentzstatic sdp_data_t *sdp_copy_seq(sdp_data_t *data)
1552e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1553e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_data_t *tmp, *seq = NULL, *cur = NULL;
1554e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1555e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	for (tmp = data; tmp; tmp = tmp->next) {
1556e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		sdp_data_t *datatmp;
1557e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		void *value;
1558e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1559eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		value = sdp_data_value(tmp, NULL);
1560e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		datatmp = sdp_data_alloc_with_length(tmp->dtd, value,
1561d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann								tmp->unitSize);
1562e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1563e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		if (cur)
1564e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz			cur->next = datatmp;
1565e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		else
1566e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz			seq = datatmp;
1567e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1568e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		cur = datatmp;
1569e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	}
1570e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1571e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	return seq;
1572e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1573e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1574e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentzstatic void sdp_copy_attrlist(void *value, void *udata)
1575e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1576e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_data_t *data = value;
1577e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_record_t *rec = udata;
1578e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	void *val;
1579eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	uint32_t len = 0;
1580e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1581eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	val = sdp_data_value(data, &len);
1582e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1583eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	if (!len)
1584eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		sdp_attr_add_new(rec, data->attrId, data->dtd, val);
1585eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	else
1586eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		sdp_attr_add_new_with_length(rec, data->attrId,
1587d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann							data->dtd, val, len);
1588e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1589e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1590e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentzsdp_record_t *sdp_copy_record(sdp_record_t *rec)
1591e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1592e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_record_t *cpy;
1593e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1594e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	cpy = sdp_record_alloc();
1595e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1596e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	cpy->handle = rec->handle;
1597e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1598e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_list_foreach(rec->pattern, sdp_copy_pattern, cpy);
1599e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_list_foreach(rec->attrlist, sdp_copy_attrlist, cpy);
1600e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1601e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	cpy->svclass = rec->svclass;
1602e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1603e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	return cpy;
1604e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1605e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void print_dataseq(sdp_data_t *p)
1608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d;
1610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (d = p; d; d = d->next)
1612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_print(d);
1613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1614542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_print(const sdp_record_t *rec)
1617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
1619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
16206d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann		printf("Service Name: %.*s\n", d->unitSize, d->val.str);
1621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
1622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
16236d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann		printf("Service Description: %.*s\n", d->unitSize, d->val.str);
1624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
1625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
16266d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann		printf("Service Provider: %.*s\n", d->unitSize, d->val.str);
1627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_print(sdp_data_t *d)
1631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
1633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("NIL\n");
1635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Integer : 0x%x\n", d->val.uint32);
1648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1651542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("UUID\n");
1653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid_print(&d->val.uuid);
1654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
1658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Text : %s\n", d->val.str);
1659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
1663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("URL : %s\n", d->val.str);
1664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		print_dataseq(d->val.dataseq);
1669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Data Sequence Alternates\n");
1674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		print_dataseq(d->val.dataseq);
1675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId)
1681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rec->attrlist) {
1683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t sdpTemplate;
1684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1685542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpTemplate.attrId = attrId;
1687542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func);
1688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (p)
1689d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann			return p->data;
1690542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
16914c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	return NULL;
1692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1694be2ffca847c7537f01b90c7933a2b288306b1f0bMarcel Holtmannstatic int sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size)
1695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1696cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t sent = 0;
1697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (sent < size) {
1699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int n = send(session->sock, buf + sent, size - sent, 0);
1700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (n < 0)
1701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return -1;
1702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sent += n;
1703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1705542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1707be2ffca847c7537f01b90c7933a2b288306b1f0bMarcel Holtmannstatic int sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size)
1708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	fd_set readFds;
1710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 };
1711542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
171273fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann	FD_ZERO(&readFds);
1713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	FD_SET(session->sock, &readFds);
1714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Waiting for response\n");
171573fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann	if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) {
1716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Client timed out\n");
1717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ETIMEDOUT;
1718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return recv(session->sock, buf, size, 0);
1721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1722542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * generic send request, wait for response method.
1725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
17268f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergint sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf,
17278f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize)
1728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
1730d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *) reqbuf;
1731d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *) rspbuf;
1732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
1734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > sdp_send_req(session, reqbuf, reqsize)) {
1735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Error sending data:%s", strerror(errno));
1736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
1739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > n)
1740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Read : %d\n", n);
1742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (n == 0 || reqhdr->tid != rsphdr->tid) {
1743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EPROTO;
1744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rspsize = n;
1747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * singly-linked lists (after openobex implementation)
1752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_append(sdp_list_t *p, void *d)
1754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
175521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_list_t *q, *n = malloc(sizeof(sdp_list_t));
1756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!n)
1758f58df2db7a606fcd13a36824bdb4fc3440d9a71eSantiago Carot-Nemesio		return NULL;
1759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->data = d;
1761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->next = 0;
1762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!p)
1764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return n;
1765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = p; q->next; q = q->next);
1767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	q->next = n;
1768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return p;
1770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_remove(sdp_list_t *list, void *d)
1773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p, *q;
1775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = 0, p = list; p; q = p, p = p->next)
1777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (p->data == d) {
1778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (q)
1779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				q->next = p->next;
1780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			else
1781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				list = p->next;
1782542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			free(p);
1783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return list;
1787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
17898f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergsdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d,
17908f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_comp_func_t f)
1791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *q, *p, *n;
1793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
179421f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	n = malloc(sizeof(sdp_list_t));
1795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!n)
1796f58df2db7a606fcd13a36824bdb4fc3440d9a71eSantiago Carot-Nemesio		return NULL;
1797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->data = d;
1798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = 0, p = list; p; q = p, p = p->next)
1799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (f(p->data, d) >= 0)
18008f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			break;
18013d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* insert between q and p; if !q insert at head */
1802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (q)
1803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		q->next = n;
1804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
1805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		list = n;
1806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->next = p;
1807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return list;
1808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
18118f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * Every element of the list points to things which need
1812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to be free()'d. This method frees the list's contents
1813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_list_free(sdp_list_t *list, sdp_free_func_t f)
1815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *next;
1817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (list) {
1818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		next = list->next;
1819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (f)
1820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			f(list->data);
1821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(list);
1822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		list = next;
1823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int __find_port(sdp_data_t *seq, int proto)
1827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!seq || !seq->next)
1829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) {
1832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = seq->next;
1833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		switch (seq->dtd) {
1834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UINT8:
1835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return seq->val.uint8;
1836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UINT16:
1837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return seq->val.uint16;
1838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_proto_port(const sdp_list_t *list, int proto)
1844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (proto != L2CAP_UUID && proto != RFCOMM_UUID) {
1846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
1847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; list; list = list->next) {
1851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = list->data; p; p = p->next) {
1853d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann			sdp_data_t *seq = p->data;
1854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			int port = __find_port(seq, proto);
1855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (port)
1856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return port;
1857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto)
1863542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; list; list = list->next) {
1865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = list->data; p; p = p->next) {
1867d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann			sdp_data_t *seq = p->data;
18688f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			if (SDP_IS_UUID(seq->dtd) &&
1869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					sdp_uuid_to_proto(&seq->val.uuid) == proto)
1870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return seq->next;
1871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return NULL;
1874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *pdlist, *curr;
1879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *ap = 0;
1880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdlist = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
1882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (pdlist == NULL) {
1883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; pdlist; pdlist = pdlist->next) {
1889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *pds = 0;
1890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pds = sdp_list_append(pds, curr->val.dataseq);
1892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		ap = sdp_list_append(ap, pds);
1893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*pap = ap;
1895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1898233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmannint sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1899233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann{
1900233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	sdp_data_t *pdlist, *curr;
1901233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	sdp_list_t *ap = 0;
1902233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1903233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
1904233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	if (pdlist == NULL) {
1905233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		errno = ENODATA;
1906233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		return -1;
1907233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	}
1908233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1909233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1910233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	pdlist = pdlist->val.dataseq;
1911233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1912233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	for (; pdlist; pdlist = pdlist->next) {
1913233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		sdp_list_t *pds = 0;
1914233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1915233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann			pds = sdp_list_append(pds, curr->val.dataseq);
1916233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		ap = sdp_list_append(ap, pds);
1917233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	}
1918233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	*pap = ap;
1919233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	return 0;
1920233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann}
1921233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
19228f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergint sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr,
19238f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_list_t **seqp)
1924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attr);
1926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*seqp = NULL;
1928542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) {
1929542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *d;
1930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (d = sdpdata->val.dataseq; d; d = d->next) {
19311f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			uuid_t *u;
1932114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) {
1933114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				errno = EINVAL;
1934542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				goto fail;
1935114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			}
19361f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi
19371f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			u = malloc(sizeof(uuid_t));
1938114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			if (!u)
1939114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				goto fail;
1940114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
19411f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			memset(u, 0, sizeof(uuid_t));
19421f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			*u = d->val.uuid;
19431f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			*seqp = sdp_list_append(*seqp, u);
1944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail:
1948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(*seqp, free);
1949114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	*seqp = NULL;
1950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq)
1954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0, i, len;
1956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **dtds, **values;
1957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid16 = SDP_UUID16;
1958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid32 = SDP_UUID32;
1959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid128 = SDP_UUID128;
1960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p;
1961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	len = sdp_list_len(seq);
1963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!seq || len == 0)
1964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1965114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	dtds = malloc(len * sizeof(void *));
1966114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!dtds)
1967114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
1968114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
1969114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	values = malloc(len * sizeof(void *));
1970114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!values) {
1971114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		free(dtds);
1972114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
1973114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	}
1974114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
1975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = seq, i = 0; i < len; i++, p = p->next) {
1976d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		uuid_t *uuid = p->data;
1977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (uuid)
1978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			switch (uuid->type) {
1979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID16:
1980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid16;
1981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid16;
1982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID32:
1984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid32;
1985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid32;
1986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID128:
1988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid128;
1989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid128;
1990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			default:
1992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				status = -1;
1993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
1995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else {
1996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data = sdp_seq_alloc(dtds, values, len);
2002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, aid, data);
2003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_pattern_add_uuidseq(rec, seq);
2004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(dtds);
2006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
2007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq)
2011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_lang_attr_t *lang;
2013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata, *curr_data;
2014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*langSeq = NULL;
2016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST);
2017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata == NULL) {
2018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
2019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2020542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	curr_data = sdpdata->val.dataseq;
2022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (curr_data) {
2023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pCode = curr_data;
20240f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		sdp_data_t *pEncoding;
20250f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		sdp_data_t *pOffset;
20260f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
20270f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		pEncoding = pCode->next;
20280f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		if (!pEncoding)
20290f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			break;
20300f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
20310f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		pOffset = pEncoding->next;
20320f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		if (!pOffset)
20330f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			break;
20340f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
20350f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		lang = malloc(sizeof(sdp_lang_attr_t));
20360f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		if (!lang) {
20370f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			sdp_list_free(*langSeq, free);
20380f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			*langSeq = NULL;
20390f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			return -1;
2040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
20410f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		lang->code_ISO639 = pCode->val.uint16;
20420f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		lang->encoding = pEncoding->val.uint16;
20430f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		lang->base_offset = pOffset->val.uint16;
20440f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		SDPDBG("code_ISO639 :  0x%02x\n", lang->code_ISO639);
20450f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		SDPDBG("encoding :     0x%02x\n", lang->encoding);
20460f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		SDPDBG("base_offfset : 0x%02x\n", lang->base_offset);
20470f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		*langSeq = sdp_list_append(*langSeq, lang);
20480f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
2049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		curr_data = pOffset->next;
2050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
20510f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
2052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq)
2056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_profile_desc_t *profDesc;
2058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata, *seq;
2059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*profDescSeq = NULL;
2061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST);
2062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!sdpdata || !sdpdata->val.dataseq) {
2063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
2064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) {
20670f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		uuid_t *uuid = NULL;
20680f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		uint16_t version = 0x100;
20690f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann
20700f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		if (SDP_IS_UUID(seq->dtd)) {
20710f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			uuid = &seq->val.uuid;
20720f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		} else {
20730f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			sdp_data_t *puuid = seq->val.dataseq;
20740f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			sdp_data_t *pVnum = seq->val.dataseq->next;
20750f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			if (puuid && pVnum) {
20760f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann				uuid = &puuid->val.uuid;
20770f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann				version = pVnum->val.uint16;
20780f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			}
20790f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		}
20800f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann
20810f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		if (uuid != NULL) {
208221f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann			profDesc = malloc(sizeof(sdp_profile_desc_t));
2083114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			if (!profDesc) {
2084114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				sdp_list_free(*profDescSeq, free);
2085114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				*profDescSeq = NULL;
2086114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				return -1;
2087114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			}
20880f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			profDesc->uuid = *uuid;
20890f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			profDesc->version = version;
2090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
2091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_uuid_print(&profDesc->uuid);
2092542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Vnum : 0x%04x\n", profDesc->version);
2093542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
2094542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*profDescSeq = sdp_list_append(*profDescSeq, profDesc);
2095542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2097542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16)
2101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d, *curr;
2103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*u16 = NULL;
2105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST);
2106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d == NULL) {
2107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
2108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (curr = d->val.dataseq; curr; curr = curr->next)
2111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*u16 = sdp_list_append(*u16, &curr->val.uint16);
2112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2113542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* flexible extraction of basic attributes - Jean II */
2116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* How do we expect caller to extract predefined data sequences? */
2117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value)
2118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
2120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata)
2122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/* Verify that it is what the caller expects */
2123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 ||
2124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 ||
2125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 ||
2126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_INT32) {
2127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*value = sdpdata->val.uint32;
2128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return 0;
2129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
2131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
2132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
21348f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergint sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value,
21358f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg								int valuelen)
2136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
2138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata)
2139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/* Verify that it is what the caller expects */
21408f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		if (sdpdata->dtd == SDP_TEXT_STR8 ||
21418f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg				sdpdata->dtd == SDP_TEXT_STR16 ||
21428f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg				sdpdata->dtd == SDP_TEXT_STR32)
2143cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann			if ((int) strlen(sdpdata->val.str) < valuelen) {
2144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				strcpy(value, sdpdata->val.str);
2145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return 0;
2146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
2147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
2148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
2149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#define get_basic_attr(attrID, pAttrValue, fieldName)		\
2152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *data = sdp_data_get(rec, attrID);		\
2153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (data) {						\
2154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*pAttrValue = data->val.fieldName;		\
2155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;					\
2156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}							\
2157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;						\
2158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
2159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid)
2161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);
2163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid)
2166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);
2168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState)
2171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);
2173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2174542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail)
2176542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2177542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);
2178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo)
2181542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);
2183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2185542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState)
2186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);
2188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * NOTE that none of the setXXX() functions below will
2192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * actually update the SDP server, unless the
2193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * {register, update}sdp_record_t() function is invoked.
2194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
21968f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergint sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd,
21978f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							const void *value)
2198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_alloc(dtd, value);
2200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d) {
2201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, attr, d);
2202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
2203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
2205542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2207eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocerastatic int sdp_attr_add_new_with_length(sdp_record_t *rec,
2208eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	uint16_t attr, uint8_t dtd, const void *value, uint32_t len)
2209eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera{
2210eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	sdp_data_t *d;
2211eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera
2212eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	d = sdp_data_alloc_with_length(dtd, value, len);
2213eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	if (!d)
2214eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		return -1;
2215eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera
2216eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	sdp_attr_replace(rec, attr, d);
2217eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera
2218eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	return 0;
2219eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera}
2220eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera
2221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2222542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Set the information attributes of the service
2223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by rec. The attributes are
2224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * service name, description and provider name
2225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
22268f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergvoid sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov,
22278f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							const char *desc)
2228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (name)
2230d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY,
2231d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann							SDP_TEXT_STR8, name);
2232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (prov)
2233d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY,
2234d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann							SDP_TEXT_STR8, prov);
2235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (desc)
2236d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY,
2237d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann							SDP_TEXT_STR8, desc);
2238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto)
2241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *seq = NULL;
2243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void *dtds[10], *values[10];
2244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **seqDTDs, **seqs;
2245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i, seqlen;
2246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p;
2247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2248542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = sdp_list_len(proto);
2249114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	seqDTDs = malloc(seqlen * sizeof(void *));
2250114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!seqDTDs)
2251114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
2252114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2253114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	seqs = malloc(seqlen * sizeof(void *));
2254114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!seqs) {
2255114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		free(seqDTDs);
2256114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
2257114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	}
2258114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0, p = proto; p; p = p->next, i++) {
2260d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_list_t *elt = p->data;
2261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *s;
22624e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann		uuid_t *uuid = NULL;
2263cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		unsigned int pslen = 0;
2264206da78a25ae175741a7444edd13dcf67bbdf059Luiz Augusto von Dentz		for (; elt && pslen < ARRAY_SIZE(dtds); elt = elt->next, pslen++) {
2265d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann			sdp_data_t *d = elt->data;
2266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[pslen] = &d->dtd;
2267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			switch (d->dtd) {
2268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID16:
22694e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				uuid = (uuid_t *) d;
22704e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				values[pslen] = &uuid->value.uuid16;
2271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID32:
22734e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				uuid = (uuid_t *) d;
22744e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				values[pslen] = &uuid->value.uuid32;
2275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID128:
22774e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				uuid = (uuid_t *) d;
22784e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				values[pslen] = &uuid->value.uuid128;
2279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UINT8:
2281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &d->val.uint8;
2282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UINT16:
2284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &d->val.uint16;
2285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ8:
2287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ16:
2288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ32:
2289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = d;
2290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
22918f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			/* FIXME: more */
2292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
2293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		s = sdp_seq_alloc(dtds, values, pslen);
2295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (s) {
2296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqDTDs[i] = &s->dtd;
2297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqs[i] = s;
22984e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann			if (uuid)
22994e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				sdp_pattern_add_uuid(rec, uuid);
2300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqDTDs);
2304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqs);
2305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seq;
2306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets the access protocols of the service specified
2310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to the value specified in "access_proto"
2311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
23128f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * Note that if there are alternate mechanisms by
23138f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * which the service is accessed, then they should
23148f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * be specified as sequences
2315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for accessProtocols has
2317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
23188f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the existing sdp_access_proto_t
2320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
2321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
2325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
2327aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_data_t *protos = NULL;
2328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = ap; p; p = p->next) {
2330d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
2331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		protos = sdp_seq_append(protos, seq);
2332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2333aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos);
2335aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2336aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	return 0;
2337aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann}
2338aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2339aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmannint sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
2340aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann{
2341aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	const sdp_list_t *p;
2342aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_data_t *protos = NULL;
2343aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2344aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	for (p = ap; p; p = p->next) {
2345d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
2346aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann		protos = sdp_seq_append(protos, seq);
2347aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	}
2348aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2349aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST,
2350aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann			protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL);
2351aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the "LanguageBase" attributes of the service record
2357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * record to the value specified in "langAttrList".
2358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * "langAttrList" is a linked list of "sdp_lang_attr_t"
2360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * objects, one for each language in which user visible
2361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attributes are present in the service record.
2362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for langAttrList has
2364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
23658f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting sdp_lang_attr_t
2367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
2368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq)
2372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uint16 = SDP_UINT16;
2374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0, i = 0, seqlen = sdp_list_len(seq);
2375114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	void **dtds, **values;
2376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
2377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2378114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	dtds = malloc(3 * seqlen * sizeof(void *));
2379114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!dtds)
2380114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
2381114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2382114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	values = malloc(3 * seqlen * sizeof(void *));
2383114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!values) {
2384114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		free(dtds);
2385114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
2386114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	}
2387114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = seq; p; p = p->next) {
2389d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_lang_attr_t *lang = p->data;
2390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!lang) {
2391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
2395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->code_ISO639;
2396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
2398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->encoding;
2399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
2401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->base_offset;
2402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen);
2406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq);
2407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(dtds);
2409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
2410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
24148f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * set the "ServiceID" attribute of the service.
24158f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
24168f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * This is the UUID of the service.
24178f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_service_id(sdp_record_t *rec, uuid_t uuid)
2421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid.type) {
2423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
24248f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16,
24258f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid16);
2426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
24288f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32,
24298f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid32);
2430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
24328f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128,
24338f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid128);
2434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &uuid);
2437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
24408f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * set the GroupID attribute of the service record defining a group.
24418f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
24428f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * This is the UUID of the group.
24438f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_group_id(sdp_record_t *rec, uuid_t uuid)
2447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid.type) {
2449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
24508f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16,
24518f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid16);
2452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
24548f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32,
24558f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid32);
2456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
24588f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128,
24598f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid128);
2460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &uuid);
2463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the ProfileDescriptorList attribute of the service record
2467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record to the value specified in "profileDesc".
2468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Each element in the list is an object of type
2470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_profile_desc_t which is a definition of the
2471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Bluetooth profile that this service conforms to.
2472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for profileDesc has
2474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
24758f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting ProfileDescriptorList
2477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
2478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles)
2482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
2484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid16 = SDP_UUID16;
2485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid32 = SDP_UUID32;
2486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid128 = SDP_UUID128;
2487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uint16 = SDP_UINT16;
2488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i = 0, seqlen = sdp_list_len(profiles);
2489114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	void **seqDTDs, **seqs;
2490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
2491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2492114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	seqDTDs = malloc(seqlen * sizeof(void *));
2493114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!seqDTDs)
2494114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
2495114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2496114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	seqs = malloc(seqlen * sizeof(void *));
2497114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!seqs) {
2498114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		free(seqDTDs);
2499114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
2500114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	}
2501114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = profiles; p; p = p->next) {
2503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *seq;
2504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		void *dtds[2], *values[2];
2505d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_profile_desc_t *profile = p->data;
2506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!profile) {
2507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		switch (profile->uuid.type) {
2511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID16:
2512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid16;
2513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid16;
2514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID32:
2516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid32;
2517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid32;
2518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID128:
2520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid128;
2521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid128;
2522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2523542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		default:
2524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[1] = &uint16;
2528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[1] = &profile->version;
2529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = sdp_seq_alloc(dtds, values, 2);
2530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (seq) {
2531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqDTDs[i] = &seq->dtd;
2532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqs[i] = seq;
2533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_pattern_add_uuid(rec, &profile->uuid);
2534542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2537542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2538542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq);
2540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqDTDs);
2542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqs);
2543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2544542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets various URL attributes of the service
2548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record. The URL include
2549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * client: a URL to the client's
2551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   platform specific (WinCE, PalmOS) executable
2552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   code that can be used to access this service.
2553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * doc: a URL pointing to service documentation
2555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * icon: a URL to an icon that can be used to represent
2557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   this service.
2558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Note that you need to pass NULL for any URLs
2560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * that you don't want to set or remove
2561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
25628f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergvoid sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc,
25638f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							const char *icon)
2564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2565542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client);
2566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc);
2567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon);
2568542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val)
2571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID16;
2574542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->value.uuid16 = val;
2575542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val)
2579542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID32;
2582542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->value.uuid32 = val;
2583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid128_create(uuid_t *u, const void *val)
25878f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg{
2588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID128;
2590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&u->value.uuid128, val, sizeof(uint128_t));
2591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2595542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function
2596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1
2597542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
259868a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentzint sdp_uuid_cmp(const void *p1, const void *p2)
259968a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz{
2600bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmann	uuid_t *u1 = sdp_uuid_to_uuid128(p1);
2601bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmann	uuid_t *u2 = sdp_uuid_to_uuid128(p2);
260268a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	int ret;
260368a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz
260468a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	ret = sdp_uuid128_cmp(u1, u2);
260568a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz
260668a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	bt_free(u1);
260768a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	bt_free(u2);
260868a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz
260968a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	return ret;
261068a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz}
261168a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz
261268a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz/*
261368a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz * UUID comparison function
261468a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz * returns 0 if uuidValue1 == uuidValue2 else -1
261568a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz */
2616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid16_cmp(const void *p1, const void *p2)
2617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2618d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	const uuid_t *u1 = p1;
2619d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	const uuid_t *u2 = p2;
2620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t));
2621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function
2625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1
2626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_cmp(const void *p1, const void *p2)
2628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2629d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	const uuid_t *u1 = p1;
2630d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	const uuid_t *u2 = p2;
2631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t));
2632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 128 to 16 bit and 32 to 16 bit UUID conversion functions
2636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * yet to be implemented. Note that the input is in NBO in
2637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * both 32 and 128 bit UUIDs and conversion is needed
2638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2639bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmannvoid sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16)
2640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	/*
2642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * We have a 16 bit value, which needs to be added to
2643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base
2644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 */
2645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned short data1;
2646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26478f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* allocate a 128bit UUID and init to the Bluetooth base UUID */
26483f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	uuid128->value.uuid128 = bluetooth_base_uuid;
2649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->type = SDP_UUID128;
2650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26518f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* extract bytes 2 and 3 of 128bit BT base UUID */
26523f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	memcpy(&data1, &bluetooth_base_uuid.data[2], 2);
2653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26548f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* add the given UUID (16 bits) */
2655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data1 += htons(uuid16->value.uuid16);
2656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26578f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* set bytes 2 and 3 of the 128 bit value */
2658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&uuid128->value.uuid128.data[2], &data1, 2);
2659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2661bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmannvoid sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32)
2662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	/*
2664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * We have a 32 bit value, which needs to be added to
2665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base
2666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 */
2667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned int data0;
2668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26698f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* allocate a 128bit UUID and init to the Bluetooth base UUID */
26703f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	uuid128->value.uuid128 = bluetooth_base_uuid;
2671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->type = SDP_UUID128;
2672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26738f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* extract first 4 bytes */
26743f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	memcpy(&data0, &bluetooth_base_uuid.data[0], 4);
2675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26768f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* add the given UUID (32bits) */
2677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data0 += htonl(uuid32->value.uuid32);
2678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26798f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* set the 4 bytes of the 128 bit value */
2680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&uuid128->value.uuid128.data[0], &data0, 4);
2681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2683bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmannuuid_t *sdp_uuid_to_uuid128(const uuid_t *uuid)
2684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
268521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	uuid_t *uuid128 = bt_malloc(sizeof(uuid_t));
2686114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2687114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!uuid128)
2688114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
2689114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2690542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(uuid128, 0, sizeof(uuid_t));
2691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
2692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
2693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*uuid128 = *uuid;
2694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
2696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid32_to_uuid128(uuid128, uuid);
2697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
2699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid16_to_uuid128(uuid128, uuid);
2700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid128;
2703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
27058f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg/*
2706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * converts a 128-bit uuid to a 16/32-bit one if possible
2707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns true if uuid contains a 16/32-bit UUID at exit
2708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_to_uuid(uuid_t *uuid)
2710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
27113f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	uint128_t *b = &bluetooth_base_uuid;
2712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *u = &uuid->value.uuid128;
2713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t data;
2714cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	unsigned int i;
2715a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid->type != SDP_UUID128)
2717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 1;
2718a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 4; i < sizeof(b->data); i++)
2720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (b->data[i] != u->data[i])
2721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return 0;
2722a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&data, u->data, 4);
2724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data = htonl(data);
2725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (data <= 0xffff) {
2726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->type = SDP_UUID16;
27273f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann		uuid->value.uuid16 = (uint16_t) data;
2728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
2729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->type = SDP_UUID32;
2730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->value.uuid32 = data;
2731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 1;
2733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * convert a UUID to the 16-bit short-form
2737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid_to_proto(uuid_t *uuid)
2739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid_t u = *uuid;
2741a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann	if (sdp_uuid128_to_uuid(&u)) {
2742a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		switch (u.type) {
2743a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		case SDP_UUID16:
2744a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann			return u.value.uuid16;
2745a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		case SDP_UUID32:
2746a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann			return u.value.uuid32;
2747a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		}
2748a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann	}
2749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
27538f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * This function appends data to the PDU buffer "dst" from source "src".
2754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The data length is also computed and set.
2755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Should the PDU length exceed 2^8, then sequence type is
2756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set accordingly and the data is memmove()'d.
2757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2758cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannvoid sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len)
2759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2760cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *p = dst->data;
2761d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	uint8_t dtd = *p;
2762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Append src size: %d\n", len);
2764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Append dst size: %d\n", dst->data_size);
2765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Dst buffer size: %d\n", dst->buf_size);
2766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size == 0 && dtd == 0) {
27678f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		/* create initial sequence */
2768d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		*p = SDP_SEQ8;
2769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
2770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += sizeof(uint8_t);
27718f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		/* reserve space for sequence size */
2772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
2773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += sizeof(uint8_t);
2774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(dst->data + dst->data_size, data, len);
2777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dst->data_size += len;
2778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2779d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	dtd = *(uint8_t *) dst->data;
2780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) {
2781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		short offset = sizeof(uint8_t) + sizeof(uint8_t);
27828f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		memmove(dst->data + offset + 1, dst->data + offset,
27838f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg						dst->data_size - offset);
2784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = dst->data;
2785d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		*p = SDP_SEQ16;
2786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
2787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += 1;
2788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = dst->data;
2790aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	dtd = *(uint8_t *) p;
2791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
2792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
2793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
2794aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t);
2795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2796542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
2797aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *) p);
2798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
2800aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *) p);
2801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d)
2806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t append;
2808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2809997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	memset(&append, 0, sizeof(sdp_buf_t));
28102db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_gen_buffer(&append, d);
28112db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	append.data = malloc(append.buf_size);
28122db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	if (!append.data)
28132db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		return;
2814997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann
2815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_set_attrid(&append, d->attrId);
2816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_gen_pdu(&append, d);
2817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_append_to_buf(pdu, append.data, append.data_size);
28182db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	free(append.data);
2819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Registers an sdp record.
2823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * It is incorrect to call this method on a record that
2825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * has been already registered with the server.
2826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
28278b11908eac4e0b4e14534ec2d44ae62806fdfd2fStephen Crane * Returns zero on success, otherwise -1 (and sets errno).
2828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
282982817924a25fb0eaaeb9824372106870c45c9db9Marcel 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)
2830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2831cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *req, *rsp, *p;
2832cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize, rspsize;
2833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
283482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int status;
2835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
2839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
2840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2842cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	req = malloc(SDP_REQ_BUFFER_SIZE);
2843cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rsp = malloc(SDP_RSP_BUFFER_SIZE);
2844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (req == NULL || rsp == NULL) {
2845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
284982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *)req;
2851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_REGISTER_REQ;
2852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t) + 1;
2854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = req + sizeof(sdp_pdu_hdr_t);
285582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2856fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann	if (bacmp(device, BDADDR_ANY)) {
2857fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		*p++ = flags | SDP_DEVICE_RECORD;
2858fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		bacpy((bdaddr_t *) p, device);
2859fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		p += sizeof(bdaddr_t);
28606db62cfa3a8de69270cc5e5689b633f43c02e041Marcel Holtmann		reqsize += sizeof(bdaddr_t);
2861fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann	} else
2862fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		*p++ = flags;
286382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
286482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	memcpy(p, data, size);
286582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	reqsize += size;
2866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize);
2869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status < 0)
2870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
287182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2872ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	if (rspsize < sizeof(sdp_pdu_hdr_t)) {
2873ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		SDPERR("Unexpected end of packet");
2874ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		errno = EPROTO;
2875ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		status = -1;
2876ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		goto end;
2877ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	}
2878ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann
2879aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	rsphdr = (sdp_pdu_hdr_t *) rsp;
2880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = rsp + sizeof(sdp_pdu_hdr_t);
288182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2882a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2883a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		/* Invalid service record */
2884a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EINVAL;
2885a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
2886a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	} else if (rsphdr->pdu_id != SDP_SVC_REGISTER_RSP) {
2887a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EPROTO;
2888a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
2889a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	} else {
2890ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint32_t)) {
2891ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann			SDPERR("Unexpected end of packet");
2892ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann			errno = EPROTO;
2893ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann			status = -1;
2894ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann			goto end;
2895ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		}
289682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		if (handle)
289782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann			*handle  = ntohl(bt_get_unaligned((uint32_t *) p));
2898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
289982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
2901a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(req);
2902a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rsp);
290382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
290782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags)
290882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{
290982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	sdp_buf_t pdu;
291082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	uint32_t handle;
291182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int err;
291282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
291382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	SDPDBG("");
291482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
291582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (rec->handle && rec->handle != 0xffffffff) {
291682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		uint32_t handle = rec->handle;
291782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
291882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
291982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	}
292082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
292182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
292282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		errno = ENOMEM;
292382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		return -1;
292482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	}
292582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
292682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	err = sdp_device_record_register_binary(session, device,
292782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann				pdu.data, pdu.data_size, flags, &handle);
292882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
292982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	free(pdu.data);
293082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
293182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (err == 0) {
293282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
293382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		rec->handle = handle;
293482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
293582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	}
293682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
293782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	return err;
293882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann}
293982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2940a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags)
2941a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
2942a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_register(session, BDADDR_ANY, rec, flags);
2943a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
2944a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
2945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * unregister a service record
2947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
294882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle)
2949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2950cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf, *p;
2951cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, rspsize = 0;
2952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
295382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int status;
2954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (handle == SDP_SERVER_RECORD_HANDLE) {
2958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
2959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
296182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
2963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
2964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
296682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2967cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2968cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2974aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_REMOVE_REQ;
2976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = reqbuf + sizeof(sdp_pdu_hdr_t);
2979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2980aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) p);
2981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
2982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2985a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (status < 0)
2986a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		goto end;
2987a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi
2988ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
2989ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		SDPERR("Unexpected end of packet");
2990ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		errno = EPROTO;
2991ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		status = -1;
2992ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		goto end;
2993ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	}
2994ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann
2995a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2996a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	p = rspbuf + sizeof(sdp_pdu_hdr_t);
2997a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	status = bt_get_unaligned((uint16_t *) p);
299882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2999a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3000a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		/* For this case the status always is invalid record handle */
3001a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EINVAL;
3002a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
3003a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	} else if (rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) {
3004a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EPROTO;
3005a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
3006a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	}
3007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
3008a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
3009a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
301082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
3011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
3012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
301482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec)
301582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{
301682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int err;
301782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
301882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	err = sdp_device_record_unregister_binary(session, device, rec->handle);
301982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (err == 0)
302082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_record_free(rec);
302182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
302282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	return err;
302382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann}
302482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
3025a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec)
3026a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
3027a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_unregister(session, BDADDR_ANY, rec);
3028a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
3029a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
3030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * modify an existing service record
3032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
303382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size)
303482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{
303582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	return -1;
303682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann}
303782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
3038a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec)
3039542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3040cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf, *p;
3041cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize, rspsize;
3042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t handle;
3044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t pdu;
304582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int status;
3046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
304882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
3049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	handle = rec->handle;
3050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (handle == SDP_SERVER_RECORD_HANDLE) {
3052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
3053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
3054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
3056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
3057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
3058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3059cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3060cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
3062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
3064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3066aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_UPDATE_REQ;
3068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
3069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3070cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	p = reqbuf + sizeof(sdp_pdu_hdr_t);
3071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
3072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3073aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) p);
3074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
3075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint32_t);
3076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3077c5621bfbf9071ed359d904bdd91308f6599dc5e5Claudio Takahasi	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
3078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
3080542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3082542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(p, pdu.data, pdu.data_size);
3083542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += pdu.data_size;
3084c5621bfbf9071ed359d904bdd91308f6599dc5e5Claudio Takahasi	free(pdu.data);
3085542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3088a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (status < 0)
3089a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		goto end;
3090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3091ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
3092ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		SDPERR("Unexpected end of packet");
3093ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		errno = EPROTO;
3094ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		status = -1;
3095ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		goto end;
3096ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	}
3097ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann
3098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Send req status : %d\n", status);
3099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3100a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3101a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	p = rspbuf + sizeof(sdp_pdu_hdr_t);
3102a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	status = bt_get_unaligned((uint16_t *) p);
3103a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi
3104a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3105a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		/* The status can be invalid sintax or invalid record handle */
3106a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EINVAL;
3107a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
3108a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	} else if (rsphdr->pdu_id != SDP_SVC_UPDATE_RSP) {
3109a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EPROTO;
3110a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
3111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
3113a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
3114a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
3115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
3116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3118a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_update(sdp_session_t *session, const sdp_record_t *rec)
3119a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
3120a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_update(session, BDADDR_ANY, rec);
3121a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
3122a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
3123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_record_t *sdp_record_alloc()
3124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
312521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_record_t *rec = malloc(sizeof(sdp_record_t));
3126114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
3127114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!rec)
3128114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
3129114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
3130d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	memset(rec, 0, sizeof(sdp_record_t));
3131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->handle = 0xffffffff;
3132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
3133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Free the contents of a service record
3137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_free(sdp_record_t *rec)
3139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3140d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	sdp_list_free(rec->attrlist, (sdp_free_func_t) sdp_data_free);
3141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(rec->pattern, free);
3142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(rec);
3143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid)
3146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid);
3148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
3150d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	SDPDBG("Trying to add : 0x%lx\n", (unsigned long) uuid128);
3151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL)
3153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp);
3154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
315521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann		bt_free(uuid128);
3156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
3158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq)
3161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; seq; seq = seq->next) {
3163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid_t *uuid = (uuid_t *)seq->data;
3164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_pattern_add_uuid(rec, uuid);
3165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract a sequence of service record handles from a PDU buffer
3170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * and add the entries to a sdp_list_t. Note that the service record
3171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * handles are not in "data element sequence" form, but just like
3172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * an array of service handles
3173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3174cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmannstatic void extract_record_handle_seq(uint8_t *pdu, int bufsize, sdp_list_t **seq, int count, unsigned int *scanned)
3175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3176542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *pSeq = *seq;
3177cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata = pdu;
3178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
3179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (n = 0; n < count; n++) {
318128cfb82c67c413cddff779a875cc7a40931b46a5Marcel Holtmann		uint32_t *pSvcRec;
3182cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint32_t)) {
3183121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3184121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			break;
3185121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
318628cfb82c67c413cddff779a875cc7a40931b46a5Marcel Holtmann		pSvcRec = malloc(sizeof(uint32_t));
318728cfb82c67c413cddff779a875cc7a40931b46a5Marcel Holtmann		if (!pSvcRec)
318828cfb82c67c413cddff779a875cc7a40931b46a5Marcel Holtmann			break;
3189aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata));
3190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pSeq = sdp_list_append(pSeq, pSvcRec);
3191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint32_t);
3192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint32_t);
3193121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		bufsize -= sizeof(uint32_t);
3194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*seq = pSeq;
3196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Generate the attribute sequence pdu form
3199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * from sdp_list_t elements. Return length of attr seq
3200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3201cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd)
3202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *dataseq;
3204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **types, **values;
3205542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t buf;
3206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i, seqlen = sdp_list_len(seq);
3207542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
32083d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* Fill up the value and the dtd arrays */
3209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
3210a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
3211542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Seq length : %d\n", seqlen);
3212542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	types = malloc(seqlen * sizeof(void *));
3214135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	if (!types)
3215135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		return -ENOMEM;
3216135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz
3217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	values = malloc(seqlen * sizeof(void *));
3218f0081032066a6b246df58659aae38048a5952effLuiz Augusto von Dentz	if (!values) {
3219f0081032066a6b246df58659aae38048a5952effLuiz Augusto von Dentz		free(types);
3220135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		return -ENOMEM;
3221f0081032066a6b246df58659aae38048a5952effLuiz Augusto von Dentz	}
3222135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz
3223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0; i < seqlen; i++) {
3224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		void *data = seq->data;
3225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		types[i] = &dtd;
3226542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (SDP_IS_UUID(dtd))
3227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			data = &((uuid_t *)data)->value;
3228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = data;
3229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = seq->next;
3230542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dataseq = sdp_seq_alloc(types, values, seqlen);
3233135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	if (!dataseq) {
3234135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		free(types);
3235135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		free(values);
3236135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		return -ENOMEM;
3237135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	}
3238135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz
32392db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	memset(&buf, 0, sizeof(sdp_buf_t));
32402db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_gen_buffer(&buf, dataseq);
32412db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	buf.data = malloc(buf.buf_size);
32422db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
3243135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	if (!buf.data) {
3244135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		sdp_data_free(dataseq);
3245135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		free(types);
3246135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		free(values);
32472db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		return -ENOMEM;
3248135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	}
32492db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
3250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data Seq : 0x%p\n", seq);
3251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = sdp_gen_pdu(&buf, dataseq);
3252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Copying : %d\n", buf.data_size);
3253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(dst, buf.data, buf.data_size);
3254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_free(dataseq);
3256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(types);
3258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
3259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(buf.data);
3260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seqlen;
3261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3263cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq)
3264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3265d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	uuid_t *uuid = seq->data;
3266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return gen_dataseq_pdu(dst, seq, uuid->type);
3267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3269cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType)
3270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return gen_dataseq_pdu(dst, seq, dataType);
3272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3274113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmanntypedef struct {
3275113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann	uint8_t length;
3276113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann	unsigned char data[16];
3277113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann} __attribute__ ((packed)) sdp_cstate_t;
3278113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann
32790a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmannstatic int copy_cstate(uint8_t *pdata, int pdata_len, const sdp_cstate_t *cstate)
3280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (cstate) {
32820a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		uint8_t len = cstate->length;
32830a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		if (len >= pdata_len) {
32840a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann			SDPERR("Continuation state size exceeds internal buffer");
32850a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann			len = pdata_len - 1;
32860a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		}
32870a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		*pdata++ = len;
32880a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		memcpy(pdata, cstate->data, len);
32890a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		return len + 1;
3290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*pdata = 0;
3292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 1;
3293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3296400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio * This is a service search request.
3297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
3299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
330041064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim *   sdp_list_t *search
3301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing elements of the search
3302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
3303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     of the service to be searched
3304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   uint16_t max_rec_num
3306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      A 16 bit integer which tells the service, the maximum
3307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      entries that the client can handle in the response. The
3308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      server is obliged not to return > max_rec_num entries
3309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
3311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   int return value
3313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
3314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       The request completed successfully. This does not
3315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       mean the requested services were found
3316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     -1:
3317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any failure and sets errno
3318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t **rsp_list
3320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     This variable is set on a successful return if there are
3321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     non-zero service handles. It is a singly linked list of
332228b4f0aea5b15ed7c0acd17ab79705a38ffe7c2fStephen Crane *     service record handles (uint16_t)
3323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search,
3325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			uint16_t max_rec_num, sdp_list_t **rsp)
3326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
3328cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
3329cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0, rsplen;
3330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0;
3331cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	int total_rec_count, rec_count;
3332cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	unsigned scanned, pdata_len;
3333cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
3334cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
3335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
3337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
3341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
3343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3345aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
3347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
3349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
33503d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add service class IDs for search */
3351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_searchseq_pdu(pdata, search);
3352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data seq added : %d\n", seqlen);
3354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
33553d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* set the length and increment the pointer */
3356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
3357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
3358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
33593d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* specify the maximum svc rec count that client expects */
3360aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
3361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
3362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
3363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
3365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata   = pdata;
3366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rsp = NULL;
3367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
33693d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* Add continuation state or NULL (first time) */
33700a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata,
33710a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
3372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
33733d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* Set the request header's param length */
3374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid  = htons(sdp_gen_tid(session));
3377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
3378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Send the request, wait for response and if
3379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * no error, set the appropriate values and return
3380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0)
3383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3385121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
3386121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3387121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
3388121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3389121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3390121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3391aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rsplen = ntohs(rsphdr->plen);
3393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
3396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
3397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned = 0;
3400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3401121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
3402121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3403121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < sizeof(uint16_t) + sizeof(uint16_t)) {
3404121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3405121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
3406121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3407121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
34093d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* net service record match count */
3410aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
3412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
3413121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len -= sizeof(uint16_t);
3414aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
3416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
3417121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len -= sizeof(uint16_t);
3418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Total svc count: %d\n", total_rec_count);
3420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Current svc count: %d\n", rec_count);
3421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("ResponseLength: %d\n", rsplen);
3422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!rec_count) {
3424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
3425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3427121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		extract_record_handle_seq(pdata, pdata_len, rsp, rec_count, &scanned);
3428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("BytesScanned : %d\n", scanned);
3429542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsplen > scanned) {
3431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			uint8_t cstate_len;
3432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3433121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			if (rspsize < sizeof(sdp_pdu_hdr_t) + scanned + sizeof(uint8_t)) {
3434121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann				SDPERR("Unexpected end of packet: continuation state data missing");
3435121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann				status = -1;
3436121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann				goto end;
3437121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			}
3438121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned;
3440aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate_len = *(uint8_t *) pdata;
3441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (cstate_len > 0) {
3442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				cstate = (sdp_cstate_t *)pdata;
3443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Cont state length: %d\n", cstate_len);
3444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			} else
3445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				cstate = NULL;
3446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
3448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3449a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannend:
3450a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
3451a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
3452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
3454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3457400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio * This is a service attribute request.
3458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
3460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   uint32_t handle
3462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     The handle of the service for which the attribute(s) are
3463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     requested
3464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_attrreq_type_t reqtype
3466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
3467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     in one of 2 ways described below :
3468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        They are the actual attribute identifiers in ascending order
3470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        The high-order 16bits is the start of range
3473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        the low-order 16bits are the end of range
3474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        0x0000 to 0xFFFF gets all attributes
3475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *attrid
3477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing attribute identifiers desired.
3478400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
3482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   return sdp_record_t *
3483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
3484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any error and sets errno
3485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     !0:
3486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *	 The service record
3487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3488400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesiosdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle,
3489542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_attrreq_type_t reqtype, const sdp_list_t *attrids)
3490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3491cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
3492cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0, rsp_count;
3493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int attr_list_len = 0;
3494cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	int seqlen = 0;
3495cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	unsigned int pdata_len;
3496cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
3497cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
3498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
3500542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t cstate_len = 0;
3501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t rsp_concat_buf;
3502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_record_t *rec = 0;
3503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
3505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
3506f58df2db7a606fcd13a36824bdb4fc3440d9a71eSantiago Carot-Nemesio		return NULL;
3507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35098232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg	memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));
35108232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg
3511cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3512cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
3514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3517aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
3519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
3522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35233d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add the service record handle */
3524aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
3525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
3526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint32_t);
3527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35283d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* specify the response limit */
3529aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
3530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
3531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
3532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35333d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* get attr seq PDU form */
3534400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio	seqlen = gen_attridseq_pdu(pdata, attrids,
3535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seqlen == -1) {
3537542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
3538542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
3541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
3542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Attr list length : %d\n", seqlen);
3543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35443d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* save before Continuation State */
3545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata = pdata;
3546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
3547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
35495e1f7cb4d8abc2c352d7ee055795cca837523b53Luiz Augusto von Dentz		int status;
35505e1f7cb4d8abc2c352d7ee055795cca837523b53Luiz Augusto von Dentz
35513d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* add NULL continuation state */
35520a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata,
35530a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
3554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35553d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* set the request header's param length */
3556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid  = htons(sdp_gen_tid(session));
3557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0)
3561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3562121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3563121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
3564121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3565121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3566121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3567121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3568aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id);
3571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3574121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
3575121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3576121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < sizeof(uint16_t)) {
3577121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3578121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3579121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3580121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3581aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3582542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		attr_list_len += rsp_count;
3583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
3584121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len -= sizeof(uint16_t);
3585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35863d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/*
35873d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		 * if continuation state set need to re-issue request before
35883d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		 * parsing
35893d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		 */
3590121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < rsp_count + sizeof(uint8_t)) {
3591121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet: continuation state data missing");
3592121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3593121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3594aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		cstate_len = *(uint8_t *) (pdata + rsp_count);
3595542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Response id : %d\n", rsphdr->pdu_id);
3597542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attrlist byte count : %d\n", rsp_count);
3598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("sdp_cstate_t length : %d\n", cstate_len);
3599542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3600542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
3601400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio		 * a split response: concatenate intermediate responses
3602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * and the last one (which has cstate_len == 0)
3603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
3605cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			uint8_t *targetPtr = NULL;
3606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3607aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
3608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
36093d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc			/* build concatenated response buffer */
3610cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
3611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
3612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
3613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(targetPtr, pdata, rsp_count);
3614542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.data_size += rsp_count;
3615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
3617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (attr_list_len > 0) {
3619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int scanned = 0;
3620121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rsp_concat_buf.data_size != 0) {
3621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rsp_concat_buf.data;
3622121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			pdata_len = rsp_concat_buf.data_size;
3623121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3624d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann		rec = sdp_extract_pdu(pdata, pdata_len, &scanned);
3625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3626400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio
3627a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannend:
3628a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
3629a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rsp_concat_buf.data);
3630a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
3631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
3632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
36358be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * SDP transaction structure for asynchronous search
36368be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */
36378be090b298a02108146d3bf48271f8408ac31917Claudio Takahasistruct sdp_transaction {
3638c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	sdp_callback_t *cb;	/* called when the transaction finishes */
3639c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	void *udata;		/* client user data */
3640c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	uint8_t *reqbuf;	/* pointer to request PDU */
36418be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	sdp_buf_t rsp_concat_buf;
3642c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	uint32_t reqsize;	/* without cstate */
36435ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	int err;		/* ZERO if success or the errno if failed */
36448be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi};
36458be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36468be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/*
36478be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * Creates a new sdp session for asynchronous search
36488be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * INPUT:
36498be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  int sk
36501be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim *     non-blocking L2CAP socket
36511be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim *
36528be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * RETURN:
36538be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  sdp_session_t *
36548be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  NULL - On memory allocation failure
36558be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */
36568be090b298a02108146d3bf48271f8408ac31917Claudio Takahasisdp_session_t *sdp_create(int sk, uint32_t flags)
36578be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi{
3658a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	sdp_session_t *session;
36598be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	struct sdp_transaction *t;
3660a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
3661a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	session = malloc(sizeof(sdp_session_t));
36628be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!session) {
36638be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		errno = ENOMEM;
36648be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return NULL;
36658be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
36668be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	memset(session, 0, sizeof(*session));
36678be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36688be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->flags = flags;
36698be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->sock = sk;
36708be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36718be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	t = malloc(sizeof(struct sdp_transaction));
36728be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!t) {
36738be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		errno = ENOMEM;
36748be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		free(session);
36758be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return NULL;
36768be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
36778be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	memset(t, 0, sizeof(*t));
36788be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36798be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->priv = t;
36808be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36818be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	return session;
36828be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi}
36838be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36848be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/*
3685adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Sets the callback function/user data used to notify the application
3686adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * that the asynchronous transaction finished. This function must be
3687adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called before request an asynchronous search.
3688dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *
3689dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * INPUT:
3690dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  sdp_session_t *session
3691dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *	Current sdp session to be handled
3692dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  sdp_callback_t *cb
3693dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *      callback to be called when the transaction finishes
3694dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  void *udata
3695dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *      user data passed to callback
3696dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * RETURN:
3697adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	 0 - Success
3698dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * 	-1 - Failure
3699dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann */
3700dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmannint sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata)
3701dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann{
3702dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	struct sdp_transaction *t;
3703dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3704dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	if (!session || !session->priv)
3705dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann		return -1;
3706dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3707dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t = session->priv;
3708dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t->cb = func;
3709dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t->udata = udata;
3710dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3711dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	return 0;
3712dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann}
3713dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3714adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi/*
3715adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service search request.
3716400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio * The incomming and outgoing data are stored in the transaction structure
3717adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * buffers. When there is incomming data the sdp_process function must be
3718adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called to get the data and handle the continuation state.
3719adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3720adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * INPUT :
3721adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *  sdp_session_t *session
3722adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Current sdp session to be handled
3723adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
372441064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim *   sdp_list_t *search
3725adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Singly linked list containing elements of the search
3726adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
3727adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     of the service to be searched
3728adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3729adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   uint16_t max_rec_num
3730adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *      A 16 bit integer which tells the service, the maximum
3731adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *      entries that the client can handle in the response. The
3732adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *      server is obliged not to return > max_rec_num entries
3733adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3734adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * OUTPUT :
3735adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3736adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   int return value
3737adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	0  - if the request has been sent properly
3738adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	-1 - On any failure and sets errno
3739adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi */
3740adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi
374141064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquimint sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num)
3742453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{
3743e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	struct sdp_transaction *t;
3744e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3745e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	uint8_t *pdata;
3746c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	int cstate_len, seqlen = 0;
3747e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
374812f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi	if (!session || !session->priv)
3749e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi		return -1;
3750e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3751e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t = session->priv;
375218a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3753a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	/* clean possible allocated buffer */
3754a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->rsp_concat_buf.data);
375518a82a6fce76be0883a431380495510010515fffClaudio Takahasi	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
375618a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3757e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	if (!t->reqbuf) {
375818a82a6fce76be0883a431380495510010515fffClaudio Takahasi		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
375918a82a6fce76be0883a431380495510010515fffClaudio Takahasi		if (!t->reqbuf) {
376018a82a6fce76be0883a431380495510010515fffClaudio Takahasi			t->err = ENOMEM;
376118a82a6fce76be0883a431380495510010515fffClaudio Takahasi			goto end;
376218a82a6fce76be0883a431380495510010515fffClaudio Takahasi		}
3763e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	}
3764e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3765e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3766e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3767e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3768e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
3769e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
37703d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* generate PDU */
3771e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3772e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3773e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
37743d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add service class IDs for search */
377541064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim	seqlen = gen_searchseq_pdu(pdata, search);
3776e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3777e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	SDPDBG("Data seq added : %d\n", seqlen);
3778e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
37793d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* now set the length and increment the pointer */
3780e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t->reqsize += seqlen;
3781e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	pdata += seqlen;
3782e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3783e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
3784e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t->reqsize += sizeof(uint16_t);
3785e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	pdata += sizeof(uint16_t);
3786e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
37873d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* set the request header's param length */
37880a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
3789c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3790e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3791c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3792e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
379312f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = errno;
3794e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi		goto end;
3795e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	}
3796e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3797453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	return 0;
3798e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasiend:
3799e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3800a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->reqbuf);
3801a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	t->reqbuf = NULL;
3802e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3803e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	return -1;
3804453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann}
3805453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3806adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi/*
3807adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service attribute request.
3808400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio * The incomming and outgoing data are stored in the transaction structure
3809adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * buffers. When there is incomming data the sdp_process function must be
3810adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called to get the data and handle the continuation state.
3811adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3812adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * INPUT :
3813adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *  sdp_session_t *session
3814adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *	Current sdp session to be handled
3815adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3816adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   uint32_t handle
3817adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     The handle of the service for which the attribute(s) are
3818adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     requested
3819adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3820adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   sdp_attrreq_type_t reqtype
3821adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Attribute identifiers are 16 bit unsigned integers specified
3822adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     in one of 2 ways described below :
3823adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3824adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        They are the actual attribute identifiers in ascending order
3825adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3826adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3827adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        The high-order 16bits is the start of range
3828adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        the low-order 16bits are the end of range
3829adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        0x0000 to 0xFFFF gets all attributes
3830adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3831adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   sdp_list_t *attrid_list
3832adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Singly linked list containing attribute identifiers desired.
3833400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3834adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3835adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3836adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * OUTPUT :
3837adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   int return value
3838adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	 0 - if the request has been sent properly
3839adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	-1 - On any failure and sets errno
3840adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi */
3841adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi
3842453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmannint sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
3843453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{
3844ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	struct sdp_transaction *t;
3845ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3846ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	uint8_t *pdata;
3847c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	int cstate_len, seqlen = 0;
3848ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
384912f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi	if (!session || !session->priv)
3850ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		return -1;
3851ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3852ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t = session->priv;
385318a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3854a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	/* clean possible allocated buffer */
3855a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->rsp_concat_buf.data);
385618a82a6fce76be0883a431380495510010515fffClaudio Takahasi	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
385718a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3858ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	if (!t->reqbuf) {
385918a82a6fce76be0883a431380495510010515fffClaudio Takahasi		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
386018a82a6fce76be0883a431380495510010515fffClaudio Takahasi		if (!t->reqbuf) {
386118a82a6fce76be0883a431380495510010515fffClaudio Takahasi			t->err = ENOMEM;
386218a82a6fce76be0883a431380495510010515fffClaudio Takahasi			goto end;
386318a82a6fce76be0883a431380495510010515fffClaudio Takahasi		}
3864ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3865ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3866ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3867ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3868ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3869ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
3870ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38713d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* generate PDU */
3872ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3873ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3874ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38753d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add the service record handle */
3876ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
3877ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize += sizeof(uint32_t);
3878ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata += sizeof(uint32_t);
3879ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38803d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* specify the response limit */
3881ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
3882ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize += sizeof(uint16_t);
3883ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata += sizeof(uint16_t);
3884ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38853d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* get attr seq PDU form */
3886ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	seqlen = gen_attridseq_pdu(pdata, attrid_list,
3887ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi			reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3888ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	if (seqlen == -1) {
388912f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = EINVAL;
3890ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		goto end;
3891ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3892ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38933d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* now set the length and increment the pointer */
3894ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize += seqlen;
3895ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata += seqlen;
3896ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	SDPDBG("Attr list length : %d\n", seqlen);
3897ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38983d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* set the request header's param length */
38990a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
3900c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3901ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3902c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3903ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
390412f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = errno;
3905ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		goto end;
3906ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3907ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3908453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	return 0;
3909ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasiend:
3910ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3911a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->reqbuf);
3912a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	t->reqbuf = NULL;
3913ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3914ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	return -1;
3915453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann}
3916453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3917dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann/*
3918adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service search attributes.
3919adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * It is a service search request combined with attribute request. The incomming
3920adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * and outgoing data are stored in the transaction structure buffers. When there
3921adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * is incomming data the sdp_process function must be called to get the data
3922adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * and handle the continuation state.
3923f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *
3924f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT:
3925f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *  sdp_session_t *session
3926f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *	Current sdp session to be handled
3927453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3928453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *   sdp_list_t *search
3929453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Singly linked list containing elements of the search
3930453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
3931453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     of the service to be searched
3932453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3933453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *   AttributeSpecification attrSpec
3934453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
3935453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     in one of 2 ways described below :
3936453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3937453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        They are the actual attribute identifiers in ascending order
3938453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3939453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3940453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        The high-order 16bits is the start of range
3941453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        the low-order 16bits are the end of range
3942453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        0x0000 to 0xFFFF gets all attributes
3943453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3944adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   sdp_list_t *attrid_list
3945453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Singly linked list containing attribute identifiers desired.
3946400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3947453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3948453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3949453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3950f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN:
3951adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	 0 - if the request has been sent properly
3952f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	-1 - On any failure
3953f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */
395441064d605ba2f88f967c8388c9b20b92a7868a87Ulisses 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)
3955f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{
3956f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	struct sdp_transaction *t;
3957f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3958f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	uint8_t *pdata;
3959c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	int cstate_len, seqlen = 0;
3960f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
396112f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi	if (!session || !session->priv)
3962f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		return -1;
3963f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3964f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t = session->priv;
396518a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3966a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	/* clean possible allocated buffer */
3967a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->rsp_concat_buf.data);
396818a82a6fce76be0883a431380495510010515fffClaudio Takahasi	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
396918a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3970f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (!t->reqbuf) {
397118a82a6fce76be0883a431380495510010515fffClaudio Takahasi		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
397218a82a6fce76be0883a431380495510010515fffClaudio Takahasi		if (!t->reqbuf) {
397318a82a6fce76be0883a431380495510010515fffClaudio Takahasi			t->err = ENOMEM;
397418a82a6fce76be0883a431380495510010515fffClaudio Takahasi			goto end;
397518a82a6fce76be0883a431380495510010515fffClaudio Takahasi		}
3976f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3977f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3978f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3979f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3980f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3981f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
3982f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
39833d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* generate PDU */
3984f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3985f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3986f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
39873d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add service class IDs for search */
398841064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim	seqlen = gen_searchseq_pdu(pdata, search);
3989f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3990f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Data seq added : %d\n", seqlen);
3991f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
39923d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* now set the length and increment the pointer */
3993f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += seqlen;
3994f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += seqlen;
3995f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3996f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
3997f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += sizeof(uint16_t);
3998f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += sizeof(uint16_t);
3999f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4000f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
4001f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
40023d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* get attr seq PDU form */
4003453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrid_list,
4004453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann			reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
4005f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (seqlen == -1) {
400612f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = EINVAL;
4007f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
4008f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
4009f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4010f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += seqlen;
4011f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Attr list length : %d\n", seqlen);
4012f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += seqlen;
4013f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
40143d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* set the request header's param length */
40150a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
4016c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
4017f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4018c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
4019f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
402012f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = errno;
4021f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
4022f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
4023f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4024f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	return 0;
4025f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend:
4026f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4027a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->reqbuf);
4028a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	t->reqbuf = NULL;
4029f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4030f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	return -1;
4031f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi}
4032f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4033f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/*
40345ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * Function used to get the error reason after sdp_callback_t function has been called
403512f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1.
403612f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly
403712f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * is not safe because multiple transactions can be triggered.
40385ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * This function must be used with asynchronous sdp functions only.
40395ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *
40405ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * INPUT:
40415ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *  sdp_session_t *session
40425ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *	Current sdp session to be handled
40435ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * RETURN:
40445ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 	 0 = No error in the current transaction
40455ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 	-1 - if the session is invalid
40465ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 	positive value - the errno value
40475ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *
40485ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi */
40495ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasiint sdp_get_error(sdp_session_t *session)
40505ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi{
40515ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	struct sdp_transaction *t;
40525ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
40535ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	if (!session || !session->priv) {
40545ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Invalid session");
40555ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		return -1;
40565ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	}
40575ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
40585ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	t = session->priv;
40595ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
40605ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	return t->err;
40615ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi}
40625ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
40635ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi/*
4064f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * Receive the incomming SDP PDU. This function must be called when there is data
4065f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * available to be read. On continuation state, the original request (with a new
4066f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * transaction ID) and the continuation state data will be appended in the initial PDU.
4067f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * If an error happens or the transaction finishes the callback function will be called.
4068f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *
4069f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT:
4070f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *  sdp_session_t *session
4071f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *	Current sdp session to be handled
4072f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN:
4073f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	0  - if the transaction is on continuation state
4074f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	-1 - On any failure or the transaction finished
4075f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */
4076f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiint sdp_process(sdp_session_t *session)
4077f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{
40785ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	struct sdp_transaction *t;
40795ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	sdp_pdu_hdr_t *reqhdr, *rsphdr;
40805ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	sdp_cstate_t *pcstate;
40815ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	uint8_t *pdata, *rspbuf, *targetPtr;
40825ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	int rsp_count, err = -1;
4083c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	size_t size = 0;
40849203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	int n, plen;
40855ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	uint16_t status = 0xffff;
40865ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	uint8_t pdu_id = 0x00;
4087f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4088f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (!session || !session->priv) {
4089c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		SDPERR("Invalid session");
4090c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		return -1;
4091f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
4092f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4093f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
40945ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	if (!rspbuf) {
40955ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Response buffer alloc failure:%s (%d)",
40965ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi				strerror(errno), errno);
4097c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		return -1;
40985ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	}
4099c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi
4100c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE);
4101f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4102f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t = session->priv;
4103f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *)t->reqbuf;
4104f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	rsphdr = (sdp_pdu_hdr_t *)rspbuf;
4105f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
41065ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
4107f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
41089203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
41099203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	if (n < 0) {
41105ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Read response:%s (%d)", strerror(errno), errno);
41115ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		t->err = errno;
4112f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
41135ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	}
4114f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
41159203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	if (n == 0 || reqhdr->tid != rsphdr->tid ||
4116cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		(n != (ntohs(rsphdr->plen) + (int) sizeof(sdp_pdu_hdr_t)))) {
41175ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		t->err = EPROTO;
41189203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPERR("Protocol error.");
4119343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi		goto end;
4120343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi	}
4121343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi
41225ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	pdu_id = rsphdr->pdu_id;
412358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	switch (rsphdr->pdu_id) {
412458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	uint8_t *ssr_pdata;
412558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	uint16_t tsrc, csrc;
412658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	case SDP_SVC_SEARCH_RSP:
412758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		/*
41289203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * TSRC: Total Service Record Count (2 bytes)
41299203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * CSRC: Current Service Record Count (2 bytes)
413058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		 */
413158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		ssr_pdata = pdata;
413258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));
41339203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		ssr_pdata += sizeof(uint16_t);
413458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));
413558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi
41369203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		/* csrc should never be larger than tsrc */
41379203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		if (csrc > tsrc) {
41389203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi			t->err = EPROTO;
41399203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi			SDPERR("Protocol error: wrong current service record count value.");
41409203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi			goto end;
41419203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		}
41429203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
41439203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPDBG("Total svc count: %d\n", tsrc);
41449203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPDBG("Current svc count: %d\n", csrc);
41459203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
41469203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		/* parameter length without continuation state */
41479203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
41489203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
4149c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann		if (t->rsp_concat_buf.data_size == 0) {
415058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi			/* first fragment */
415158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi			rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
415258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		} else {
4153e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			/* point to the first csrc */
4154e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			uint16_t *pcsrc = (uint16_t *) (t->rsp_concat_buf.data + 2);
4155e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
4156e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			/* FIXME: update the interface later. csrc doesn't need be passed to clients */
4157e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
4158e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			pdata += sizeof(uint16_t); /* point to csrc */
4159e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
4160e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			/* the first csrc contains the sum of partial csrc responses */
4161400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio			*pcsrc += bt_get_unaligned((uint16_t *) pdata);
4162e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
4163e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			pdata += sizeof(uint16_t); /* point to the first handle */
416458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi			rsp_count = csrc * 4;
416558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		}
41665ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		status = 0x0000;
416758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		break;
416858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	case SDP_SVC_ATTR_RSP:
416958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	case SDP_SVC_SEARCH_ATTR_RSP:
417058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
417158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		SDPDBG("Attrlist byte count : %d\n", rsp_count);
4172400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio
4173400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio		/*
41749203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * Number of bytes in the AttributeLists parameter(without
41759203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * continuation state) + AttributeListsByteCount field size.
41769203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 */
41779203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		plen = sizeof(uint16_t) + rsp_count;
4178f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
41793d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		pdata += sizeof(uint16_t); /* points to attribute list */
41805ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		status = 0x0000;
418158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		break;
41825ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	case SDP_ERROR_RSP:
41835ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		status = ntohs(bt_get_unaligned((uint16_t *) pdata));
41849203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		size = ntohs(rsphdr->plen);
41859203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
41869203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		/* error code + error info */
41879203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		plen = size;
41885ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		goto end;
418958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	default:
41905ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		t->err = EPROTO;
41915ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id);
419258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		goto end;
419358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	}
4194f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
419558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	pcstate = (sdp_cstate_t *) (pdata + rsp_count);
419658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi
419758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	SDPDBG("Cstate length : %d\n", pcstate->length);
41989203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
4199400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio	/*
42009203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	 * Check out of bound. Continuation state must have at least
42019203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	 * 1 byte: ZERO to indicate that it is not a partial response.
42029203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	 */
4203cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if ((n - (int) sizeof(sdp_pdu_hdr_t))  != (plen + pcstate->length + 1)) {
42049203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		t->err = EPROTO;
42059203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPERR("Protocol error: wrong PDU size.");
42069203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		status = 0xffff;
42079203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		goto end;
42089203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	}
42099203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
4210f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	/*
4211f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	 * This is a split response, need to concatenate intermediate
42125ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	 * responses and the last one which will have cstate length == 0
4213f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	 */
421458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count);
421558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size;
421658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count;
421758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	memcpy(targetPtr, pdata, rsp_count);
421858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	t->rsp_concat_buf.data_size += rsp_count;
421958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi
422058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	if (pcstate->length > 0) {
422158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		int reqsize, cstate_len;
4222f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4223f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		reqhdr->tid = htons(sdp_gen_tid(session));
4224f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
42253d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* add continuation state */
42260a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		cstate_len = copy_cstate(t->reqbuf + t->reqsize,
42270a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann				SDP_REQ_BUFFER_SIZE - t->reqsize, pcstate);
4228f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
422958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		reqsize = t->reqsize + cstate_len;
4230f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
42313d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* set the request header's param length */
4232f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
4233400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio
4234f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (sdp_send_req(session, t->reqbuf, reqsize) < 0) {
42355ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			SDPERR("Error sendind data:%s(%d)", strerror(errno), errno);
42365ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			status = 0xffff;
42375ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			t->err = errno;
4238f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi			goto end;
4239f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		}
4240c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		err = 0;
4241f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
4242f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4243f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend:
4244c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	if (err) {
4245c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann		if (t->rsp_concat_buf.data_size != 0) {
4246f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi			pdata = t->rsp_concat_buf.data;
4247c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann			size = t->rsp_concat_buf.data_size;
4248c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann		}
4249f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (t->cb)
42505ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			t->cb(pdu_id, status, pdata, size, t->udata);
4251f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
4252f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4253a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
4254f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4255c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	return err;
4256f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi}
4257f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4258f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/*
4259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service search request combined with the service
4260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attribute request. First a service class match is done and
4261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * for matching service, requested attributes are extracted
4262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
4264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *search
4266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing elements of the search
4267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
4268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     of the service to be searched
4269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   AttributeSpecification attrSpec
4271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
4272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     in one of 2 ways described below :
4273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
4274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        They are the actual attribute identifiers in ascending order
4275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
4277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        The high-order 16bits is the start of range
4278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        the low-order 16bits are the end of range
4279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        0x0000 to 0xFFFF gets all attributes
4280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *attrids
4282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing attribute identifiers desired.
4283400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
4284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
4285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
4287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   int return value
4288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
4289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       The request completed successfully. This does not
4290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       mean the requested services were found
4291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     -1:
4292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any error and sets errno
4293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t **rsp
4295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     This variable is set on a successful return to point to
4296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     service(s) found. Each element of this list is of type
4297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     sdp_record_t* (of the services which matched the search list)
4298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
4299542fc57346fbb329934152f446f58cc61a5d5d00Marcel 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)
4300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
4301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
4302cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
4303cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0;
4304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0, attr_list_len = 0;
4305cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	int rsp_count = 0, cstate_len = 0;
4306cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	unsigned int pdata_len;
4307cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
4308cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
4309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
4310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dataType;
4311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *rec_list = NULL;
4312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t rsp_concat_buf;
4313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
4314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
4316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
4317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
4318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
43198232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg
43208232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg	memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));
43218232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg
4322cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
4323cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
4324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
4325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
4326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
4327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
4328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
4329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4330aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
4331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
4332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43333d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* generate PDU */
4334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
4335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
4336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43373d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add service class IDs for search */
4338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_searchseq_pdu(pdata, search);
4339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data seq added : %d\n", seqlen);
4341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43428f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* now set the length and increment the pointer */
4343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
4344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
4345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4346aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
4347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
4348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
4349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
4351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43528f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* get attr seq PDU form */
4353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrids,
4354aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
4355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seqlen == -1) {
4356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = EINVAL;
4357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
4358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
4359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
4360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Attr list length : %d\n", seqlen);
4361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
4362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rsp = 0;
4363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43648f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* save before Continuation State */
4365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata = pdata;
4366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
4367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
4369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid = htons(sdp_gen_tid(session));
4370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43718f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		/* add continuation state (can be null) */
43720a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata,
43730a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
4374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43758f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		/* set the request header's param length */
4376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
4377aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
4378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
4379121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
4380121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
4381121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
4382121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
4383121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
4384121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0) {
4386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
4387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
4388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
43898f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg
4390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
4391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
4392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
4393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
43948f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg
4395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
4396121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
4397121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4398121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < sizeof(uint16_t)) {
4399121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
4400121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
4401121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
4402121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
4403121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4404aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
4405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		attr_list_len += rsp_count;
44063d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		pdata += sizeof(uint16_t); /* pdata points to attribute list */
4407121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len -= sizeof(uint16_t);
4408121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4409121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < rsp_count + sizeof(uint8_t)) {
4410121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet: continuation state data missing");
4411121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
4412121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
4413121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
4414121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4415aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		cstate_len = *(uint8_t *) (pdata + rsp_count);
4416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attrlist byte count : %d\n", attr_list_len);
4418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Response byte count : %d\n", rsp_count);
4419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Cstate length : %d\n", cstate_len);
4420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
4421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * This is a split response, need to concatenate intermediate
4422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * responses and the last one which will have cstate_len == 0
4423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
4424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
4425cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			uint8_t *targetPtr = NULL;
4426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4427aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
4428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
44298f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			/* build concatenated response buffer */
4430cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
4431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
4432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
4433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(targetPtr, pdata, rsp_count);
4434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.data_size += rsp_count;
4435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
4436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
4437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (attr_list_len > 0) {
4439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int scanned = 0;
4440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4441121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rsp_concat_buf.data_size != 0) {
4442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rsp_concat_buf.data;
4443121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			pdata_len = rsp_concat_buf.data_size;
4444121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
4445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
4447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Response is a sequence of sequence(s) for one or
4448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * more data element sequence(s) representing services
4449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * for which attributes are returned
4450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
4451d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann		scanned = sdp_extract_seqtype(pdata, pdata_len, &dataType, &seqlen);
4452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Bytes scanned : %d\n", scanned);
4454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Seq length : %d\n", seqlen);
4455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (scanned && seqlen) {
4457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata += scanned;
4458121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			pdata_len -= scanned;
4459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			do {
4460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				int recsize = 0;
4461d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann				sdp_record_t *rec = sdp_extract_pdu(pdata, pdata_len, &recsize);
4462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				if (rec == NULL) {
4463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					SDPERR("SVC REC is null\n");
4464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					status = -1;
4465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					goto end;
4466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				}
44678db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann				if (!recsize) {
44688db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann					sdp_record_free(rec);
44698db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann					break;
44708db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann				}
4471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				scanned += recsize;
4472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				pdata += recsize;
4473121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann				pdata_len -= recsize;
4474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Loc seq length : %d\n", recsize);
4476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle);
4477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Bytes scanned : %d\n", scanned);
4478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Attrlist byte count : %d\n", attr_list_len);
4479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				rec_list = sdp_list_append(rec_list, rec);
4480121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			} while (scanned < attr_list_len && pdata_len > 0);
4481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Successful scan of service attr lists\n");
4483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*rsp = rec_list;
4484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
4485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
44868f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergend:
4487a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rsp_concat_buf.data);
4488a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
4489a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
4490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
4491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
4492542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
4494542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Find devices in the piconet.
4495542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
4496542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found)
4497542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
4498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0);
4499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (n < 0) {
4500542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Inquiry failed:%s", strerror(errno));
4501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
4502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
4503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*found = n;
4504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
4505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
4506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_close(sdp_session_t *session)
4508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
45098be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	struct sdp_transaction *t;
45108be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	int ret;
45118f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg
45128be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!session)
45138be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return -1;
45148be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
45158be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	ret = close(session->sock);
45168be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
45178be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	t = session->priv;
45188be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
45198be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (t) {
4520a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan		free(t->reqbuf);
45218be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
4522a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan		free(t->rsp_concat_buf.data);
45238be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
45248be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		free(t);
45258be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
4526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(session);
4527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return ret;
4528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
4529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int sdp_is_local(const bdaddr_t *device)
4531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
4532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0;
4533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
4534542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
45351be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimstatic int sdp_connect_local(sdp_session_t *session)
4536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
45371be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	struct sockaddr_un sa;
4538a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
45391be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->sock = socket(PF_UNIX, SOCK_STREAM, 0);
45401be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (session->sock < 0)
45411be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return -1;
45421be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->local = 1;
4543a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
45441be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.sun_family = AF_UNIX;
45451be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	strcpy(sa.sun_path, SDP_UNIX_PATH);
4546a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
4547d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	return connect(session->sock, (struct sockaddr *) &sa, sizeof(sa));
45481be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim}
45491be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45501be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimstatic int sdp_connect_l2cap(const bdaddr_t *src,
45518f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		const bdaddr_t *dst, sdp_session_t *session)
45521be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim{
45531be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	uint32_t flags = session->flags;
45541be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	struct sockaddr_l2 sa;
45551be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	int sk;
45561be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45571be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
45581be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (session->sock < 0)
45591be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return -1;
45601be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->local = 0;
45611be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45621be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sk = session->sock;
45631be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45641be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (flags & SDP_NON_BLOCKING) {
45651be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		long arg = fcntl(sk, F_GETFL, 0);
45661be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		fcntl(sk, F_SETFL, arg | O_NONBLOCK);
4567a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	}
4568a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
4569b5e64e37e108d782ad9496873fcdc579e5a4dc60Johan Hedberg	memset(&sa, 0, sizeof(sa));
4570b5e64e37e108d782ad9496873fcdc579e5a4dc60Johan Hedberg
45711be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_family = AF_BLUETOOTH;
45721be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_psm = 0;
4573a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
45741be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (bacmp(src, BDADDR_ANY)) {
45751be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		sa.l2_bdaddr = *src;
45761be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0)
45771be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			return -1;
45781be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	}
4579a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
45801be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (flags & SDP_WAIT_ON_CLOSE) {
45811be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		struct linger l = { .l_onoff = 1, .l_linger = 1 };
45821be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
45831be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	}
45841be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45851be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_psm = htobs(SDP_PSM);
45861be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_bdaddr = *dst;
45871be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45881be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	do {
45891be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa));
4590aa7577018bb1faac4b67b52dc8b003663cdd03adUlisses Furquim		if (!ret)
45911be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			return 0;
45921be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (ret < 0 && (flags & SDP_NON_BLOCKING) &&
45938f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg				(errno == EAGAIN || errno == EINPROGRESS))
45941be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			return 0;
45951be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	} while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY));
45961be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45971be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	return -1;
45981be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim}
45991be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
46001be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimsdp_session_t *sdp_connect(const bdaddr_t *src,
46018f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		const bdaddr_t *dst, uint32_t flags)
46021be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim{
46031be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sdp_session_t *session;
46041be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	int err;
46051be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
46061be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) {
46071be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		errno = EINVAL;
46081be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return NULL;
46091be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	}
46101be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
46111be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session = sdp_create(-1, flags);
46121be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (!session)
46131be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return NULL;
46141be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
46151be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (sdp_is_local(dst)) {
46161be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (sdp_connect_local(session) < 0)
46171be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			goto fail;
4618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
46191be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (sdp_connect_l2cap(src, dst, session) < 0)
46201be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			goto fail;
4621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
4622a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
46231be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	return session;
46241be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
4625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail:
462612862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann	err = errno;
4627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (session->sock >= 0)
4628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		close(session->sock);
4629a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(session->priv);
4630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(session);
463112862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann	errno = err;
46321be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
46331be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	return NULL;
4634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
46358f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann
46368f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannint sdp_get_socket(const sdp_session_t *session)
46378f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{
46388f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann	return session->sock;
46398f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann}
46408f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann
46418f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannuint16_t sdp_gen_tid(sdp_session_t *session)
46428f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{
46438f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann	return session->tid++;
46448f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann}
46453faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
46463faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas/*
46473faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas * Set the supported features
46483faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas */
46493faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenasint sdp_set_supp_feat(sdp_record_t *rec, const sdp_list_t *sf)
46503faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas{
46513faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	const sdp_list_t *p, *r;
46523faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdp_data_t *feat, *seq_feat;
46533faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	int seqlen, i;
46543faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	void **seqDTDs, **seqVals;
46553faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
46563faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	seqlen = sdp_list_len(sf);
46573faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	seqDTDs = malloc(seqlen * sizeof(void *));
46583faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	if (!seqDTDs)
46593faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		return -1;
46603faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	seqVals = malloc(seqlen * sizeof(void *));
46613faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	if (!seqVals) {
46623faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		free(seqDTDs);
46633faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		return -1;
46643faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	}
46653faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
46663faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	for (p = sf, i = 0; p; p = p->next, i++) {
46673faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		int plen, j;
46683faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		void **dtds, **vals;
46691d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		int *lengths;
46703faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
46713faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		plen = sdp_list_len(p->data);
46723faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		dtds = malloc(plen * sizeof(void *));
46733faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		if (!dtds)
46743faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			goto fail;
46753faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		vals = malloc(plen * sizeof(void *));
46763faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		if (!vals) {
46773faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			free(dtds);
46783faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			goto fail;
46793faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		}
46801d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		lengths = malloc(plen * sizeof(int *));
46811d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		if (!lengths) {
46821d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			free(dtds);
46831d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			free(vals);
46841d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			goto fail;
46851d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		}
46863faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		for (r = p->data, j = 0; r; r = r->next, j++) {
46873faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			sdp_data_t *data = (sdp_data_t*)r->data;
46883faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			dtds[j] = &data->dtd;
46891d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			switch (data->dtd) {
46901d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_URL_STR8:
46911d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_URL_STR16:
46921d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_TEXT_STR8:
46931d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_TEXT_STR16:
46941d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				vals[j] = data->val.str;
46951d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				lengths[j] = data->unitSize - sizeof(uint8_t);
46961d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				break;
46971d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_ALT8:
46981d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_ALT16:
46991d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_ALT32:
47001d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_SEQ8:
47011d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_SEQ16:
47021d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_SEQ32:
47031d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				vals[j] = data->val.dataseq;
47041d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				lengths[j] = 0;
47051d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				break;
47061d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			default:
47071d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				vals[j] = &data->val;
47081d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				lengths[j] = 0;
47091d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				break;
47101d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			}
47113faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		}
47121d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		feat = sdp_seq_alloc_with_length(dtds, vals, lengths, plen);
47133faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		free(dtds);
47143faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		free(vals);
47151d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		free(lengths);
47163faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		if (!feat)
47173faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			goto fail;
47183faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		seqDTDs[i] = &feat->dtd;
47193faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		seqVals[i] = feat;
47203faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	}
47213faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	seq_feat = sdp_seq_alloc(seqDTDs, seqVals, seqlen);
47223faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	if (!seq_feat)
47233faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		goto fail;
47243faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdp_attr_replace(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST, seq_feat);
47253faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47263faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	free(seqVals);
47273faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	free(seqDTDs);
47283faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	return 0;
47293faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47303faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenasfail:
47313faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	free(seqVals);
47323faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	free(seqDTDs);
47333faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	return -1;
47343faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas}
47353faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47363faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas/*
47373faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas * Get the supported features
47383faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas * If an error occurred -1 is returned and errno is set
47393faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas */
47403faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenasint sdp_get_supp_feat(const sdp_record_t *rec, sdp_list_t **seqp)
47413faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas{
47423faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdp_data_t *sdpdata, *d;
47433faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdp_list_t *tseq;
47443faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	tseq = NULL;
47453faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47463faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdpdata = sdp_data_get(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST);
47473faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47483faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	if (!sdpdata || sdpdata->dtd < SDP_SEQ8 || sdpdata->dtd > SDP_SEQ32)
47493faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		return sdp_get_uuidseq_attr(rec,
4750d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann					SDP_ATTR_SUPPORTED_FEATURES_LIST, seqp);
47513faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47523faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	for (d = sdpdata->val.dataseq; d; d = d->next) {
47533faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		sdp_data_t *dd;
47543faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		sdp_list_t *subseq;
47553faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47563faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
47573faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			goto fail;
475815b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter
47593faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		subseq = NULL;
476015b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter
47613faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		for (dd = d->val.dataseq; dd; dd = dd->next) {
47623faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			sdp_data_t *data;
476315b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			void *val;
476415b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			int length;
476515b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter
476615b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			switch (dd->dtd) {
476715b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_URL_STR8:
476815b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_URL_STR16:
476915b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_TEXT_STR8:
477015b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_TEXT_STR16:
477115b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				val = dd->val.str;
477215b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				length = dd->unitSize - sizeof(uint8_t);
477315b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				break;
477415b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_UINT8:
477515b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_UINT16:
477615b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				val = &dd->val;
477715b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				length = 0;
477815b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				break;
477915b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			default:
47803faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas				goto fail;
478115b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			}
478215b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter
478315b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			data = sdp_data_alloc_with_length(dd->dtd, val, length);
47843faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			if (data)
47853faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas				subseq = sdp_list_append(subseq, data);
47863faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		}
47873faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		tseq = sdp_list_append(tseq, subseq);
47883faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	}
47893faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	*seqp = tseq;
47903faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	return 0;
47913faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47923faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenasfail:
47933faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	while (tseq) {
47943faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		sdp_list_t * next;
47953faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47963faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		next = tseq->next;
47973faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		sdp_list_free(tseq, free);
47983faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		tseq = next;
47993faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	}
48003faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	errno = EINVAL;
48013faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	return -1;
48023faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas}
48033faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
4804