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
67661d0747e6c9289485ca5b33e2fd1874d1a9b27c5Szymon Janc	*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	buf->data_size += sizeof(uint16_t);
692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata)
695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d;
697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = 0;
698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
6992db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	for (d = sdpdata->val.dataseq; d; d = d->next) {
7002db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		if (buf->data)
7012db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz			n += sdp_gen_pdu(buf, d);
7022db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		else
7032db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz			n += sdp_gen_buffer(buf, d);
7042db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	}
705641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return n;
707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
7092db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentzstatic int sdp_get_data_size(sdp_buf_t *buf, sdp_data_t *d)
7102db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz{
7112db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	uint32_t data_size = 0;
7122db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	uint8_t dtd = d->dtd;
7132db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7142db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	switch (dtd) {
7152db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_DATA_NIL:
7162db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7172db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT8:
7182db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint8_t);
7192db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7202db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT16:
7212db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint16_t);
7222db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7232db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT32:
7242db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint32_t);
7252db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7262db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT64:
7272db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint64_t);
7282db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7292db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UINT128:
7302db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint128_t);
7312db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7322db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT8:
7332db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_BOOL:
7342db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(int8_t);
7352db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7362db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT16:
7372db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(int16_t);
7382db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7392db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT32:
7402db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(int32_t);
7412db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7422db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT64:
7432db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(int64_t);
7442db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7452db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_INT128:
7462db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint128_t);
7472db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7482db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_TEXT_STR8:
7492db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_TEXT_STR16:
7502db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_TEXT_STR32:
7512db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_URL_STR8:
7522db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_URL_STR16:
7532db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_URL_STR32:
7542db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = d->unitSize - sizeof(uint8_t);
7552db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7562db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_SEQ8:
7572db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_SEQ16:
7582db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_SEQ32:
7592db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = get_data_size(buf, d);
7602db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7612db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_ALT8:
7622db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_ALT16:
7632db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_ALT32:
7642db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = get_data_size(buf, d);
7652db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7662db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UUID16:
7672db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint16_t);
7682db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7692db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UUID32:
7702db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint32_t);
7712db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7722db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	case SDP_UUID128:
7732db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		data_size = sizeof(uint128_t);
7742db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7752db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	default:
7762db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		break;
7772db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	}
7782db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7792db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	if (!buf->data)
7802db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		buf->buf_size += data_size;
7812db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7822db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	return data_size;
7832db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz}
7842db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7856996a497c429be009a9f522c3a28ad777d2ba3b5Luiz Augusto von Dentzstatic int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d)
7862db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz{
7872db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	int orig = buf->buf_size;
7882db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7892db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	if (buf->buf_size == 0 && d->dtd == 0) {
7902db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		/* create initial sequence */
7912db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		buf->buf_size += sizeof(uint8_t);
7922db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7932db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		/* reserve space for sequence size */
7942db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		buf->buf_size += sizeof(uint8_t);
7952db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	}
7962db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
7972db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	/* attribute length */
7982db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	buf->buf_size += sizeof(uint8_t) + sizeof(uint16_t);
7992db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
8002db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_get_data_type(buf, d->dtd);
8012db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_get_data_size(buf, d);
8022db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
8032db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	if (buf->buf_size > UCHAR_MAX && d->dtd == SDP_SEQ8)
8042db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		buf->buf_size += sizeof(uint8_t);
8052db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
8062db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	return buf->buf_size - orig;
8072db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz}
8082db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
811cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t pdu_size = 0, data_size = 0;
812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned char *src = NULL, is_seq = 0, is_alt = 0;
813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd = d->dtd;
814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint16_t u16;
815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t u32;
816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint64_t u64;
817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t u128;
818cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *seqp = buf->data + buf->data_size;
819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdu_size = sdp_set_data_type(buf, dtd);
8212db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	data_size = sdp_get_data_size(buf, d);
822641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		src = &d->val.uint8;
828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.uint16);
831cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u16;
832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.uint32);
835cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u32;
836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u64 = hton64(d->val.uint64);
839cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u64;
840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		hton128(&d->val.uint128, &u128);
843cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u128;
844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
847cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &d->val.int8;
848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.int16);
851cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u16;
852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.int32);
855cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u32;
856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u64 = hton64(d->val.int64);
859cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u64;
860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		hton128(&d->val.int128, &u128);
863cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u128;
864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
868641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann	case SDP_URL_STR8:
869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
871cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) d->val.str;
872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		is_seq = 1;
878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		is_alt = 1;
884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_set_seq_len(seqp, data_size);
885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u16 = htons(d->val.uuid.value.uuid16);
888cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u16;
889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		u32 = htonl(d->val.uuid.value.uuid32);
892cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &u32;
893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
895cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann		src = (unsigned char *) &d->val.uuid.value.uuid128;
896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
900641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!is_seq && !is_alt) {
9020738d9b9063fb953038299911a1a757e89f894dcSzymon Janc		if (src && buf->buf_size >= buf->data_size + data_size) {
903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(buf->data + buf->data_size, src, data_size);
904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			buf->data_size += data_size;
90566dcd1342d3f9bf08dfc476df121c7355c84427aMarcel Holtmann		} else if (dtd != SDP_DATA_NIL) {
9060477cf9b6c61ab1f329206f8b40bcf8e8bfbaad5Vinicius Costa Gomes			SDPDBG("Gen PDU : Can't copy from invalid source or dest\n");
90766dcd1342d3f9bf08dfc476df121c7355c84427aMarcel Holtmann		}
908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
909641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
910542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdu_size += data_size;
911641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann
912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return pdu_size;
913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void sdp_attr_pdu(void *value, void *udata)
916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value);
918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
9202db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentzstatic void sdp_attr_size(void *value, void *udata)
9212db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz{
9222db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_gen_buffer((sdp_buf_t *)udata, (sdp_data_t *)value);
9232db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz}
9242db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf)
926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
9272db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	memset(buf, 0, sizeof(sdp_buf_t));
9282db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_list_foreach(rec->attrlist, sdp_attr_size, buf);
9292db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
9302db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	buf->data = malloc(buf->buf_size);
931997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	if (!buf->data)
932997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann		return -ENOMEM;
933997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	buf->data_size = 0;
934997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	memset(buf->data, 0, buf->buf_size);
9352db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
936997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf);
937997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann
938997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	return 0;
939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d)
942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *p = sdp_data_get(rec, attr);
944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (p) {
946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->attrlist = sdp_list_remove(rec->attrlist, p);
947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_free(p);
948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
9494c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->attrId = attr;
9514c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func);
9524c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
9534c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	if (attr == SDP_ATTR_SVCLASS_ID_LIST)
9544c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann		extract_svclass_uuid(d, &rec->svclass);
955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attrid_comp_func(const void *key1, const void *key2)
958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_data_t *d1 = (const sdp_data_t *)key1;
960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_data_t *d2 = (const sdp_data_t *)key2;
961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d1 && d2)
963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return d1->attrId - d2->attrId;
964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void data_seq_free(sdp_data_t *seq)
968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = seq->val.dataseq;
970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (d) {
972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *next = d->next;
973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_free(d);
974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d = next;
975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_free(sdp_data_t *d)
979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		data_seq_free(d);
985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d->val.str);
993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(d);
996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
998d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmannint sdp_uuid_extract(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned)
999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1000a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	uint8_t type;
1001a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1002cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1003a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1004a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return -1;
1005a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1006a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1007a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	type = *(const uint8_t *) p;
1008a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1009a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (!SDP_IS_UUID(type)) {
1010a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unknown data type : %d expecting a svc UUID\n", type);
1011a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return -1;
1012a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1013a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	p += sizeof(uint8_t);
1014a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	*scanned += sizeof(uint8_t);
1015a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= sizeof(uint8_t);
1016a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (type == SDP_UUID16) {
1017cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint16_t)) {
1018a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Not enough room for 16-bit UUID");
1019a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return -1;
1020a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1021a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p)));
1022a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*scanned += sizeof(uint16_t);
1023a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	} else if (type == SDP_UUID32) {
1024cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint32_t)) {
1025a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Not enough room for 32-bit UUID");
1026a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return -1;
1027a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1028a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p)));
1029a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*scanned += sizeof(uint32_t);
1030a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	} else {
1031cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint128_t)) {
1032a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Not enough room for 128-bit UUID");
1033a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return -1;
1034a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1035a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		sdp_uuid128_create(uuid, p);
1036a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*scanned += sizeof(uint128_t);
1037a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1038a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	return 0;
1039a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann}
1040a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1041a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannstatic sdp_data_t *extract_int(const void *p, int bufsize, int *len)
1042a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann{
1043a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	sdp_data_t *d;
1044a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1045cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1046a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1047a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1048a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1049a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1050a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	d = malloc(sizeof(sdp_data_t));
1051114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!d)
1052114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
1053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting integer\n");
1055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
1056aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
1057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
1058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += sizeof(uint8_t);
1059a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= sizeof(uint8_t);
1060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
1062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1067cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint8_t)) {
1068a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1069a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1070a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1071a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint8_t);
1073aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint8 = *(uint8_t *) p;
1074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1077cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint16_t)) {
1078a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1079a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1080a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1081a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1082542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint16_t);
1083aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p));
1084542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1085542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1087cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint32_t)) {
1088a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1089a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1090a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1091a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1092542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint32_t);
1093aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p));
1094542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1095542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1097cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint64_t)) {
1098a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1099a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1100a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1101a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint64_t);
1103aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p));
1104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1107cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint128_t)) {
1108a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1109a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1110a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1111a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint128_t);
1113aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		ntoh128((uint128_t *) p, &d->val.uint128);
1114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
1117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		d = NULL;
1118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
11228f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergstatic sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len,
11238f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_record_t *rec)
1124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
112521f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
1126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1127114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!d)
1128114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
1129114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
1130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting UUID");
1131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
1132d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann	if (sdp_uuid_extract(p, bufsize, &d->val.uuid, len) < 0) {
1133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
1134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
1135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1136d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	d->dtd = *p;
11379d9a7646b189cc2471b925cc448862e14c10c0c4Marcel Holtmann	if (rec)
11389d9a7646b189cc2471b925cc448862e14c10c0c4Marcel Holtmann		sdp_pattern_add_uuid(rec, &d->val.uuid);
1139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
11438f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * Extract strings from the PDU (could be service description and similar info)
1144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1145a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannstatic sdp_data_t *extract_str(const void *p, int bufsize, int *len)
1146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	char *s;
1148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
1149a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	sdp_data_t *d;
1150a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1151cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1152a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1153a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1154a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1155a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1156a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	d = malloc(sizeof(sdp_data_t));
1157114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!d)
1158114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
1159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
1161aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	d->dtd = *(uint8_t *) p;
1162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
1163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += sizeof(uint8_t);
1164a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= sizeof(uint8_t);
1165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
1167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1169cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint8_t)) {
1170a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1171a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1172a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1173a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1174aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		n = *(uint8_t *) p;
1175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint8_t);
1176a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*len += sizeof(uint8_t);
1177a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		bufsize -= sizeof(uint8_t);
1178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1181cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint16_t)) {
1182a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1183a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			free(d);
1184a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return NULL;
1185a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1186aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		n = ntohs(bt_get_unaligned((uint16_t *) p));
1187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += sizeof(uint16_t);
1188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*len += sizeof(uint16_t) + n;
1189a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		bufsize -= sizeof(uint16_t);
1190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Sizeof text string > UINT16_MAX\n");
1193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(d);
1194f58df2db7a606fcd13a36824bdb4fc3440d9a71eSantiago Carot-Nemesio		return NULL;
1195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1197a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (bufsize < n) {
1198a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("String too long to fit in packet");
1199a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		free(d);
1200a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1201a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1202a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1203ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann	s = malloc(n + 1);
1204a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (!s) {
1205a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Not enough memory for incoming string");
1206a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		free(d);
1207a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1208a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(s, 0, n + 1);
1210ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann	memcpy(s, p, n);
1211542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1212a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	*len += n;
1213a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1214542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Len : %d\n", n);
1215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Str : %s\n", s);
1216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d->val.str = s;
12180ed4f8572e1b32b4dd57304db14351f0e0c59119Marcel Holtmann	d->unitSize = n + sizeof(uint8_t);
1219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1222a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann/*
1223a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann * Extract the sequence type and its length, and return offset into buf
1224a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann * or 0 on failure.
1225a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann */
1226d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmannint sdp_extract_seqtype(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size)
1227a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann{
1228a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	uint8_t dtd;
1229a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	int scanned = sizeof(uint8_t);
1230a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1231cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1232a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1233a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return 0;
1234a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1235a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1236a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	dtd = *(uint8_t *) buf;
1237a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	buf += sizeof(uint8_t);
1238a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= sizeof(uint8_t);
1239a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	*dtdp = dtd;
1240a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	switch (dtd) {
1241a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_SEQ8:
1242a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_ALT8:
1243cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint8_t)) {
1244a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1245a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return 0;
1246a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1247a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*size = *(uint8_t *) buf;
1248a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		scanned += sizeof(uint8_t);
1249a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		break;
1250a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_SEQ16:
1251a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_ALT16:
1252cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint16_t)) {
1253a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1254a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return 0;
1255a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1256a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*size = ntohs(bt_get_unaligned((uint16_t *) buf));
1257a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		scanned += sizeof(uint16_t);
1258a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		break;
1259a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_SEQ32:
1260a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	case SDP_ALT32:
1261cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint32_t)) {
1262a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			SDPERR("Unexpected end of packet");
1263a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann			return 0;
1264a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		}
1265a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		*size = ntohl(bt_get_unaligned((uint32_t *) buf));
1266a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		scanned += sizeof(uint32_t);
1267a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		break;
1268a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	default:
1269a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unknown sequence type, aborting\n");
1270a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return 0;
1271a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1272a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	return scanned;
1273a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann}
1274a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
12758f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergstatic sdp_data_t *extract_seq(const void *p, int bufsize, int *len,
12768f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_record_t *rec)
1277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen, n = 0;
1279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *curr, *prev;
128021f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_data_t *d = malloc(sizeof(sdp_data_t));
1281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1282114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!d)
1283114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
1284114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
1285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Extracting SEQ");
1286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(d, 0, sizeof(sdp_data_t));
1287d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann	*len = sdp_extract_seqtype(p, bufsize, &d->dtd, &seqlen);
1288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen);
1289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (*len == 0)
1291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return d;
1292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1293a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	if (*len > bufsize) {
1294a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Packet not big enough to hold sequence.");
1295a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		free(d);
1296a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1297a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1298a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += *len;
1300a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	bufsize -= *len;
130158a7ff1f9e789b7354bb1feb02f9b7ca5198ec65Luiz Augusto von Dentz	prev = NULL;
1302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (n < seqlen) {
1303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int attrlen = 0;
1304d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann		curr = sdp_extract_attr(p, bufsize, &attrlen, rec);
1305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (curr == NULL)
1306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (prev)
1309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			prev->next = curr;
1310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else
1311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			d->val.dataseq = curr;
1312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		prev = curr;
1313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += attrlen;
1314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += attrlen;
1315a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		bufsize -= attrlen;
1316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen);
1318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*len += n;
1321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return d;
1322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
13248f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergsdp_data_t *sdp_extract_attr(const uint8_t *p, int bufsize, int *size,
13258f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_record_t *rec)
1326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *elem;
1328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = 0;
1329a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	uint8_t dtd;
1330a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1331cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if (bufsize < (int) sizeof(uint8_t)) {
1332a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		SDPERR("Unexpected end of packet");
1333a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		return NULL;
1334a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	}
1335a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
1336a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann	dtd = *(const uint8_t *)p;
1337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("extract_attr: dtd=0x%x", dtd);
1339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
1340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1352a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		elem = extract_int(p, bufsize, &n);
1353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1357a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		elem = extract_uuid(p, bufsize, &n, rec);
1358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
1362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
1365a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		elem = extract_str(p, bufsize, &n);
1366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1373a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann		elem = extract_seq(p, bufsize, &n, rec);
1374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	default:
1376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd);
1377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return NULL;
1378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*size += n;
1380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return elem;
1381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void attr_print_func(void *value, void *userData)
1385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = (sdp_data_t *)value;
1387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("=====================================\n");
1389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n",  d->attrId);
1390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value);
1391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
1392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_print(d);
1393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
1394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("NULL value\n");
1395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("=====================================\n");
1396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_print_service_attr(sdp_list_t *svcAttrList)
1399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
14008bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann	SDPDBG("Printing service attr list %p\n", svcAttrList);
1401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_foreach(svcAttrList, attr_print_func, NULL);
14028bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann	SDPDBG("Printed service attr list %p\n", svcAttrList);
1403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1406d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmannsdp_record_t *sdp_extract_pdu(const uint8_t *buf, int bufsize, int *scanned)
1407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int extracted = 0, seqlen = 0;
1409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dtd;
1410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint16_t attr;
1411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_record_t *rec = sdp_record_alloc();
1412cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	const uint8_t *p = buf;
1413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1414d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann	*scanned = sdp_extract_seqtype(buf, bufsize, &dtd, &seqlen);
1415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += *scanned;
14160e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann	bufsize -= *scanned;
1417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->attrlist = NULL;
14180e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann
14190e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann	while (extracted < seqlen && bufsize > 0) {
1420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int n = sizeof(uint8_t), attrlen = 0;
1421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data = NULL;
1422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
14230e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann		SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d",
14240e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann							seqlen, extracted);
14250e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann
1426cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < n + (int) sizeof(uint16_t)) {
14270e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann			SDPERR("Unexpected end of packet");
14280e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann			break;
14290e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann		}
14300e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann
1431aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		dtd = *(uint8_t *) p;
1432aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		attr = ntohs(bt_get_unaligned((uint16_t *) (p + n)));
1433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += sizeof(uint16_t);
1434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr);
1436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1437d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann		data = sdp_extract_attr(p + n, bufsize - n, &attrlen, rec);
1438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen);
1440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		n += attrlen;
1442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (data == NULL) {
1443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Terminating extraction of attributes");
1444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
14464c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
1447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (attr == SDP_ATTR_RECORD_HANDLE)
1448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rec->handle = data->val.uint32;
14494c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
14504c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann		if (attr == SDP_ATTR_SVCLASS_ID_LIST)
14514c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann			extract_svclass_uuid(data, &rec->svclass);
14524c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann
1453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		extracted += n;
1454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p += n;
14550e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann		bufsize -= n;
1456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, attr, data);
14570e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann
1458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d",
14590e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann							seqlen, extracted);
1460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Successful extracting of Svc Rec attributes\n");
1463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_print_service_attr(rec->attrlist);
1464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*scanned += seqlen;
1466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
1467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1469e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentzstatic void sdp_copy_pattern(void *value, void *udata)
1470e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1471e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	uuid_t *uuid = value;
1472e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_record_t *rec = udata;
1473e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1474e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_pattern_add_uuid(rec, uuid);
1475e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1476e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1477eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocerastatic void *sdp_data_value(sdp_data_t *data, uint32_t *len)
1478e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1479e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	void *val = NULL;
1480e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1481e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	switch (data->dtd) {
1482e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_DATA_NIL:
1483e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1484e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT8:
1485e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint8;
1486e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1487e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT8:
1488e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_BOOL:
1489e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int8;
1490e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1491e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT16:
1492e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint16;
1493e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1494e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT16:
1495e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int16;
1496e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1497e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT32:
1498e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint32;
1499e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1500e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT32:
1501e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int32;
1502e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1503e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT64:
1504e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int64;
1505e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1506e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT64:
1507e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint64;
1508e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1509e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UINT128:
1510e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.uint128;
1511e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1512e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_INT128:
1513e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = &data->val.int128;
1514e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1515e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UUID16:
15160472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		val = &data->val.uuid.value.uuid16;
15170472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		break;
1518e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UUID32:
15190472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		val = &data->val.uuid.value.uuid32;
15200472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		break;
1521e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_UUID128:
15220472c96f4702fadcb684ff0f4b42ce044c235024Luiz Augusto von Dentz		val = &data->val.uuid.value.uuid128;
1523e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1524e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_URL_STR8:
1525e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_URL_STR16:
1526e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_TEXT_STR8:
1527e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_TEXT_STR16:
1528e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_URL_STR32:
1529e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_TEXT_STR32:
1530e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = data->val.str;
1531eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		if (len)
1532eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera			*len = data->unitSize - 1;
1533e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1534e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_ALT8:
1535e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_ALT16:
1536e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_ALT32:
1537e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_SEQ8:
1538e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_SEQ16:
1539e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	case SDP_SEQ32:
1540e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		val = sdp_copy_seq(data->val.dataseq);
1541e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		break;
1542e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	}
1543e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1544e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	return val;
1545e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1546e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1547e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentzstatic sdp_data_t *sdp_copy_seq(sdp_data_t *data)
1548e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1549e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_data_t *tmp, *seq = NULL, *cur = NULL;
1550e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1551e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	for (tmp = data; tmp; tmp = tmp->next) {
1552e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		sdp_data_t *datatmp;
1553e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		void *value;
1554e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1555eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		value = sdp_data_value(tmp, NULL);
1556e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		datatmp = sdp_data_alloc_with_length(tmp->dtd, value,
1557d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann								tmp->unitSize);
1558e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1559e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		if (cur)
1560e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz			cur->next = datatmp;
1561e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		else
1562e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz			seq = datatmp;
1563e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1564e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz		cur = datatmp;
1565e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	}
1566e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1567e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	return seq;
1568e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1569e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1570e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentzstatic void sdp_copy_attrlist(void *value, void *udata)
1571e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1572e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_data_t *data = value;
1573e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_record_t *rec = udata;
1574e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	void *val;
1575eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	uint32_t len = 0;
1576e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1577eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	val = sdp_data_value(data, &len);
1578e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1579eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	if (!len)
1580eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		sdp_attr_add_new(rec, data->attrId, data->dtd, val);
1581eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	else
1582eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		sdp_attr_add_new_with_length(rec, data->attrId,
1583d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann							data->dtd, val, len);
1584e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1585e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1586e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentzsdp_record_t *sdp_copy_record(sdp_record_t *rec)
1587e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz{
1588e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_record_t *cpy;
1589e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1590e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	cpy = sdp_record_alloc();
1591e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1592e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	cpy->handle = rec->handle;
1593e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1594e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_list_foreach(rec->pattern, sdp_copy_pattern, cpy);
1595e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	sdp_list_foreach(rec->attrlist, sdp_copy_attrlist, cpy);
1596e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1597e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	cpy->svclass = rec->svclass;
1598e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1599e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz	return cpy;
1600e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz}
1601e464fdc01d72be442e8386d9004452a1e29a9eb9Luiz Augusto von Dentz
1602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void print_dataseq(sdp_data_t *p)
1604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1605542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d;
1606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (d = p; d; d = d->next)
1608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_print(d);
1609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_print(const sdp_record_t *rec)
1613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1614542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
1615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
16166d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann		printf("Service Name: %.*s\n", d->unitSize, d->val.str);
1617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
1618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
16196d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann		printf("Service Description: %.*s\n", d->unitSize, d->val.str);
1620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY);
1621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d)
16226d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann		printf("Service Provider: %.*s\n", d->unitSize, d->val.str);
1623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
1626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_print(sdp_data_t *d)
1627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (d->dtd) {
1629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_DATA_NIL:
1630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("NIL\n");
1631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_BOOL:
1633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT8:
1634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT16:
1635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT32:
1636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT64:
1637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UINT128:
1638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT8:
1639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT16:
1640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT32:
1641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT64:
1642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_INT128:
1643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Integer : 0x%x\n", d->val.uint32);
1644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
1646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
1647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
1648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("UUID\n");
1649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid_print(&d->val.uuid);
1650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1651542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR8:
1652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR16:
1653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_TEXT_STR32:
1654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Text : %s\n", d->val.str);
1655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR8:
1657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR16:
1658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_URL_STR32:
1659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("URL : %s\n", d->val.str);
1660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
1662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
1663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
1664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		print_dataseq(d->val.dataseq);
1665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT8:
1667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT16:
1668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_ALT32:
1669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Data Sequence Alternates\n");
1670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		print_dataseq(d->val.dataseq);
1671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
1672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
1675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId)
1677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (rec->attrlist) {
1679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t sdpTemplate;
1680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpTemplate.attrId = attrId;
1683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func);
1684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (p)
1685d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann			return p->data;
1686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
16874c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann	return NULL;
1688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1690be2ffca847c7537f01b90c7933a2b288306b1f0bMarcel Holtmannstatic int sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size)
1691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1692cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t sent = 0;
1693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (sent < size) {
1695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int n = send(session->sock, buf + sent, size - sent, 0);
1696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (n < 0)
1697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return -1;
1698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sent += n;
1699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1703be2ffca847c7537f01b90c7933a2b288306b1f0bMarcel Holtmannstatic int sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size)
1704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1705542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	fd_set readFds;
1706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 };
1707542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
170873fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann	FD_ZERO(&readFds);
1709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	FD_SET(session->sock, &readFds);
1710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Waiting for response\n");
171173fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann	if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) {
1712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Client timed out\n");
1713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ETIMEDOUT;
1714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return recv(session->sock, buf, size, 0);
1717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * generic send request, wait for response method.
1721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
17228f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergint sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf,
17238f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize)
1724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
1726d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *) reqbuf;
1727d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *) rspbuf;
1728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
1730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > sdp_send_req(session, reqbuf, reqsize)) {
1731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Error sending data:%s", strerror(errno));
1732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
1735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (0 > n)
1736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Read : %d\n", n);
1738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (n == 0 || reqhdr->tid != rsphdr->tid) {
1739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EPROTO;
1740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rspsize = n;
1743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
1747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * singly-linked lists (after openobex implementation)
1748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_append(sdp_list_t *p, void *d)
1750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
175121f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_list_t *q, *n = malloc(sizeof(sdp_list_t));
1752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!n)
1754f58df2db7a606fcd13a36824bdb4fc3440d9a71eSantiago Carot-Nemesio		return NULL;
1755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->data = d;
1757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->next = 0;
1758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!p)
1760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return n;
1761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = p; q->next; q = q->next);
1763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	q->next = n;
1764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return p;
1766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_remove(sdp_list_t *list, void *d)
1769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p, *q;
1771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = 0, p = list; p; q = p, p = p->next)
1773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (p->data == d) {
1774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (q)
1775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				q->next = p->next;
1776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			else
1777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				list = p->next;
1778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			free(p);
1779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1782542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return list;
1783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
17858f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergsdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d,
17868f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_comp_func_t f)
1787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *q, *p, *n;
1789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
179021f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	n = malloc(sizeof(sdp_list_t));
1791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!n)
1792f58df2db7a606fcd13a36824bdb4fc3440d9a71eSantiago Carot-Nemesio		return NULL;
1793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->data = d;
1794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (q = 0, p = list; p; q = p, p = p->next)
1795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (f(p->data, d) >= 0)
17968f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			break;
17973d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* insert between q and p; if !q insert at head */
1798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (q)
1799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		q->next = n;
1800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
1801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		list = n;
1802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	n->next = p;
1803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return list;
1804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
18078f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * Every element of the list points to things which need
1808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to be free()'d. This method frees the list's contents
1809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
1810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_list_free(sdp_list_t *list, sdp_free_func_t f)
1811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *next;
1813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (list) {
1814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		next = list->next;
1815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (f)
1816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			f(list->data);
1817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		free(list);
1818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		list = next;
1819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int __find_port(sdp_data_t *seq, int proto)
1823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!seq || !seq->next)
1825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) {
1828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = seq->next;
1829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		switch (seq->dtd) {
1830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UINT8:
1831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return seq->val.uint8;
1832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UINT16:
1833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return seq->val.uint16;
1834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_proto_port(const sdp_list_t *list, int proto)
1840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (proto != L2CAP_UUID && proto != RFCOMM_UUID) {
1842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
1843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; list; list = list->next) {
1847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = list->data; p; p = p->next) {
1849d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann			sdp_data_t *seq = p->data;
1850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			int port = __find_port(seq, proto);
1851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (port)
1852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return port;
1853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto)
1859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; list; list = list->next) {
1861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *p;
1862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (p = list->data; p; p = p->next) {
1863d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann			sdp_data_t *seq = p->data;
18648f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			if (SDP_IS_UUID(seq->dtd) &&
1865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					sdp_uuid_to_proto(&seq->val.uuid) == proto)
1866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return seq->next;
1867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return NULL;
1870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *pdlist, *curr;
1875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *ap = 0;
1876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdlist = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
1878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (pdlist == NULL) {
1879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
1880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; pdlist; pdlist = pdlist->next) {
1885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_list_t *pds = 0;
1886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pds = sdp_list_append(pds, curr->val.dataseq);
1888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		ap = sdp_list_append(ap, pds);
1889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*pap = ap;
1891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
1892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1894233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmannint sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap)
1895233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann{
1896233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	sdp_data_t *pdlist, *curr;
1897233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	sdp_list_t *ap = 0;
1898233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1899233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
1900233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	if (pdlist == NULL) {
1901233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		errno = ENODATA;
1902233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		return -1;
1903233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	}
1904233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	SDPDBG("AP type : 0%x\n", pdlist->dtd);
1905233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1906233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	pdlist = pdlist->val.dataseq;
1907233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
1908233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	for (; pdlist; pdlist = pdlist->next) {
1909233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		sdp_list_t *pds = 0;
1910233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		for (curr = pdlist->val.dataseq; curr; curr = curr->next)
1911233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann			pds = sdp_list_append(pds, curr->val.dataseq);
1912233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann		ap = sdp_list_append(ap, pds);
1913233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	}
1914233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	*pap = ap;
1915233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann	return 0;
1916233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann}
1917233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann
19188f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergint sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr,
19198f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							sdp_list_t **seqp)
1920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1921542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attr);
1922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*seqp = NULL;
1924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) {
1925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *d;
1926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		for (d = sdpdata->val.dataseq; d; d = d->next) {
19271f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			uuid_t *u;
1928114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) {
1929114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				errno = EINVAL;
1930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				goto fail;
1931114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			}
19321f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi
19331f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			u = malloc(sizeof(uuid_t));
1934114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			if (!u)
1935114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				goto fail;
1936114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
19371f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			memset(u, 0, sizeof(uuid_t));
19381f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			*u = d->val.uuid;
19391f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi			*seqp = sdp_list_append(*seqp, u);
1940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
1942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail:
1944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(*seqp, free);
1945114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	*seqp = NULL;
1946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
1947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
1948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq)
1950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
1951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0, i, len;
1952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **dtds, **values;
1953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid16 = SDP_UUID16;
1954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid32 = SDP_UUID32;
1955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid128 = SDP_UUID128;
1956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p;
1957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
1958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	len = sdp_list_len(seq);
1959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!seq || len == 0)
1960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
1961114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	dtds = malloc(len * sizeof(void *));
1962114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!dtds)
1963114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
1964114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
1965114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	values = malloc(len * sizeof(void *));
1966114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!values) {
1967114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		free(dtds);
1968114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
1969114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	}
1970114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
1971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = seq, i = 0; i < len; i++, p = p->next) {
1972d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		uuid_t *uuid = p->data;
1973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (uuid)
1974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			switch (uuid->type) {
1975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID16:
1976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid16;
1977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid16;
1978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID32:
1980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid32;
1981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid32;
1982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID128:
1984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				dtds[i] = &uuid128;
1985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[i] = &uuid->value.uuid128;
1986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			default:
1988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				status = -1;
1989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
1990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
1991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		else {
1992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
1993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
1994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
1995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
1996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
1997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *data = sdp_seq_alloc(dtds, values, len);
1998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, aid, data);
1999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_pattern_add_uuidseq(rec, seq);
2000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(dtds);
2002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
2003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq)
2007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_lang_attr_t *lang;
2009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata, *curr_data;
2010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*langSeq = NULL;
2012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST);
2013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata == NULL) {
2014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
2015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	curr_data = sdpdata->val.dataseq;
2018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	while (curr_data) {
2019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pCode = curr_data;
20200f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		sdp_data_t *pEncoding;
20210f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		sdp_data_t *pOffset;
20220f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
20230f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		pEncoding = pCode->next;
20240f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		if (!pEncoding)
20250f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			break;
20260f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
20270f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		pOffset = pEncoding->next;
20280f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		if (!pOffset)
20290f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			break;
20300f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
20310f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		lang = malloc(sizeof(sdp_lang_attr_t));
20320f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		if (!lang) {
20330f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			sdp_list_free(*langSeq, free);
20340f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			*langSeq = NULL;
20350f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc			return -1;
2036542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
20370f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		lang->code_ISO639 = pCode->val.uint16;
20380f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		lang->encoding = pEncoding->val.uint16;
20390f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		lang->base_offset = pOffset->val.uint16;
20400f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		SDPDBG("code_ISO639 :  0x%02x\n", lang->code_ISO639);
20410f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		SDPDBG("encoding :     0x%02x\n", lang->encoding);
20420f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		SDPDBG("base_offfset : 0x%02x\n", lang->base_offset);
20430f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc		*langSeq = sdp_list_append(*langSeq, lang);
20440f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
2045542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		curr_data = pOffset->next;
2046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
20470f27847ff8ab48d06d5abd6e5bf35e315cf16457Szymon Janc
2048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq)
2052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_profile_desc_t *profDesc;
2054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata, *seq;
2055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*profDescSeq = NULL;
2057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST);
2058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!sdpdata || !sdpdata->val.dataseq) {
2059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
2060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) {
20630f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		uuid_t *uuid = NULL;
20640f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		uint16_t version = 0x100;
20650f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann
20660f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		if (SDP_IS_UUID(seq->dtd)) {
20670f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			uuid = &seq->val.uuid;
20680f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		} else {
20690f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			sdp_data_t *puuid = seq->val.dataseq;
20700f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			sdp_data_t *pVnum = seq->val.dataseq->next;
20710f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			if (puuid && pVnum) {
20720f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann				uuid = &puuid->val.uuid;
20730f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann				version = pVnum->val.uint16;
20740f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			}
20750f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		}
20760f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann
20770f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann		if (uuid != NULL) {
207821f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann			profDesc = malloc(sizeof(sdp_profile_desc_t));
2079114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			if (!profDesc) {
2080114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				sdp_list_free(*profDescSeq, free);
2081114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				*profDescSeq = NULL;
2082114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio				return -1;
2083114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio			}
20840f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			profDesc->uuid = *uuid;
20850f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann			profDesc->version = version;
2086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG
2087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_uuid_print(&profDesc->uuid);
2088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Vnum : 0x%04x\n", profDesc->version);
2089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif
2090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*profDescSeq = sdp_list_append(*profDescSeq, profDesc);
2091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2092542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2093542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2094542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2095542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16)
2097542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d, *curr;
2099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*u16 = NULL;
2101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST);
2102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d == NULL) {
2103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENODATA;
2104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (curr = d->val.dataseq; curr; curr = curr->next)
2107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*u16 = sdp_list_append(*u16, &curr->val.uint16);
2108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* flexible extraction of basic attributes - Jean II */
2112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* How do we expect caller to extract predefined data sequences? */
2113542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value)
2114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
2116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata)
2118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/* Verify that it is what the caller expects */
2119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 ||
2120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 ||
2121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 ||
2122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdpdata->dtd == SDP_INT32) {
2123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*value = sdpdata->val.uint32;
2124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return 0;
2125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
2127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
2128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
21308f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergint sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value,
21318f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg								int valuelen)
2132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *sdpdata = sdp_data_get(rec, attrid);
2134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdpdata)
2135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/* Verify that it is what the caller expects */
21368f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		if (sdpdata->dtd == SDP_TEXT_STR8 ||
21378f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg				sdpdata->dtd == SDP_TEXT_STR16 ||
21388f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg				sdpdata->dtd == SDP_TEXT_STR32)
2139cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann			if ((int) strlen(sdpdata->val.str) < valuelen) {
2140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				strcpy(value, sdpdata->val.str);
2141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				return 0;
2142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
2143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;
2144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
2145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#define get_basic_attr(attrID, pAttrValue, fieldName)		\
2148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *data = sdp_data_get(rec, attrID);		\
2149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (data) {						\
2150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*pAttrValue = data->val.fieldName;		\
2151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;					\
2152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}							\
2153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	errno = EINVAL;						\
2154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
2155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid)
2157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid);
2159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid)
2162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid);
2164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState)
2167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32);
2169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail)
2172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8);
2174542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2176542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo)
2177542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32);
2179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2181542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState)
2182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32);
2184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2185542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * NOTE that none of the setXXX() functions below will
2188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * actually update the SDP server, unless the
2189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * {register, update}sdp_record_t() function is invoked.
2190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
21928f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergint sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd,
21938f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							const void *value)
2194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *d = sdp_data_alloc(dtd, value);
2196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (d) {
2197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_replace(rec, attr, d);
2198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 0;
2199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return -1;
2201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2203eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocerastatic int sdp_attr_add_new_with_length(sdp_record_t *rec,
2204eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	uint16_t attr, uint8_t dtd, const void *value, uint32_t len)
2205eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera{
2206eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	sdp_data_t *d;
2207eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera
2208eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	d = sdp_data_alloc_with_length(dtd, value, len);
2209eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	if (!d)
2210eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera		return -1;
2211eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera
2212eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	sdp_attr_replace(rec, attr, d);
2213eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera
2214eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera	return 0;
2215eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera}
2216eb101261ee8d43dd3a1bfaa982a3336cd8dfa020Bastien Nocera
2217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2218542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Set the information attributes of the service
2219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by rec. The attributes are
2220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * service name, description and provider name
2221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
22228f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergvoid sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov,
22238f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							const char *desc)
2224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (name)
2226d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY,
2227d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann							SDP_TEXT_STR8, name);
2228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (prov)
2229d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY,
2230d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann							SDP_TEXT_STR8, prov);
2231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (desc)
2232d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY,
2233d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann							SDP_TEXT_STR8, desc);
2234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto)
2237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *seq = NULL;
2239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void *dtds[10], *values[10];
2240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **seqDTDs, **seqs;
2241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i, seqlen;
2242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *p;
2243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = sdp_list_len(proto);
2245114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	seqDTDs = malloc(seqlen * sizeof(void *));
2246114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!seqDTDs)
2247114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
2248114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2249114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	seqs = malloc(seqlen * sizeof(void *));
2250114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!seqs) {
2251114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		free(seqDTDs);
2252114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
2253114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	}
2254114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0, p = proto; p; p = p->next, i++) {
2256d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_list_t *elt = p->data;
2257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *s;
22584e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann		uuid_t *uuid = NULL;
2259cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		unsigned int pslen = 0;
2260206da78a25ae175741a7444edd13dcf67bbdf059Luiz Augusto von Dentz		for (; elt && pslen < ARRAY_SIZE(dtds); elt = elt->next, pslen++) {
2261d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann			sdp_data_t *d = elt->data;
2262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[pslen] = &d->dtd;
2263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			switch (d->dtd) {
2264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID16:
22654e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				uuid = (uuid_t *) d;
22664e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				values[pslen] = &uuid->value.uuid16;
2267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID32:
22694e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				uuid = (uuid_t *) d;
22704e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				values[pslen] = &uuid->value.uuid32;
2271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UUID128:
22734e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				uuid = (uuid_t *) d;
22744e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				values[pslen] = &uuid->value.uuid128;
2275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UINT8:
2277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &d->val.uint8;
2278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_UINT16:
2280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = &d->val.uint16;
2281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
2282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ8:
2283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ16:
2284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			case SDP_SEQ32:
2285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				values[pslen] = d;
2286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				break;
22878f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			/* FIXME: more */
2288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			}
2289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		s = sdp_seq_alloc(dtds, values, pslen);
2291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (s) {
2292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqDTDs[i] = &s->dtd;
2293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqs[i] = s;
22944e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann			if (uuid)
22954e50b413d5237e3fcfa44780ab2207a871686bd2Marcel Holtmann				sdp_pattern_add_uuid(rec, uuid);
2296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqDTDs);
2300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqs);
2301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seq;
2302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets the access protocols of the service specified
2306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to the value specified in "access_proto"
2307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
23088f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * Note that if there are alternate mechanisms by
23098f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * which the service is accessed, then they should
23108f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * be specified as sequences
2311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for accessProtocols has
2313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
23148f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the existing sdp_access_proto_t
2316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
2317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
2321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
2323aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_data_t *protos = NULL;
2324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = ap; p; p = p->next) {
2326d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
2327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		protos = sdp_seq_append(protos, seq);
2328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2329aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos);
2331aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2332aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	return 0;
2333aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann}
2334aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2335aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmannint sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap)
2336aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann{
2337aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	const sdp_list_t *p;
2338aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_data_t *protos = NULL;
2339aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2340aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	for (p = ap; p; p = p->next) {
2341d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_data_t *seq = access_proto_to_dataseq(rec, p->data);
2342aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann		protos = sdp_seq_append(protos, seq);
2343aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	}
2344aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2345aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann	sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST,
2346aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann			protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL);
2347aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann
2348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the "LanguageBase" attributes of the service record
2353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * record to the value specified in "langAttrList".
2354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * "langAttrList" is a linked list of "sdp_lang_attr_t"
2356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * objects, one for each language in which user visible
2357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attributes are present in the service record.
2358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for langAttrList has
2360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
23618f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting sdp_lang_attr_t
2363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
2364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq)
2368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uint16 = SDP_UINT16;
2370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0, i = 0, seqlen = sdp_list_len(seq);
2371114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	void **dtds, **values;
2372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
2373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2374114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	dtds = malloc(3 * seqlen * sizeof(void *));
2375114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!dtds)
2376114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
2377114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2378114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	values = malloc(3 * seqlen * sizeof(void *));
2379114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!values) {
2380114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		free(dtds);
2381114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
2382114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	}
2383114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = seq; p; p = p->next) {
2385d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_lang_attr_t *lang = p->data;
2386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!lang) {
2387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
2391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->code_ISO639;
2392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
2394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->encoding;
2395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[i] = &uint16;
2397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = &lang->base_offset;
2398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen);
2402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq);
2403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(dtds);
2405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
2406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
24108f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * set the "ServiceID" attribute of the service.
24118f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
24128f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * This is the UUID of the service.
24138f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_service_id(sdp_record_t *rec, uuid_t uuid)
2417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid.type) {
2419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
24208f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16,
24218f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid16);
2422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
24248f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32,
24258f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid32);
2426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
24288f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128,
24298f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid128);
2430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &uuid);
2433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
24368f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * set the GroupID attribute of the service record defining a group.
24378f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
24388f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * This is the UUID of the group.
24398f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_group_id(sdp_record_t *rec, uuid_t uuid)
2443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid.type) {
2445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
24468f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16,
24478f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid16);
2448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
24508f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32,
24518f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid32);
2452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
24548f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128,
24558f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							&uuid.value.uuid128);
2456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pattern_add_uuid(rec, &uuid);
2459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the ProfileDescriptorList attribute of the service record
2463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record to the value specified in "profileDesc".
2464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Each element in the list is an object of type
2466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_profile_desc_t which is a definition of the
2467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Bluetooth profile that this service conforms to.
2468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for profileDesc has
2470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set)
24718f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg *
2472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting ProfileDescriptorList
2473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified.
2474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure.
2476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles)
2478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
2480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid16 = SDP_UUID16;
2481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid32 = SDP_UUID32;
2482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uuid128 = SDP_UUID128;
2483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t uint16 = SDP_UINT16;
2484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i = 0, seqlen = sdp_list_len(profiles);
2485114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	void **seqDTDs, **seqs;
2486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	const sdp_list_t *p;
2487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2488114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	seqDTDs = malloc(seqlen * sizeof(void *));
2489114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!seqDTDs)
2490114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
2491114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2492114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	seqs = malloc(seqlen * sizeof(void *));
2493114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!seqs) {
2494114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		free(seqDTDs);
2495114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return -1;
2496114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	}
2497114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (p = profiles; p; p = p->next) {
2499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *seq;
2500542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		void *dtds[2], *values[2];
2501d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		sdp_profile_desc_t *profile = p->data;
2502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!profile) {
2503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		switch (profile->uuid.type) {
2507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID16:
2508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid16;
2509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid16;
2510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID32:
2512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid32;
2513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid32;
2514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		case SDP_UUID128:
2516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			dtds[0] = &uuid128;
2517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			values[0] = &profile->uuid.value.uuid128;
2518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		default:
2520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
2521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			break;
2522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2523542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dtds[1] = &uint16;
2524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[1] = &profile->version;
2525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = sdp_seq_alloc(dtds, values, 2);
2526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (seq) {
2527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqDTDs[i] = &seq->dtd;
2528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			seqs[i] = seq;
2529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_pattern_add_uuid(rec, &profile->uuid);
2530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
2531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		i++;
2532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status == 0) {
2534542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen);
2535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq);
2536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2537542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqDTDs);
2538542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(seqs);
2539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets various URL attributes of the service
2544542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record. The URL include
2545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * client: a URL to the client's
2547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   platform specific (WinCE, PalmOS) executable
2548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   code that can be used to access this service.
2549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * doc: a URL pointing to service documentation
2551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * icon: a URL to an icon that can be used to represent
2553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   this service.
2554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Note that you need to pass NULL for any URLs
2556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * that you don't want to set or remove
2557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
25588f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergvoid sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc,
25598f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg							const char *icon)
2560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client);
2562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc);
2563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon);
2564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2565542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val)
2567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2568542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID16;
2570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->value.uuid16 = val;
2571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2574542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val)
2575542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID32;
2578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->value.uuid32 = val;
2579542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2582542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid128_create(uuid_t *u, const void *val)
25838f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg{
2584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(u, 0, sizeof(uuid_t));
2585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	u->type = SDP_UUID128;
2586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&u->value.uuid128, val, sizeof(uint128_t));
2587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return u;
2588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function
2592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1
2593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
259468a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentzint sdp_uuid_cmp(const void *p1, const void *p2)
259568a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz{
2596bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmann	uuid_t *u1 = sdp_uuid_to_uuid128(p1);
2597bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmann	uuid_t *u2 = sdp_uuid_to_uuid128(p2);
259868a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	int ret;
259968a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz
260068a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	ret = sdp_uuid128_cmp(u1, u2);
260168a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz
260268a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	bt_free(u1);
260368a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	bt_free(u2);
260468a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz
260568a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz	return ret;
260668a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz}
260768a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz
260868a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz/*
260968a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz * UUID comparison function
261068a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz * returns 0 if uuidValue1 == uuidValue2 else -1
261168a3563bf41199b4949f77251788faf62b697babLuiz Augusto von Dentz */
2612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid16_cmp(const void *p1, const void *p2)
2613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2614d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	const uuid_t *u1 = p1;
2615d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	const uuid_t *u2 = p2;
2616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t));
2617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function
2621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1
2622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_cmp(const void *p1, const void *p2)
2624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2625d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	const uuid_t *u1 = p1;
2626d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	const uuid_t *u2 = p2;
2627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t));
2628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 128 to 16 bit and 32 to 16 bit UUID conversion functions
2632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * yet to be implemented. Note that the input is in NBO in
2633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * both 32 and 128 bit UUIDs and conversion is needed
2634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2635bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmannvoid sdp_uuid16_to_uuid128(uuid_t *uuid128, const uuid_t *uuid16)
2636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	/*
2638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * We have a 16 bit value, which needs to be added to
2639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base
2640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 */
2641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned short data1;
2642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26438f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* allocate a 128bit UUID and init to the Bluetooth base UUID */
26443f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	uuid128->value.uuid128 = bluetooth_base_uuid;
2645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->type = SDP_UUID128;
2646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26478f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* extract bytes 2 and 3 of 128bit BT base UUID */
26483f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	memcpy(&data1, &bluetooth_base_uuid.data[2], 2);
2649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26508f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* add the given UUID (16 bits) */
2651542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data1 += htons(uuid16->value.uuid16);
2652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26538f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* set bytes 2 and 3 of the 128 bit value */
2654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&uuid128->value.uuid128.data[2], &data1, 2);
2655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2657bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmannvoid sdp_uuid32_to_uuid128(uuid_t *uuid128, const uuid_t *uuid32)
2658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	/*
2660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * We have a 32 bit value, which needs to be added to
2661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base
2662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	 */
2663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	unsigned int data0;
2664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26658f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* allocate a 128bit UUID and init to the Bluetooth base UUID */
26663f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	uuid128->value.uuid128 = bluetooth_base_uuid;
2667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid128->type = SDP_UUID128;
2668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26698f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* extract first 4 bytes */
26703f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	memcpy(&data0, &bluetooth_base_uuid.data[0], 4);
2671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26728f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* add the given UUID (32bits) */
2673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data0 += htonl(uuid32->value.uuid32);
2674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
26758f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* set the 4 bytes of the 128 bit value */
2676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&uuid128->value.uuid128.data[0], &data0, 4);
2677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2679bd3ebad37bedd9082f4123751c304ed97a7866fdMarcel Holtmannuuid_t *sdp_uuid_to_uuid128(const uuid_t *uuid)
2680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
268121f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	uuid_t *uuid128 = bt_malloc(sizeof(uuid_t));
2682114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2683114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!uuid128)
2684114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
2685114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
2686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memset(uuid128, 0, sizeof(uuid_t));
2687542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (uuid->type) {
2688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID128:
2689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*uuid128 = *uuid;
2690542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID32:
2692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid32_to_uuid128(uuid128, uuid);
2693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_UUID16:
2695542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_uuid16_to_uuid128(uuid128, uuid);
2696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return uuid128;
2699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
27018f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg/*
2702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * converts a 128-bit uuid to a 16/32-bit one if possible
2703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns true if uuid contains a 16/32-bit UUID at exit
2704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2705542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_to_uuid(uuid_t *uuid)
2706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
27073f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann	uint128_t *b = &bluetooth_base_uuid;
2708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint128_t *u = &uuid->value.uuid128;
2709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t data;
2710cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	unsigned int i;
2711a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (uuid->type != SDP_UUID128)
2713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return 1;
2714a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 4; i < sizeof(b->data); i++)
2716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (b->data[i] != u->data[i])
2717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			return 0;
2718a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann
2719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(&data, u->data, 4);
2720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	data = htonl(data);
2721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (data <= 0xffff) {
2722542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->type = SDP_UUID16;
27233f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann		uuid->value.uuid16 = (uint16_t) data;
2724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
2725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->type = SDP_UUID32;
2726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid->value.uuid32 = data;
2727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 1;
2729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * convert a UUID to the 16-bit short-form
2733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid_to_proto(uuid_t *uuid)
2735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid_t u = *uuid;
2737a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann	if (sdp_uuid128_to_uuid(&u)) {
2738a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		switch (u.type) {
2739a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		case SDP_UUID16:
2740a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann			return u.value.uuid16;
2741a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		case SDP_UUID32:
2742a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann			return u.value.uuid32;
2743a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann		}
2744a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann	}
2745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
2746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
27498f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg * This function appends data to the PDU buffer "dst" from source "src".
2750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The data length is also computed and set.
2751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Should the PDU length exceed 2^8, then sequence type is
2752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set accordingly and the data is memmove()'d.
2753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
2754cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannvoid sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len)
2755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2756cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *p = dst->data;
2757d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	uint8_t dtd = *p;
2758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Append src size: %d\n", len);
2760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Append dst size: %d\n", dst->data_size);
2761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Dst buffer size: %d\n", dst->buf_size);
2762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size == 0 && dtd == 0) {
27638f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		/* create initial sequence */
2764d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		*p = SDP_SEQ8;
2765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += sizeof(uint8_t);
27668f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		/* reserve space for sequence size */
2767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += sizeof(uint8_t);
2768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(dst->data + dst->data_size, data, len);
2771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dst->data_size += len;
2772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2773d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	dtd = *(uint8_t *) dst->data;
2774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) {
2775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		short offset = sizeof(uint8_t) + sizeof(uint8_t);
27768f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		memmove(dst->data + offset + 1, dst->data + offset,
27778f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg						dst->data_size - offset);
2778d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann		*p = SDP_SEQ16;
2779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		dst->data_size += 1;
2780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2781aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	dtd = *(uint8_t *) p;
2782542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint8_t);
2783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	switch (dtd) {
2784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ8:
2785aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t);
2786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ16:
2788aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *) p);
2789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	case SDP_SEQ32:
2791aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		bt_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *) p);
2792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		break;
2793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2796542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d)
2797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t append;
2799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2800997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann	memset(&append, 0, sizeof(sdp_buf_t));
28012db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_gen_buffer(&append, d);
28022db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	append.data = malloc(append.buf_size);
28032db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	if (!append.data)
28042db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		return;
2805997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann
2806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_set_attrid(&append, d->attrId);
2807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_gen_pdu(&append, d);
2808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_append_to_buf(pdu, append.data, append.data_size);
28092db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	free(append.data);
2810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Registers an sdp record.
2814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
2815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * It is incorrect to call this method on a record that
2816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * has been already registered with the server.
2817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
28188b11908eac4e0b4e14534ec2d44ae62806fdfd2fStephen Crane * Returns zero on success, otherwise -1 (and sets errno).
2819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
282082817924a25fb0eaaeb9824372106870c45c9db9Marcel 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)
2821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2822cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *req, *rsp, *p;
2823cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize, rspsize;
2824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
282582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int status;
2826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
2830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
2831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2833cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	req = malloc(SDP_REQ_BUFFER_SIZE);
2834cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rsp = malloc(SDP_RSP_BUFFER_SIZE);
2835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (req == NULL || rsp == NULL) {
2836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
284082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *)req;
2842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_REGISTER_REQ;
2843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2844542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t) + 1;
2845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = req + sizeof(sdp_pdu_hdr_t);
284682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2847fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann	if (bacmp(device, BDADDR_ANY)) {
2848fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		*p++ = flags | SDP_DEVICE_RECORD;
2849fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		bacpy((bdaddr_t *) p, device);
2850fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		p += sizeof(bdaddr_t);
28516db62cfa3a8de69270cc5e5689b633f43c02e041Marcel Holtmann		reqsize += sizeof(bdaddr_t);
2852fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann	} else
2853fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann		*p++ = flags;
285482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
285582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	memcpy(p, data, size);
285682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	reqsize += size;
2857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize);
2860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (status < 0)
2861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
286282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2863ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	if (rspsize < sizeof(sdp_pdu_hdr_t)) {
2864ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		SDPERR("Unexpected end of packet");
2865ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		errno = EPROTO;
2866ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		status = -1;
2867ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		goto end;
2868ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	}
2869ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann
2870aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	rsphdr = (sdp_pdu_hdr_t *) rsp;
2871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = rsp + sizeof(sdp_pdu_hdr_t);
287282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2873a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2874a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		/* Invalid service record */
2875a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EINVAL;
2876a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
2877a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	} else if (rsphdr->pdu_id != SDP_SVC_REGISTER_RSP) {
2878a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EPROTO;
2879a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
2880a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	} else {
2881ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint32_t)) {
2882ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann			SDPERR("Unexpected end of packet");
2883ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann			errno = EPROTO;
2884ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann			status = -1;
2885ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann			goto end;
2886ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		}
288782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		if (handle)
288882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann			*handle  = ntohl(bt_get_unaligned((uint32_t *) p));
2889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
289082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
2892a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(req);
2893a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rsp);
289482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
2896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
2897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
289882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags)
289982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{
290082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	sdp_buf_t pdu;
290182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	uint32_t handle;
290282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int err;
290382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
290482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	SDPDBG("");
290582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
290682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (rec->handle && rec->handle != 0xffffffff) {
290782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		uint32_t handle = rec->handle;
290882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
290982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
291082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	}
291182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
291282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
291382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		errno = ENOMEM;
291482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		return -1;
291582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	}
291682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
291782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	err = sdp_device_record_register_binary(session, device,
291882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann				pdu.data, pdu.data_size, flags, &handle);
291982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
292082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	free(pdu.data);
292182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
292282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (err == 0) {
292382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle);
292482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		rec->handle = handle;
292582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data);
292682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	}
292782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
292882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	return err;
292982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann}
293082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2931a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags)
2932a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
2933a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_register(session, BDADDR_ANY, rec, flags);
2934a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
2935a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
2936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
2937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * unregister a service record
2938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
293982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle)
2940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
2941cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf, *p;
2942cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, rspsize = 0;
2943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
294482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int status;
2945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
2947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (handle == SDP_SERVER_RECORD_HANDLE) {
2949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
2950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
295282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
2954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
2955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
2956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
295782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2958cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
2959cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
2960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
2961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
2962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
2963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
2964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
2965aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
2966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_REMOVE_REQ;
2967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
2968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p = reqbuf + sizeof(sdp_pdu_hdr_t);
2970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
2971aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) p);
2972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
2973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
2974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
2975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
2976a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (status < 0)
2977a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		goto end;
2978a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi
2979ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
2980ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		SDPERR("Unexpected end of packet");
2981ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		errno = EPROTO;
2982ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		status = -1;
2983ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		goto end;
2984ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	}
2985ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann
2986a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
2987a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	p = rspbuf + sizeof(sdp_pdu_hdr_t);
2988a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	status = bt_get_unaligned((uint16_t *) p);
298982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
2990a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
2991a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		/* For this case the status always is invalid record handle */
2992a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EINVAL;
2993a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
2994a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	} else if (rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) {
2995a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EPROTO;
2996a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
2997a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	}
2998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
2999a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
3000a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
300182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
3002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
3003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
300582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec)
300682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{
300782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int err;
300882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
300982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	err = sdp_device_record_unregister_binary(session, device, rec->handle);
301082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	if (err == 0)
301182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann		sdp_record_free(rec);
301282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
301382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	return err;
301482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann}
301582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
3016a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec)
3017a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
3018a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_unregister(session, BDADDR_ANY, rec);
3019a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
3020a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
3021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * modify an existing service record
3023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
302482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size)
302582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{
302682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	return -1;
302782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann}
302882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
3029a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec)
3030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3031cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf, *p;
3032cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize, rspsize;
3033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint32_t handle;
3035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t pdu;
303682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann	int status;
3037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
303982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann
3040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	handle = rec->handle;
3041542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (handle == SDP_SERVER_RECORD_HANDLE) {
3043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
3044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
3045542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!session->local) {
3047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EREMOTE;
3048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
3049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3050cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3051cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
3053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
3055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3057aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_UPDATE_REQ;
3059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->tid    = htons(sdp_gen_tid(session));
3060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3061cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	p = reqbuf + sizeof(sdp_pdu_hdr_t);
3062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
3063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3064aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) p);
3065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
3066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	p += sizeof(uint32_t);
3067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3068c5621bfbf9071ed359d904bdd91308f6599dc5e5Claudio Takahasi	if (sdp_gen_record_pdu(rec, &pdu) < 0) {
3069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
3071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(p, pdu.data, pdu.data_size);
3074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += pdu.data_size;
3075c5621bfbf9071ed359d904bdd91308f6599dc5e5Claudio Takahasi	free(pdu.data);
3076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3079a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (status < 0)
3080a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		goto end;
3081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3082ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) {
3083ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		SDPERR("Unexpected end of packet");
3084ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		errno = EPROTO;
3085ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		status = -1;
3086ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann		goto end;
3087ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann	}
3088ca0d3dc0bb5a573b44496847919cc02c9da2016fMarcel Holtmann
3089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Send req status : %d\n", status);
3090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3091a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3092a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	p = rspbuf + sizeof(sdp_pdu_hdr_t);
3093a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	status = bt_get_unaligned((uint16_t *) p);
3094a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi
3095a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3096a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		/* The status can be invalid sintax or invalid record handle */
3097a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EINVAL;
3098a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
3099a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi	} else if (rsphdr->pdu_id != SDP_SVC_UPDATE_RSP) {
3100a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		errno = EPROTO;
3101a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi		status = -1;
3102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend:
3104a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
3105a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
3106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
3107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3109a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_update(sdp_session_t *session, const sdp_record_t *rec)
3110a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{
3111a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann	return sdp_device_record_update(session, BDADDR_ANY, rec);
3112a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann}
3113a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann
31148af5f43a6988e8f9eb2df0d43decfde23a168980Szymon Jancsdp_record_t *sdp_record_alloc(void)
3115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
311621f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann	sdp_record_t *rec = malloc(sizeof(sdp_record_t));
3117114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
3118114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio	if (!rec)
3119114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio		return NULL;
3120114cb3f810dcc9361a31443a6c7361771a1d8481Santiago Carot-Nemesio
3121d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	memset(rec, 0, sizeof(sdp_record_t));
3122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rec->handle = 0xffffffff;
3123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
3124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Free the contents of a service record
3128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_free(sdp_record_t *rec)
3130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3131d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	sdp_list_free(rec->attrlist, (sdp_free_func_t) sdp_data_free);
3132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_free(rec->pattern, free);
3133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(rec);
3134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid)
3137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid);
3139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
3141d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	SDPDBG("Trying to add : 0x%lx\n", (unsigned long) uuid128);
3142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL)
3144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp);
3145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	else
314621f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann		bt_free(uuid128);
3147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern));
3149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq)
3152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (; seq; seq = seq->next) {
3154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		uuid_t *uuid = (uuid_t *)seq->data;
3155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		sdp_pattern_add_uuid(rec, uuid);
3156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract a sequence of service record handles from a PDU buffer
3161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * and add the entries to a sdp_list_t. Note that the service record
3162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * handles are not in "data element sequence" form, but just like
3163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * an array of service handles
3164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3165cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmannstatic void extract_record_handle_seq(uint8_t *pdu, int bufsize, sdp_list_t **seq, int count, unsigned int *scanned)
3166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *pSeq = *seq;
3168cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata = pdu;
3169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n;
3170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (n = 0; n < count; n++) {
317228cfb82c67c413cddff779a875cc7a40931b46a5Marcel Holtmann		uint32_t *pSvcRec;
3173cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		if (bufsize < (int) sizeof(uint32_t)) {
3174121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3175121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			break;
3176121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
317728cfb82c67c413cddff779a875cc7a40931b46a5Marcel Holtmann		pSvcRec = malloc(sizeof(uint32_t));
317828cfb82c67c413cddff779a875cc7a40931b46a5Marcel Holtmann		if (!pSvcRec)
317928cfb82c67c413cddff779a875cc7a40931b46a5Marcel Holtmann			break;
3180aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		*pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata));
3181542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pSeq = sdp_list_append(pSeq, pSvcRec);
3182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint32_t);
3183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		*scanned += sizeof(uint32_t);
3184121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		bufsize -= sizeof(uint32_t);
3185542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*seq = pSeq;
3187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Generate the attribute sequence pdu form
3190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * from sdp_list_t elements. Return length of attr seq
3191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3192cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd)
3193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_t *dataseq;
3195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	void **types, **values;
3196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t buf;
3197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int i, seqlen = sdp_list_len(seq);
3198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
31993d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* Fill up the value and the dtd arrays */
3200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("");
3201a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann
3202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Seq length : %d\n", seqlen);
3203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	types = malloc(seqlen * sizeof(void *));
3205135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	if (!types)
3206135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		return -ENOMEM;
3207135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz
3208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	values = malloc(seqlen * sizeof(void *));
3209f0081032066a6b246df58659aae38048a5952effLuiz Augusto von Dentz	if (!values) {
3210f0081032066a6b246df58659aae38048a5952effLuiz Augusto von Dentz		free(types);
3211135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		return -ENOMEM;
3212f0081032066a6b246df58659aae38048a5952effLuiz Augusto von Dentz	}
3213135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz
3214542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	for (i = 0; i < seqlen; i++) {
3215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		void *data = seq->data;
3216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		types[i] = &dtd;
3217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (SDP_IS_UUID(dtd))
3218542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			data = &((uuid_t *)data)->value;
3219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		values[i] = data;
3220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		seq = seq->next;
3221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3222542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	dataseq = sdp_seq_alloc(types, values, seqlen);
3224135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	if (!dataseq) {
3225135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		free(types);
3226135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		free(values);
3227135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		return -ENOMEM;
3228135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	}
3229135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz
32302db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	memset(&buf, 0, sizeof(sdp_buf_t));
32312db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	sdp_gen_buffer(&buf, dataseq);
32322db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz	buf.data = malloc(buf.buf_size);
32332db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
3234135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	if (!buf.data) {
3235135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		sdp_data_free(dataseq);
3236135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		free(types);
3237135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz		free(values);
32382db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz		return -ENOMEM;
3239135e87fb2fc2f8f9966e296e9fb8b921638c7453Luiz Augusto von Dentz	}
32402db52b2d09096c81be0ea0b1f72e3939382e5febLuiz Augusto von Dentz
3241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data Seq : 0x%p\n", seq);
3242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = sdp_gen_pdu(&buf, dataseq);
3243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Copying : %d\n", buf.data_size);
3244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	memcpy(dst, buf.data, buf.data_size);
3245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_data_free(dataseq);
3247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3248542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(types);
3249542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(values);
3250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(buf.data);
3251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return seqlen;
3252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3254cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq)
3255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3256d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	uuid_t *uuid = seq->data;
3257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return gen_dataseq_pdu(dst, seq, uuid->type);
3258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3260cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType)
3261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return gen_dataseq_pdu(dst, seq, dataType);
3263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3265113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmanntypedef struct {
3266113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann	uint8_t length;
3267113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann	unsigned char data[16];
3268113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann} __attribute__ ((packed)) sdp_cstate_t;
3269113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann
32700a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmannstatic int copy_cstate(uint8_t *pdata, int pdata_len, const sdp_cstate_t *cstate)
3271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (cstate) {
32730a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		uint8_t len = cstate->length;
32740a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		if (len >= pdata_len) {
32750a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann			SDPERR("Continuation state size exceeds internal buffer");
32760a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann			len = pdata_len - 1;
32770a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		}
32780a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		*pdata++ = len;
32790a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		memcpy(pdata, cstate->data, len);
32800a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		return len + 1;
3281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*pdata = 0;
3283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 1;
3284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3287400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio * This is a service search request.
3288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
3290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
329141064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim *   sdp_list_t *search
3292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing elements of the search
3293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
3294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     of the service to be searched
3295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   uint16_t max_rec_num
3297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      A 16 bit integer which tells the service, the maximum
3298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      entries that the client can handle in the response. The
3299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *      server is obliged not to return > max_rec_num entries
3300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
3302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   int return value
3304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
3305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       The request completed successfully. This does not
3306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       mean the requested services were found
3307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     -1:
3308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any failure and sets errno
3309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t **rsp_list
3311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     This variable is set on a successful return if there are
3312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     non-zero service handles. It is a singly linked list of
331328b4f0aea5b15ed7c0acd17ab79705a38ffe7c2fStephen Crane *     service record handles (uint16_t)
3314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search,
3316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			uint16_t max_rec_num, sdp_list_t **rsp)
3317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
3319cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
3320cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0, rsplen;
3321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0;
332261d0747e6c9289485ca5b33e2fd1874d1a9b27c5Szymon Janc	int rec_count;
3323cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	unsigned scanned, pdata_len;
3324cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
3325cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
3326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
3328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
3332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
3334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3336aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
3338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
3340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
33413d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add service class IDs for search */
3342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_searchseq_pdu(pdata, search);
3343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data seq added : %d\n", seqlen);
3345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
33463d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* set the length and increment the pointer */
3347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
3348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
3349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
33503d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* specify the maximum svc rec count that client expects */
3351aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
3352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
3353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
3354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
3356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata   = pdata;
3357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rsp = NULL;
3358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
33603d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* Add continuation state or NULL (first time) */
33610a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata,
33620a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
3363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
33643d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* Set the request header's param length */
3365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid  = htons(sdp_gen_tid(session));
3368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
3369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Send the request, wait for response and if
3370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * no error, set the appropriate values and return
3371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0)
3374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3376121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
3377121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3378121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
3379121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3380121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3381121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3382aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		rsplen = ntohs(rsphdr->plen);
3384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
3387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
3388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned = 0;
3391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3392121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
3393121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3394121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < sizeof(uint16_t) + sizeof(uint16_t)) {
3395121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3396121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
3397121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3398121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
34003d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* net service record match count */
3401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
3402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
3403121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len -= sizeof(uint16_t);
3404aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
3406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		scanned += sizeof(uint16_t);
3407121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len -= sizeof(uint16_t);
3408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Total svc count: %d\n", total_rec_count);
3410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Current svc count: %d\n", rec_count);
3411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("ResponseLength: %d\n", rsplen);
3412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (!rec_count) {
3414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
3415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3417121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		extract_record_handle_seq(pdata, pdata_len, rsp, rec_count, &scanned);
3418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("BytesScanned : %d\n", scanned);
3419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsplen > scanned) {
3421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			uint8_t cstate_len;
3422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3423121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			if (rspsize < sizeof(sdp_pdu_hdr_t) + scanned + sizeof(uint8_t)) {
3424121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann				SDPERR("Unexpected end of packet: continuation state data missing");
3425121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann				status = -1;
3426121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann				goto end;
3427121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			}
3428121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3429542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned;
3430aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate_len = *(uint8_t *) pdata;
3431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			if (cstate_len > 0) {
3432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				cstate = (sdp_cstate_t *)pdata;
3433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Cont state length: %d\n", cstate_len);
3434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			} else
3435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				cstate = NULL;
3436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
3438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3439a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannend:
3440a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
3441a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
3442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
3444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
3447400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio * This is a service attribute request.
3448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
3450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   uint32_t handle
3452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     The handle of the service for which the attribute(s) are
3453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     requested
3454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_attrreq_type_t reqtype
3456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
3457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     in one of 2 ways described below :
3458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        They are the actual attribute identifiers in ascending order
3460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        The high-order 16bits is the start of range
3463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        the low-order 16bits are the end of range
3464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        0x0000 to 0xFFFF gets all attributes
3465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *attrid
3467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing attribute identifiers desired.
3468400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
3471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
3472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   return sdp_record_t *
3473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
3474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any error and sets errno
3475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     !0:
3476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *	 The service record
3477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
3478400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesiosdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle,
3479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			sdp_attrreq_type_t reqtype, const sdp_list_t *attrids)
3480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
3481cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
3482cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0, rsp_count;
3483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int attr_list_len = 0;
3484cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	int seqlen = 0;
3485cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	unsigned int pdata_len;
3486cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
3487cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
3488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
3489542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
3490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t cstate_len = 0;
3491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t rsp_concat_buf;
3492542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_record_t *rec = 0;
3493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3494542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
3495542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
3496f58df2db7a606fcd13a36824bdb4fc3440d9a71eSantiago Carot-Nemesio		return NULL;
3497542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
34998232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg	memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));
35008232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg
3501cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
3502cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
3503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
3504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
3505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3507aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
3508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
3509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
3511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
3512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35133d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add the service record handle */
3514aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
3515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint32_t);
3516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint32_t);
3517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35183d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* specify the response limit */
3519aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
3520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
3521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
3522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35233d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* get attr seq PDU form */
3524400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio	seqlen = gen_attridseq_pdu(pdata, attrids,
3525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seqlen == -1) {
3527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
3528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
3529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
3531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
3532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Attr list length : %d\n", seqlen);
3533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35343d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* save before Continuation State */
3535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata = pdata;
3536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
3537542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3538542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
35395e1f7cb4d8abc2c352d7ee055795cca837523b53Luiz Augusto von Dentz		int status;
35405e1f7cb4d8abc2c352d7ee055795cca837523b53Luiz Augusto von Dentz
35413d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* add NULL continuation state */
35420a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata,
35430a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
3544542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35453d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* set the request header's param length */
3546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid  = htons(sdp_gen_tid(session));
3547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
3548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
3550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0)
3551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3552121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3553121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
3554121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3555121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3556121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3557121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3558aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
3559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
3560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id);
3561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
3562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
3564121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
3565121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3566121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < sizeof(uint16_t)) {
3567121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
3568121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3569121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3570121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
3571aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
3572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		attr_list_len += rsp_count;
3573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata += sizeof(uint16_t);
3574121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len -= sizeof(uint16_t);
3575542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35763d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/*
35773d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		 * if continuation state set need to re-issue request before
35783d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		 * parsing
35793d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		 */
3580121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < rsp_count + sizeof(uint8_t)) {
3581121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet: continuation state data missing");
3582121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
3583121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3584aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		cstate_len = *(uint8_t *) (pdata + rsp_count);
3585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Response id : %d\n", rsphdr->pdu_id);
3587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attrlist byte count : %d\n", rsp_count);
3588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("sdp_cstate_t length : %d\n", cstate_len);
3589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
3591400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio		 * a split response: concatenate intermediate responses
3592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * and the last one (which has cstate_len == 0)
3593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
3594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
3595cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			uint8_t *targetPtr = NULL;
3596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3597aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
3598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
35993d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc			/* build concatenated response buffer */
3600cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
3601542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
3602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
3603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(targetPtr, pdata, rsp_count);
3604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.data_size += rsp_count;
3605542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
3606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
3607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (attr_list_len > 0) {
3609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int scanned = 0;
3610121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rsp_concat_buf.data_size != 0) {
3611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rsp_concat_buf.data;
3612121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			pdata_len = rsp_concat_buf.data_size;
3613121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
3614d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann		rec = sdp_extract_pdu(pdata, pdata_len, &scanned);
3615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
3616400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio
3617a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannend:
3618a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
3619a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rsp_concat_buf.data);
3620a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
3621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return rec;
3622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
3623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
3624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
36258be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * SDP transaction structure for asynchronous search
36268be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */
36278be090b298a02108146d3bf48271f8408ac31917Claudio Takahasistruct sdp_transaction {
3628c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	sdp_callback_t *cb;	/* called when the transaction finishes */
3629c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	void *udata;		/* client user data */
3630c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	uint8_t *reqbuf;	/* pointer to request PDU */
36318be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	sdp_buf_t rsp_concat_buf;
3632c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	uint32_t reqsize;	/* without cstate */
36335ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	int err;		/* ZERO if success or the errno if failed */
36348be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi};
36358be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36368be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/*
36378be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * Creates a new sdp session for asynchronous search
36388be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * INPUT:
36398be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  int sk
36401be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim *     non-blocking L2CAP socket
36411be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim *
36428be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * RETURN:
36438be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  sdp_session_t *
36448be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi *  NULL - On memory allocation failure
36458be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */
36468be090b298a02108146d3bf48271f8408ac31917Claudio Takahasisdp_session_t *sdp_create(int sk, uint32_t flags)
36478be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi{
3648a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	sdp_session_t *session;
36498be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	struct sdp_transaction *t;
3650a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
3651a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	session = malloc(sizeof(sdp_session_t));
36528be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!session) {
36538be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		errno = ENOMEM;
36548be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return NULL;
36558be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
36568be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	memset(session, 0, sizeof(*session));
36578be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36588be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->flags = flags;
36598be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->sock = sk;
36608be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36618be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	t = malloc(sizeof(struct sdp_transaction));
36628be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!t) {
36638be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		errno = ENOMEM;
36648be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		free(session);
36658be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return NULL;
36668be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
36678be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	memset(t, 0, sizeof(*t));
36688be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36698be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	session->priv = t;
36708be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36718be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	return session;
36728be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi}
36738be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
36748be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/*
3675adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Sets the callback function/user data used to notify the application
3676adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * that the asynchronous transaction finished. This function must be
3677adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called before request an asynchronous search.
3678dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *
3679dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * INPUT:
3680dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  sdp_session_t *session
3681dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *	Current sdp session to be handled
3682dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  sdp_callback_t *cb
3683dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *      callback to be called when the transaction finishes
3684dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *  void *udata
3685dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann *      user data passed to callback
3686dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * RETURN:
3687adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	 0 - Success
3688dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * 	-1 - Failure
3689dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann */
3690dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmannint sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata)
3691dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann{
3692dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	struct sdp_transaction *t;
3693dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3694dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	if (!session || !session->priv)
3695dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann		return -1;
3696dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3697dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t = session->priv;
3698dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t->cb = func;
3699dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	t->udata = udata;
3700dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3701dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann	return 0;
3702dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann}
3703dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann
3704adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi/*
3705adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service search request.
3706400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio * The incomming and outgoing data are stored in the transaction structure
3707adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * buffers. When there is incomming data the sdp_process function must be
3708adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called to get the data and handle the continuation state.
3709adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3710adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * INPUT :
3711adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *  sdp_session_t *session
3712adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Current sdp session to be handled
3713adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
371441064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim *   sdp_list_t *search
3715adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Singly linked list containing elements of the search
3716adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16)
3717adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     of the service to be searched
3718adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3719adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   uint16_t max_rec_num
3720adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *      A 16 bit integer which tells the service, the maximum
3721adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *      entries that the client can handle in the response. The
3722adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *      server is obliged not to return > max_rec_num entries
3723adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3724adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * OUTPUT :
3725adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3726adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   int return value
3727adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	0  - if the request has been sent properly
3728adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	-1 - On any failure and sets errno
3729adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi */
3730adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi
373141064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquimint sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num)
3732453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{
3733e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	struct sdp_transaction *t;
3734e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3735e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	uint8_t *pdata;
3736c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	int cstate_len, seqlen = 0;
3737e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
373812f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi	if (!session || !session->priv)
3739e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi		return -1;
3740e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3741e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t = session->priv;
374218a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3743a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	/* clean possible allocated buffer */
3744a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->rsp_concat_buf.data);
374518a82a6fce76be0883a431380495510010515fffClaudio Takahasi	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
374618a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3747e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	if (!t->reqbuf) {
374818a82a6fce76be0883a431380495510010515fffClaudio Takahasi		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
374918a82a6fce76be0883a431380495510010515fffClaudio Takahasi		if (!t->reqbuf) {
375018a82a6fce76be0883a431380495510010515fffClaudio Takahasi			t->err = ENOMEM;
375118a82a6fce76be0883a431380495510010515fffClaudio Takahasi			goto end;
375218a82a6fce76be0883a431380495510010515fffClaudio Takahasi		}
3753e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	}
3754e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3755e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3756e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3757e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3758e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	reqhdr->pdu_id = SDP_SVC_SEARCH_REQ;
3759e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
37603d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* generate PDU */
3761e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3762e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3763e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
37643d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add service class IDs for search */
376541064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim	seqlen = gen_searchseq_pdu(pdata, search);
3766e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3767e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	SDPDBG("Data seq added : %d\n", seqlen);
3768e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
37693d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* now set the length and increment the pointer */
3770e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t->reqsize += seqlen;
3771e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	pdata += seqlen;
3772e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3773e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata);
3774e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	t->reqsize += sizeof(uint16_t);
3775e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	pdata += sizeof(uint16_t);
3776e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
37773d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* set the request header's param length */
37780a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
3779c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3780e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3781c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3782e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
378312f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = errno;
3784e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi		goto end;
3785e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	}
3786e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3787453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	return 0;
3788e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasiend:
3789e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3790a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->reqbuf);
3791a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	t->reqbuf = NULL;
3792e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi
3793e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi	return -1;
3794453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann}
3795453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3796adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi/*
3797adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service attribute request.
3798400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio * The incomming and outgoing data are stored in the transaction structure
3799adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * buffers. When there is incomming data the sdp_process function must be
3800adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called to get the data and handle the continuation state.
3801adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3802adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * INPUT :
3803adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *  sdp_session_t *session
3804adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *	Current sdp session to be handled
3805adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3806adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   uint32_t handle
3807adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     The handle of the service for which the attribute(s) are
3808adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     requested
3809adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3810adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   sdp_attrreq_type_t reqtype
3811adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Attribute identifiers are 16 bit unsigned integers specified
3812adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     in one of 2 ways described below :
3813adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3814adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        They are the actual attribute identifiers in ascending order
3815adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3816adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3817adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        The high-order 16bits is the start of range
3818adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        the low-order 16bits are the end of range
3819adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *        0x0000 to 0xFFFF gets all attributes
3820adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3821adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   sdp_list_t *attrid_list
3822adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     Singly linked list containing attribute identifiers desired.
3823400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3824adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3825adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *
3826adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * OUTPUT :
3827adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   int return value
3828adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	 0 - if the request has been sent properly
3829adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	-1 - On any failure and sets errno
3830adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi */
3831adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi
3832453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmannint sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list)
3833453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{
3834ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	struct sdp_transaction *t;
3835ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3836ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	uint8_t *pdata;
3837c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	int cstate_len, seqlen = 0;
3838ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
383912f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi	if (!session || !session->priv)
3840ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		return -1;
3841ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3842ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t = session->priv;
384318a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3844a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	/* clean possible allocated buffer */
3845a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->rsp_concat_buf.data);
384618a82a6fce76be0883a431380495510010515fffClaudio Takahasi	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
384718a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3848ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	if (!t->reqbuf) {
384918a82a6fce76be0883a431380495510010515fffClaudio Takahasi		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
385018a82a6fce76be0883a431380495510010515fffClaudio Takahasi		if (!t->reqbuf) {
385118a82a6fce76be0883a431380495510010515fffClaudio Takahasi			t->err = ENOMEM;
385218a82a6fce76be0883a431380495510010515fffClaudio Takahasi			goto end;
385318a82a6fce76be0883a431380495510010515fffClaudio Takahasi		}
3854ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3855ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3856ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3857ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3858ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3859ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	reqhdr->pdu_id = SDP_SVC_ATTR_REQ;
3860ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38613d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* generate PDU */
3862ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3863ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3864ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38653d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add the service record handle */
3866ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	bt_put_unaligned(htonl(handle), (uint32_t *) pdata);
3867ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize += sizeof(uint32_t);
3868ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata += sizeof(uint32_t);
3869ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38703d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* specify the response limit */
3871ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	bt_put_unaligned(htons(65535), (uint16_t *) pdata);
3872ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize += sizeof(uint16_t);
3873ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata += sizeof(uint16_t);
3874ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38753d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* get attr seq PDU form */
3876ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	seqlen = gen_attridseq_pdu(pdata, attrid_list,
3877ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi			reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32);
3878ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	if (seqlen == -1) {
387912f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = EINVAL;
3880ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		goto end;
3881ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3882ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38833d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* now set the length and increment the pointer */
3884ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	t->reqsize += seqlen;
3885ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	pdata += seqlen;
3886ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	SDPDBG("Attr list length : %d\n", seqlen);
3887ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
38883d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* set the request header's param length */
38890a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
3890c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
3891ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3892c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
3893ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
389412f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = errno;
3895ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi		goto end;
3896ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	}
3897ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3898453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	return 0;
3899ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasiend:
3900ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3901a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->reqbuf);
3902a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	t->reqbuf = NULL;
3903ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi
3904ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi	return -1;
3905453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann}
3906453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3907dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann/*
3908adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service search attributes.
3909adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * It is a service search request combined with attribute request. The incomming
3910adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * and outgoing data are stored in the transaction structure buffers. When there
3911adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * is incomming data the sdp_process function must be called to get the data
3912adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * and handle the continuation state.
3913f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *
3914f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT:
3915f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *  sdp_session_t *session
3916f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *	Current sdp session to be handled
3917453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3918453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *   sdp_list_t *search
3919453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Singly linked list containing elements of the search
3920453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
3921453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     of the service to be searched
3922453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3923453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *   AttributeSpecification attrSpec
3924453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
3925453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     in one of 2 ways described below :
3926453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
3927453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        They are the actual attribute identifiers in ascending order
3928453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3929453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
3930453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        The high-order 16bits is the start of range
3931453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        the low-order 16bits are the end of range
3932453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *        0x0000 to 0xFFFF gets all attributes
3933453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3934adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi *   sdp_list_t *attrid_list
3935453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     Singly linked list containing attribute identifiers desired.
3936400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
3937453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
3938453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann *
3939453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann
3940f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN:
3941adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 	 0 - if the request has been sent properly
3942f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	-1 - On any failure
3943f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */
394441064d605ba2f88f967c8388c9b20b92a7868a87Ulisses 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)
3945f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{
3946f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	struct sdp_transaction *t;
3947f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	sdp_pdu_hdr_t *reqhdr;
3948f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	uint8_t *pdata;
3949c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	int cstate_len, seqlen = 0;
3950f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
395112f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi	if (!session || !session->priv)
3952f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		return -1;
3953f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3954f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t = session->priv;
395518a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3956a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	/* clean possible allocated buffer */
3957a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->rsp_concat_buf.data);
395818a82a6fce76be0883a431380495510010515fffClaudio Takahasi	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
395918a82a6fce76be0883a431380495510010515fffClaudio Takahasi
3960f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (!t->reqbuf) {
396118a82a6fce76be0883a431380495510010515fffClaudio Takahasi		t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
396218a82a6fce76be0883a431380495510010515fffClaudio Takahasi		if (!t->reqbuf) {
396318a82a6fce76be0883a431380495510010515fffClaudio Takahasi			t->err = ENOMEM;
396418a82a6fce76be0883a431380495510010515fffClaudio Takahasi			goto end;
396518a82a6fce76be0883a431380495510010515fffClaudio Takahasi		}
3966f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3967f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE);
3968f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3969f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *) t->reqbuf;
3970f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr->tid = htons(sdp_gen_tid(session));
3971f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
3972f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
39733d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* generate PDU */
3974f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t);
3975f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize = sizeof(sdp_pdu_hdr_t);
3976f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
39773d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add service class IDs for search */
397841064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim	seqlen = gen_searchseq_pdu(pdata, search);
3979f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3980f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Data seq added : %d\n", seqlen);
3981f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
39823d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* now set the length and increment the pointer */
3983f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += seqlen;
3984f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += seqlen;
3985f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3986f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
3987f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += sizeof(uint16_t);
3988f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += sizeof(uint16_t);
3989f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
3990f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
3991f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
39923d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* get attr seq PDU form */
3993453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrid_list,
3994453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann			reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
3995f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (seqlen == -1) {
399612f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = EINVAL;
3997f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
3998f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
3999f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4000f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	pdata += seqlen;
4001f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	SDPDBG("Attr list length : %d\n", seqlen);
4002f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t->reqsize += seqlen;
4003f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
40043d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* set the request header's param length */
40050a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann	cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL);
4006c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t));
4007f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4008c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) {
4009f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		SDPERR("Error sendind data:%s", strerror(errno));
401012f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi		t->err = errno;
4011f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
4012f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
4013f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4014f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	return 0;
4015f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend:
4016f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4017a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(t->reqbuf);
4018a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	t->reqbuf = NULL;
4019f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4020f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	return -1;
4021f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi}
4022f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4023f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/*
40245ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * Function used to get the error reason after sdp_callback_t function has been called
402512f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1.
402612f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly
402712f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * is not safe because multiple transactions can be triggered.
40285ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * This function must be used with asynchronous sdp functions only.
40295ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *
40305ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * INPUT:
40315ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *  sdp_session_t *session
40325ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *	Current sdp session to be handled
40335ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * RETURN:
40345ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 	 0 = No error in the current transaction
40355ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 	-1 - if the session is invalid
40365ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 	positive value - the errno value
40375ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi *
40385ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi */
40395ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasiint sdp_get_error(sdp_session_t *session)
40405ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi{
40415ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	struct sdp_transaction *t;
40425ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
40435ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	if (!session || !session->priv) {
40445ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Invalid session");
40455ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		return -1;
40465ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	}
40475ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
40485ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	t = session->priv;
40495ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
40505ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	return t->err;
40515ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi}
40525ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi
40535ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi/*
4054f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * Receive the incomming SDP PDU. This function must be called when there is data
4055f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * available to be read. On continuation state, the original request (with a new
4056f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * transaction ID) and the continuation state data will be appended in the initial PDU.
4057f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * If an error happens or the transaction finishes the callback function will be called.
4058f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *
4059f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT:
4060f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *  sdp_session_t *session
4061f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi *	Current sdp session to be handled
4062f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN:
4063f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	0  - if the transaction is on continuation state
4064f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 	-1 - On any failure or the transaction finished
4065f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */
4066f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiint sdp_process(sdp_session_t *session)
4067f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{
40685ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	struct sdp_transaction *t;
40695ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	sdp_pdu_hdr_t *reqhdr, *rsphdr;
40705ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	sdp_cstate_t *pcstate;
40715ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	uint8_t *pdata, *rspbuf, *targetPtr;
40725ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	int rsp_count, err = -1;
4073c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann	size_t size = 0;
40749203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	int n, plen;
40755ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	uint16_t status = 0xffff;
40765ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	uint8_t pdu_id = 0x00;
4077f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4078f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	if (!session || !session->priv) {
4079c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		SDPERR("Invalid session");
4080c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		return -1;
4081f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
4082f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4083f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
40845ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	if (!rspbuf) {
40855ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Response buffer alloc failure:%s (%d)",
40865ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi				strerror(errno), errno);
4087c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		return -1;
40885ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	}
4089c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi
4090c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE);
4091f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4092f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	t = session->priv;
4093f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	reqhdr = (sdp_pdu_hdr_t *)t->reqbuf;
4094f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	rsphdr = (sdp_pdu_hdr_t *)rspbuf;
4095f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
40965ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
4097f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
40989203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE);
40999203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	if (n < 0) {
41005ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Read response:%s (%d)", strerror(errno), errno);
41015ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		t->err = errno;
4102f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		goto end;
41035ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	}
4104f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
41059203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	if (n == 0 || reqhdr->tid != rsphdr->tid ||
4106cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann		(n != (ntohs(rsphdr->plen) + (int) sizeof(sdp_pdu_hdr_t)))) {
41075ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		t->err = EPROTO;
41089203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPERR("Protocol error.");
4109343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi		goto end;
4110343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi	}
4111343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi
41125ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	pdu_id = rsphdr->pdu_id;
411358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	switch (rsphdr->pdu_id) {
411458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	uint8_t *ssr_pdata;
411558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	uint16_t tsrc, csrc;
411658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	case SDP_SVC_SEARCH_RSP:
411758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		/*
41189203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * TSRC: Total Service Record Count (2 bytes)
41199203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * CSRC: Current Service Record Count (2 bytes)
412058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		 */
412158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		ssr_pdata = pdata;
412258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));
41239203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		ssr_pdata += sizeof(uint16_t);
412458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata));
412558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi
41269203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		/* csrc should never be larger than tsrc */
41279203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		if (csrc > tsrc) {
41289203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi			t->err = EPROTO;
41299203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi			SDPERR("Protocol error: wrong current service record count value.");
41309203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi			goto end;
41319203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		}
41329203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
41339203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPDBG("Total svc count: %d\n", tsrc);
41349203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPDBG("Current svc count: %d\n", csrc);
41359203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
41369203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		/* parameter length without continuation state */
41379203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
41389203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
4139c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann		if (t->rsp_concat_buf.data_size == 0) {
414058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi			/* first fragment */
414158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi			rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
414258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		} else {
4143e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			/* point to the first csrc */
4144e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			uint16_t *pcsrc = (uint16_t *) (t->rsp_concat_buf.data + 2);
4145e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
4146e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			/* FIXME: update the interface later. csrc doesn't need be passed to clients */
4147e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
4148e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			pdata += sizeof(uint16_t); /* point to csrc */
4149e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
4150e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			/* the first csrc contains the sum of partial csrc responses */
4151400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio			*pcsrc += bt_get_unaligned((uint16_t *) pdata);
4152e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi
4153e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi			pdata += sizeof(uint16_t); /* point to the first handle */
415458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi			rsp_count = csrc * 4;
415558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		}
41565ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		status = 0x0000;
415758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		break;
415858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	case SDP_SVC_ATTR_RSP:
415958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	case SDP_SVC_SEARCH_ATTR_RSP:
416058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
416158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		SDPDBG("Attrlist byte count : %d\n", rsp_count);
4162400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio
4163400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio		/*
41649203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * Number of bytes in the AttributeLists parameter(without
41659203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 * continuation state) + AttributeListsByteCount field size.
41669203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		 */
41679203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		plen = sizeof(uint16_t) + rsp_count;
4168f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
41693d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		pdata += sizeof(uint16_t); /* points to attribute list */
41705ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		status = 0x0000;
417158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		break;
41725ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	case SDP_ERROR_RSP:
41735ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		status = ntohs(bt_get_unaligned((uint16_t *) pdata));
41749203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		size = ntohs(rsphdr->plen);
41759203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
41765ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		goto end;
417758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	default:
41785ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		t->err = EPROTO;
41795ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi		SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id);
418058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		goto end;
418158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	}
4182f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
418358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	pcstate = (sdp_cstate_t *) (pdata + rsp_count);
418458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi
418558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	SDPDBG("Cstate length : %d\n", pcstate->length);
41869203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
4187400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio	/*
41889203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	 * Check out of bound. Continuation state must have at least
41899203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	 * 1 byte: ZERO to indicate that it is not a partial response.
41909203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	 */
4191cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	if ((n - (int) sizeof(sdp_pdu_hdr_t))  != (plen + pcstate->length + 1)) {
41929203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		t->err = EPROTO;
41939203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		SDPERR("Protocol error: wrong PDU size.");
41949203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		status = 0xffff;
41959203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi		goto end;
41969203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi	}
41979203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi
4198f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	/*
4199f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	 * This is a split response, need to concatenate intermediate
42005ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi	 * responses and the last one which will have cstate length == 0
4201f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	 */
420258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count);
420358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size;
420458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count;
420558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	memcpy(targetPtr, pdata, rsp_count);
420658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	t->rsp_concat_buf.data_size += rsp_count;
420758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi
420858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi	if (pcstate->length > 0) {
420958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		int reqsize, cstate_len;
4210f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4211f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		reqhdr->tid = htons(sdp_gen_tid(session));
4212f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
42133d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* add continuation state */
42140a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		cstate_len = copy_cstate(t->reqbuf + t->reqsize,
42150a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann				SDP_REQ_BUFFER_SIZE - t->reqsize, pcstate);
4216f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
421758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi		reqsize = t->reqsize + cstate_len;
4218f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
42193d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		/* set the request header's param length */
4220f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
4221400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio
4222f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (sdp_send_req(session, t->reqbuf, reqsize) < 0) {
42235ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			SDPERR("Error sendind data:%s(%d)", strerror(errno), errno);
42245ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			status = 0xffff;
42255ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			t->err = errno;
4226f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi			goto end;
4227f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		}
4228c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi		err = 0;
4229f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
4230f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4231f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend:
4232c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	if (err) {
4233c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann		if (t->rsp_concat_buf.data_size != 0) {
4234f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi			pdata = t->rsp_concat_buf.data;
4235c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann			size = t->rsp_concat_buf.data_size;
4236c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann		}
4237f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi		if (t->cb)
42385ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi			t->cb(pdu_id, status, pdata, size, t->udata);
4239f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi	}
4240f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4241a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
4242f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4243c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi	return err;
4244f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi}
4245f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi
4246f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/*
4247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service search request combined with the service
4248542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attribute request. First a service class match is done and
4249542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * for matching service, requested attributes are extracted
4250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT :
4252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *search
4254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing elements of the search
4255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16)
4256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     of the service to be searched
4257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   AttributeSpecification attrSpec
4259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Attribute identifiers are 16 bit unsigned integers specified
4260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     in one of 2 ways described below :
4261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers
4262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        They are the actual attribute identifiers in ascending order
4263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     SDP_ATTR_REQ_RANGE - 32bit identifier range
4265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        The high-order 16bits is the start of range
4266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        the low-order 16bits are the end of range
4267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *        0x0000 to 0xFFFF gets all attributes
4268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t *attrids
4270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     Singly linked list containing attribute identifiers desired.
4271400772d67b5861e8dbc8aaeb0aa697e5facb97d7Santiago Carot-Nemesio *     Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL)
4272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE)
4273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT :
4275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   int return value
4276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     0:
4277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       The request completed successfully. This does not
4278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       mean the requested services were found
4279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     -1:
4280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *       On any error and sets errno
4281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *
4282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *   sdp_list_t **rsp
4283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     This variable is set on a successful return to point to
4284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     service(s) found. Each element of this list is of type
4285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *     sdp_record_t* (of the services which matched the search list)
4286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
4287542fc57346fbb329934152f446f58cc61a5d5d00Marcel 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)
4288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
4289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int status = 0;
4290cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t reqsize = 0, _reqsize;
4291cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint32_t rspsize = 0;
4292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int seqlen = 0, attr_list_len = 0;
4293cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	int rsp_count = 0, cstate_len = 0;
4294cb0b4b761c43394bd9c4e735455d5a5e479198f9Marcel Holtmann	unsigned int pdata_len;
4295cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *pdata, *_pdata;
4296cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	uint8_t *reqbuf, *rspbuf;
4297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_pdu_hdr_t *reqhdr, *rsphdr;
4298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	uint8_t dataType;
4299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_list_t *rec_list = NULL;
4300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_buf_t rsp_concat_buf;
4301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	sdp_cstate_t *cstate = NULL;
4302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) {
4304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = EINVAL;
4305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
4306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
43078232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg
43088232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg	memset(&rsp_concat_buf, 0, sizeof(sdp_buf_t));
43098232558057813074ce6bdb3317a9fb4888f7b8e3Johan Hedberg
4310cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	reqbuf = malloc(SDP_REQ_BUFFER_SIZE);
4311cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann	rspbuf = malloc(SDP_RSP_BUFFER_SIZE);
4312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (!reqbuf || !rspbuf) {
4313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		errno = ENOMEM;
4314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = -1;
4315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
4316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
4317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4318aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	reqhdr = (sdp_pdu_hdr_t *) reqbuf;
4319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ;
4320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43213d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* generate PDU */
4322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata = reqbuf + sizeof(sdp_pdu_hdr_t);
4323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize = sizeof(sdp_pdu_hdr_t);
4324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43253d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc	/* add service class IDs for search */
4326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_searchseq_pdu(pdata, search);
4327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Data seq added : %d\n", seqlen);
4329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43308f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* now set the length and increment the pointer */
4331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
4332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
4333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4334aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann	bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata);
4335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += sizeof(uint16_t);
4336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += sizeof(uint16_t);
4337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN);
4339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43408f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* get attr seq PDU form */
4341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	seqlen = gen_attridseq_pdu(pdata, attrids,
4342aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32);
4343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (seqlen == -1) {
4344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = EINVAL;
4345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		goto end;
4346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
4347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	pdata += seqlen;
4348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	SDPDBG("Attr list length : %d\n", seqlen);
4349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	reqsize += seqlen;
4350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*rsp = 0;
4351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43528f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg	/* save before Continuation State */
4353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_pdata = pdata;
4354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	_reqsize = reqsize;
4355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	do {
4357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->tid = htons(sdp_gen_tid(session));
4358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43598f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		/* add continuation state (can be null) */
43600a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann		reqsize = _reqsize + copy_cstate(_pdata,
43610a8f7c9206e17ab118966bf7da8a053ef34dce84Marcel Holtmann					SDP_REQ_BUFFER_SIZE - _reqsize, cstate);
4362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
43638f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		/* set the request header's param length */
4364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t));
4365aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsphdr = (sdp_pdu_hdr_t *) rspbuf;
4366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize);
4367121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rspsize < sizeof(sdp_pdu_hdr_t)) {
4368121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
4369121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
4370121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
4371121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
4372121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (status < 0) {
4374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Status : 0x%x\n", rsphdr->pdu_id);
4375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
4376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
43778f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg
4378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (rsphdr->pdu_id == SDP_ERROR_RSP) {
4379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			status = -1;
4380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			goto end;
4381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
43828f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg
4383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		pdata = rspbuf + sizeof(sdp_pdu_hdr_t);
4384121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len = rspsize - sizeof(sdp_pdu_hdr_t);
4385121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4386121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < sizeof(uint16_t)) {
4387121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet");
4388121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
4389121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
4390121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
4391121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4392aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata));
4393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		attr_list_len += rsp_count;
43943d586da1dd17ca73a4bd4a5cad9284a331860042Szymon Janc		pdata += sizeof(uint16_t); /* pdata points to attribute list */
4395121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		pdata_len -= sizeof(uint16_t);
4396121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4397121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (pdata_len < rsp_count + sizeof(uint8_t)) {
4398121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			SDPERR("Unexpected end of packet: continuation state data missing");
4399121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			status = -1;
4400121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			goto end;
4401121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
4402121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann
4403aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann		cstate_len = *(uint8_t *) (pdata + rsp_count);
4404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Attrlist byte count : %d\n", attr_list_len);
4406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Response byte count : %d\n", rsp_count);
4407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Cstate length : %d\n", cstate_len);
4408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
4409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * This is a split response, need to concatenate intermediate
4410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * responses and the last one which will have cstate_len == 0
4411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
4412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (cstate_len > 0 || rsp_concat_buf.data_size != 0) {
4413cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			uint8_t *targetPtr = NULL;
4414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4415aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann			cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0;
4416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
44178f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg			/* build concatenated response buffer */
4418cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann			rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count);
4419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size;
4420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count;
4421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			memcpy(targetPtr, pdata, rsp_count);
4422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			rsp_concat_buf.data_size += rsp_count;
4423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
4424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} while (cstate);
4425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (attr_list_len > 0) {
4427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		int scanned = 0;
4428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4429121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		if (rsp_concat_buf.data_size != 0) {
4430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata = rsp_concat_buf.data;
4431121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			pdata_len = rsp_concat_buf.data_size;
4432121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann		}
4433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		/*
4435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * Response is a sequence of sequence(s) for one or
4436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * more data element sequence(s) representing services
4437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 * for which attributes are returned
4438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		 */
4439d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann		scanned = sdp_extract_seqtype(pdata, pdata_len, &dataType, &seqlen);
4440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Bytes scanned : %d\n", scanned);
4442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPDBG("Seq length : %d\n", seqlen);
4443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		if (scanned && seqlen) {
4445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			pdata += scanned;
4446121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			pdata_len -= scanned;
4447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			do {
4448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				int recsize = 0;
4449d39e08cc5483dc924f3b764b87042fb6aebb722dMarcel Holtmann				sdp_record_t *rec = sdp_extract_pdu(pdata, pdata_len, &recsize);
4450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				if (rec == NULL) {
4451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					SDPERR("SVC REC is null\n");
4452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					status = -1;
4453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann					goto end;
4454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				}
44558db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann				if (!recsize) {
44568db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann					sdp_record_free(rec);
44578db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann					break;
44588db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann				}
4459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				scanned += recsize;
4460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				pdata += recsize;
4461121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann				pdata_len -= recsize;
4462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Loc seq length : %d\n", recsize);
4464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle);
4465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Bytes scanned : %d\n", scanned);
4466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				SDPDBG("Attrlist byte count : %d\n", attr_list_len);
4467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann				rec_list = sdp_list_append(rec_list, rec);
4468121c632f01e3f49a69a9d637e0da4d25c2ee090dMarcel Holtmann			} while (scanned < attr_list_len && pdata_len > 0);
4469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			SDPDBG("Successful scan of service attr lists\n");
4471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann			*rsp = rec_list;
4472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		}
4473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
44748f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedbergend:
4475a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rsp_concat_buf.data);
4476a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(reqbuf);
4477a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(rspbuf);
4478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return status;
4479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
4480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/*
4482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Find devices in the piconet.
4483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */
4484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found)
4485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
4486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0);
4487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (n < 0) {
4488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		SDPERR("Inquiry failed:%s", strerror(errno));
4489542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		return -1;
4490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
4491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	*found = n;
4492542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return 0;
4493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
4494542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4495542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_close(sdp_session_t *session)
4496542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
44978be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	struct sdp_transaction *t;
44988be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	int ret;
44998f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg
45008be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (!session)
45018be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		return -1;
45028be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
45038be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	ret = close(session->sock);
45048be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
45058be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	t = session->priv;
45068be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
45078be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	if (t) {
4508a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan		free(t->reqbuf);
45098be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
4510a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan		free(t->rsp_concat_buf.data);
45118be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi
45128be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi		free(t);
45138be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi	}
4514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(session);
4515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return ret;
4516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
4517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
4518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int sdp_is_local(const bdaddr_t *device)
4519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
4520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0;
4521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
4522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann
45231be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimstatic int sdp_connect_local(sdp_session_t *session)
4524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{
45251be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	struct sockaddr_un sa;
4526a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
45271be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->sock = socket(PF_UNIX, SOCK_STREAM, 0);
45281be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (session->sock < 0)
45291be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return -1;
45301be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->local = 1;
4531a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
45321be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.sun_family = AF_UNIX;
45331be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	strcpy(sa.sun_path, SDP_UNIX_PATH);
4534a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
4535d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann	return connect(session->sock, (struct sockaddr *) &sa, sizeof(sa));
45361be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim}
45371be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45381be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimstatic int sdp_connect_l2cap(const bdaddr_t *src,
45398f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		const bdaddr_t *dst, sdp_session_t *session)
45401be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim{
45411be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	uint32_t flags = session->flags;
45421be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	struct sockaddr_l2 sa;
45431be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	int sk;
45441be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45451be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
45461be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (session->sock < 0)
45471be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return -1;
45481be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session->local = 0;
45491be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45501be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sk = session->sock;
45511be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45521be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (flags & SDP_NON_BLOCKING) {
45531be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		long arg = fcntl(sk, F_GETFL, 0);
45541be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		fcntl(sk, F_SETFL, arg | O_NONBLOCK);
4555a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann	}
4556a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
4557b5e64e37e108d782ad9496873fcdc579e5a4dc60Johan Hedberg	memset(&sa, 0, sizeof(sa));
4558b5e64e37e108d782ad9496873fcdc579e5a4dc60Johan Hedberg
45591be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_family = AF_BLUETOOTH;
45601be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_psm = 0;
4561a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
45621be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (bacmp(src, BDADDR_ANY)) {
45631be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		sa.l2_bdaddr = *src;
45641be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0)
45651be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			return -1;
45661be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	}
4567a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
45681be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (flags & SDP_WAIT_ON_CLOSE) {
45691be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		struct linger l = { .l_onoff = 1, .l_linger = 1 };
45701be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
45711be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	}
45721be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45731be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_psm = htobs(SDP_PSM);
45741be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sa.l2_bdaddr = *dst;
45751be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45761be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	do {
45771be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa));
4578aa7577018bb1faac4b67b52dc8b003663cdd03adUlisses Furquim		if (!ret)
45791be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			return 0;
45801be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (ret < 0 && (flags & SDP_NON_BLOCKING) &&
45818f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg				(errno == EAGAIN || errno == EINPROGRESS))
45821be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			return 0;
45831be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	} while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY));
45841be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45851be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	return -1;
45861be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim}
45871be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45881be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimsdp_session_t *sdp_connect(const bdaddr_t *src,
45898f159d4498f549b0f9ecad9ef4147847f0583ebbJohan Hedberg		const bdaddr_t *dst, uint32_t flags)
45901be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim{
45911be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	sdp_session_t *session;
45921be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	int err;
45931be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45941be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) {
45951be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		errno = EINVAL;
45961be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return NULL;
45971be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	}
45981be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
45991be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	session = sdp_create(-1, flags);
46001be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (!session)
46011be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		return NULL;
46021be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
46031be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	if (sdp_is_local(dst)) {
46041be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (sdp_connect_local(session) < 0)
46051be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			goto fail;
4606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	} else {
46071be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim		if (sdp_connect_l2cap(src, dst, session) < 0)
46081be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim			goto fail;
4609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	}
4610a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann
46111be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	return session;
46121be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
4613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail:
461412862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann	err = errno;
4615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	if (session->sock >= 0)
4616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann		close(session->sock);
4617a554d3a656f0b0e3a3d82b68ab61b89f1b876660Gustavo F. Padovan	free(session->priv);
4618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann	free(session);
461912862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann	errno = err;
46201be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim
46211be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim	return NULL;
4622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}
46238f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann
46248f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannint sdp_get_socket(const sdp_session_t *session)
46258f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{
46268f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann	return session->sock;
46278f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann}
46288f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann
46298f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannuint16_t sdp_gen_tid(sdp_session_t *session)
46308f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{
46318f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann	return session->tid++;
46328f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann}
46333faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
46343faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas/*
46353faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas * Set the supported features
46363faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas */
46373faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenasint sdp_set_supp_feat(sdp_record_t *rec, const sdp_list_t *sf)
46383faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas{
46393faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	const sdp_list_t *p, *r;
46403faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdp_data_t *feat, *seq_feat;
46413faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	int seqlen, i;
46423faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	void **seqDTDs, **seqVals;
46433faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
46443faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	seqlen = sdp_list_len(sf);
46453faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	seqDTDs = malloc(seqlen * sizeof(void *));
46463faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	if (!seqDTDs)
46473faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		return -1;
46483faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	seqVals = malloc(seqlen * sizeof(void *));
46493faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	if (!seqVals) {
46503faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		free(seqDTDs);
46513faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		return -1;
46523faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	}
46533faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
46543faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	for (p = sf, i = 0; p; p = p->next, i++) {
46553faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		int plen, j;
46563faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		void **dtds, **vals;
46571d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		int *lengths;
46583faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
46593faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		plen = sdp_list_len(p->data);
46603faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		dtds = malloc(plen * sizeof(void *));
46613faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		if (!dtds)
46623faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			goto fail;
46633faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		vals = malloc(plen * sizeof(void *));
46643faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		if (!vals) {
46653faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			free(dtds);
46663faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			goto fail;
46673faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		}
46681d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		lengths = malloc(plen * sizeof(int *));
46691d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		if (!lengths) {
46701d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			free(dtds);
46711d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			free(vals);
46721d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			goto fail;
46731d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		}
46743faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		for (r = p->data, j = 0; r; r = r->next, j++) {
46753faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			sdp_data_t *data = (sdp_data_t*)r->data;
46763faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			dtds[j] = &data->dtd;
46771d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			switch (data->dtd) {
46781d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_URL_STR8:
46791d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_URL_STR16:
46801d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_TEXT_STR8:
46811d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_TEXT_STR16:
46821d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				vals[j] = data->val.str;
46831d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				lengths[j] = data->unitSize - sizeof(uint8_t);
46841d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				break;
46851d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_ALT8:
46861d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_ALT16:
46871d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_ALT32:
46881d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_SEQ8:
46891d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_SEQ16:
46901d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			case SDP_SEQ32:
46911d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				vals[j] = data->val.dataseq;
46921d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				lengths[j] = 0;
46931d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				break;
46941d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			default:
46951d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				vals[j] = &data->val;
46961d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				lengths[j] = 0;
46971d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas				break;
46981d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas			}
46993faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		}
47001d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		feat = sdp_seq_alloc_with_length(dtds, vals, lengths, plen);
47013faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		free(dtds);
47023faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		free(vals);
47031d1154156df28660e41031df5c3f1ffe91c01aaeJosé Antonio Santos Cadenas		free(lengths);
47043faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		if (!feat)
47053faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			goto fail;
47063faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		seqDTDs[i] = &feat->dtd;
47073faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		seqVals[i] = feat;
47083faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	}
47093faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	seq_feat = sdp_seq_alloc(seqDTDs, seqVals, seqlen);
47103faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	if (!seq_feat)
47113faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		goto fail;
47123faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdp_attr_replace(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST, seq_feat);
47133faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47143faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	free(seqVals);
47153faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	free(seqDTDs);
47163faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	return 0;
47173faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47183faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenasfail:
47193faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	free(seqVals);
47203faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	free(seqDTDs);
47213faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	return -1;
47223faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas}
47233faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47243faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas/*
47253faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas * Get the supported features
47263faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas * If an error occurred -1 is returned and errno is set
47273faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas */
47283faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenasint sdp_get_supp_feat(const sdp_record_t *rec, sdp_list_t **seqp)
47293faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas{
47303faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdp_data_t *sdpdata, *d;
47313faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdp_list_t *tseq;
47323faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	tseq = NULL;
47333faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47343faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	sdpdata = sdp_data_get(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST);
47353faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47363faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	if (!sdpdata || sdpdata->dtd < SDP_SEQ8 || sdpdata->dtd > SDP_SEQ32)
47373faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		return sdp_get_uuidseq_attr(rec,
4738d108edd5cd7115ced6fc3c1a9bc2b975abdfc4e2Marcel Holtmann					SDP_ATTR_SUPPORTED_FEATURES_LIST, seqp);
47393faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47403faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	for (d = sdpdata->val.dataseq; d; d = d->next) {
47413faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		sdp_data_t *dd;
47423faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		sdp_list_t *subseq;
47433faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47443faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
47453faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			goto fail;
474615b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter
47473faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		subseq = NULL;
474815b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter
47493faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		for (dd = d->val.dataseq; dd; dd = dd->next) {
47503faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			sdp_data_t *data;
475115b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			void *val;
475215b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			int length;
475315b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter
475415b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			switch (dd->dtd) {
475515b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_URL_STR8:
475615b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_URL_STR16:
475715b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_TEXT_STR8:
475815b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_TEXT_STR16:
475915b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				val = dd->val.str;
476015b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				length = dd->unitSize - sizeof(uint8_t);
476115b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				break;
476215b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_UINT8:
476315b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			case SDP_UINT16:
476415b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				val = &dd->val;
476515b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				length = 0;
476615b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter				break;
476715b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			default:
47683faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas				goto fail;
476915b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			}
477015b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter
477115b2bfd69b42c2b6a37916a7067a429491a0da95Elvis Pfützenreuter			data = sdp_data_alloc_with_length(dd->dtd, val, length);
47723faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas			if (data)
47733faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas				subseq = sdp_list_append(subseq, data);
47743faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		}
47753faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		tseq = sdp_list_append(tseq, subseq);
47763faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	}
47773faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	*seqp = tseq;
47783faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	return 0;
47793faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47803faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenasfail:
47813faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	while (tseq) {
47823faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		sdp_list_t * next;
47833faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
47843faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		next = tseq->next;
47853faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		sdp_list_free(tseq, free);
47863faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas		tseq = next;
47873faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	}
47883faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	errno = EINVAL;
47893faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas	return -1;
47903faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas}
47913faf12fdb7f9d7a043ad526e8e8d1788d4956a4bJosé Antonio Santos Cadenas
4792