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