sdp.c revision 0e1789b3f1897512eb30d63c8e9803f1461446c1
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> 77208028266fc19d380ac77c97c46b6f2fdc80e1dMarcel Holtmann * Copyright (C) 2002-2008 Marcel Holtmann <marcel@holtmann.org> 8764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane <steve.crane@rococosoft.com> 9764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann * 10764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann * 11764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann * This program is free software; you can redistribute it and/or modify 12c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * it under the terms of the GNU General Public License as published by 13c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * the Free Software Foundation; either version 2 of the License, or 14c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * (at your option) any later version. 15764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann * 16c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * This program is distributed in the hope that it will be useful, 17c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 18c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * GNU General Public License for more details. 20764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann * 21c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * You should have received a copy of the GNU General Public License 22c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * along with this program; if not, write to the Free Software 23c0d524486a50e8366c12c5ebea1a4441e9db46aaMarcel Holtmann * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann * 25542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 26542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 27764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann#ifdef HAVE_CONFIG_H 28764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann#include <config.h> 29764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann#endif 30764abe23a0d4ede999f1f34ee0e310c0eeaaff79Marcel Holtmann 31542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <stdio.h> 32542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <errno.h> 331be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim#include <fcntl.h> 34b393cdff611943a05ec598048b5c4be8130151ddMarcel Holtmann#include <unistd.h> 35542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <stdlib.h> 36b393cdff611943a05ec598048b5c4be8130151ddMarcel Holtmann#include <limits.h> 37bb45b882917f26aaa26b2b903b70d622b39cce84Marcel Holtmann#include <string.h> 38654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#include <syslog.h> 39542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <sys/un.h> 40542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#include <sys/socket.h> 418bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann#include <sys/time.h> 428bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann#include <sys/types.h> 43542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4451e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/bluetooth.h> 4551e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/hci.h> 4651e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/hci_lib.h> 4751e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/l2cap.h> 4851e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/sdp.h> 4951e671b116fe121053444c4817e38ad07e9586f8Marcel Holtmann#include <bluetooth/sdp_lib.h> 50654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann 51654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#include <netinet/in.h> 52654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann 53654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg) 54654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg) 55654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann 56654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#ifdef SDP_DEBUG 57654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg) 58654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#else 59654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDPDBG(fmt...) 60654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#endif 61654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann 62654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#if __BYTE_ORDER == __BIG_ENDIAN 63654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define ntoh64(x) (x) 64654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmannstatic inline void ntoh128(uint128_t *src, uint128_t *dst) 65654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann{ 66654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann int i; 67654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann for (i = 0; i < 16; i++) 68654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann dst->data[i] = src->data[i]; 69654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann} 70654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#else 71654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmannstatic inline uint64_t ntoh64(uint64_t n) 72654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann{ 73654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann uint64_t h; 74654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann uint64_t tmp = ntohl(n & 0x00000000ffffffff); 75654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann h = ntohl(n >> 32); 76654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann h |= tmp << 32; 77654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann return h; 78654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann} 79654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmannstatic inline void ntoh128(uint128_t *src, uint128_t *dst) 80654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann{ 81654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann int i; 82654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann for (i = 0; i < 16; i++) 83654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann dst->data[15 - i] = src->data[i]; 84654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann} 85654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#endif 86654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann 87654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define hton64(x) ntoh64(x) 88654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define hton128(x, y) ntoh128(x, y) 89542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 90542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB" 91542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 923f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmannstatic uint128_t bluetooth_base_uuid = { 933f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 94c30706178221e3df5dfe82eb5c91f39fe118eb78Marcel Holtmann 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB } 953f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann}; 96542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 97654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann#define SDP_MAX_ATTR_LEN 65535 98654f832d98530b05dc7ffaefff5950a32de76b3cMarcel Holtmann 99542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* Message structure. */ 100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstruct tupla { 101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int index; 102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann char *str; 103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}; 104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic struct tupla Protocol[] = { 1066864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { SDP_UUID, "SDP" }, 1076864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UDP_UUID, "UDP" }, 1086864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { RFCOMM_UUID, "RFCOMM" }, 1096864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { TCP_UUID, "TCP" }, 1106864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { TCS_BIN_UUID, "TCS-BIN" }, 1116864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { TCS_AT_UUID, "TCS-AT" }, 1126864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { OBEX_UUID, "OBEX" }, 1136864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { IP_UUID, "IP" }, 1146864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { FTP_UUID, "FTP" }, 1156864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HTTP_UUID, "HTTP" }, 1166864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { WSP_UUID, "WSP" }, 1176864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { BNEP_UUID, "BNEP" }, 1186864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UPNP_UUID, "UPNP" }, 1196864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HIDP_UUID, "HIDP" }, 1206864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HCRP_CTRL_UUID, "HCRP-Ctrl" }, 1216864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HCRP_DATA_UUID, "HCRP-Data" }, 1226864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HCRP_NOTE_UUID, "HCRP-Notify" }, 1236864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { AVCTP_UUID, "AVCTP" }, 1246864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { AVDTP_UUID, "AVDTP" }, 1256864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { CMTP_UUID, "CMTP" }, 1266864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UDI_UUID, "UDI" }, 127f767416e71484be2463caa6482dc978e165cabaeMarcel Holtmann { MCAP_CTRL_UUID, "MCAP-Ctrl" }, 128f767416e71484be2463caa6482dc978e165cabaeMarcel Holtmann { MCAP_DATA_UUID, "MCAP-Data" }, 1296864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { L2CAP_UUID, "L2CAP" }, 130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann { 0 } 131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}; 132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic struct tupla ServiceClass[] = { 1346864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { SDP_SERVER_SVCLASS_ID, "SDP Server" }, 1356864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { BROWSE_GRP_DESC_SVCLASS_ID, "Browse Group Descriptor" }, 1366864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { PUBLIC_BROWSE_GROUP, "Public Browse Group" }, 1376864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { SERIAL_PORT_SVCLASS_ID, "Serial Port" }, 1386864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { LAN_ACCESS_SVCLASS_ID, "LAN Access Using PPP" }, 1396864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { DIALUP_NET_SVCLASS_ID, "Dialup Networking" }, 1406864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { IRMC_SYNC_SVCLASS_ID, "IrMC Sync" }, 1416864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { OBEX_OBJPUSH_SVCLASS_ID, "OBEX Object Push" }, 1426864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { OBEX_FILETRANS_SVCLASS_ID, "OBEX File Transfer" }, 1436864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { IRMC_SYNC_CMD_SVCLASS_ID, "IrMC Sync Command" }, 1446864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HEADSET_SVCLASS_ID, "Headset" }, 1456864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { CORDLESS_TELEPHONY_SVCLASS_ID, "Cordless Telephony" }, 1466864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { AUDIO_SOURCE_SVCLASS_ID, "Audio Source" }, 1476864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { AUDIO_SINK_SVCLASS_ID, "Audio Sink" }, 1486864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { AV_REMOTE_TARGET_SVCLASS_ID, "AV Remote Target" }, 1496864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { ADVANCED_AUDIO_SVCLASS_ID, "Advanced Audio" }, 1506864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { AV_REMOTE_SVCLASS_ID, "AV Remote" }, 1516864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { VIDEO_CONF_SVCLASS_ID, "Video Conferencing" }, 1526864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { INTERCOM_SVCLASS_ID, "Intercom" }, 1536864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { FAX_SVCLASS_ID, "Fax" }, 1546864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HEADSET_AGW_SVCLASS_ID, "Headset Audio Gateway" }, 1556864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { WAP_SVCLASS_ID, "WAP" }, 1566864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { WAP_CLIENT_SVCLASS_ID, "WAP Client" }, 1576864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { PANU_SVCLASS_ID, "PAN User" }, 1586864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { NAP_SVCLASS_ID, "Network Access Point" }, 1596864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { GN_SVCLASS_ID, "PAN Group Network" }, 1606864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { DIRECT_PRINTING_SVCLASS_ID, "Direct Printing" }, 1616864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { REFERENCE_PRINTING_SVCLASS_ID, "Reference Printing" }, 1626864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { IMAGING_SVCLASS_ID, "Imaging" }, 1636864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { IMAGING_RESPONDER_SVCLASS_ID, "Imaging Responder" }, 1646864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { IMAGING_ARCHIVE_SVCLASS_ID, "Imaging Automatic Archive" }, 1656864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { IMAGING_REFOBJS_SVCLASS_ID, "Imaging Referenced Objects" }, 1666864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HANDSFREE_SVCLASS_ID, "Handsfree" }, 1676864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HANDSFREE_AGW_SVCLASS_ID, "Handfree Audio Gateway" }, 1686864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { DIRECT_PRT_REFOBJS_SVCLASS_ID, "Direct Printing Ref. Objects" }, 1696864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { REFLECTED_UI_SVCLASS_ID, "Reflected UI" }, 1706864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { BASIC_PRINTING_SVCLASS_ID, "Basic Printing" }, 1716864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { PRINTING_STATUS_SVCLASS_ID, "Printing Status" }, 1726864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HID_SVCLASS_ID, "Human Interface Device" }, 1736864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HCR_SVCLASS_ID, "Hardcopy Cable Replacement" }, 1746864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HCR_PRINT_SVCLASS_ID, "HCR Print" }, 1756864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { HCR_SCAN_SVCLASS_ID, "HCR Scan" }, 1766864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { CIP_SVCLASS_ID, "Common ISDN Access" }, 1776864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { VIDEO_CONF_GW_SVCLASS_ID, "Video Conferencing Gateway" }, 1786864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UDI_MT_SVCLASS_ID, "UDI MT" }, 1796864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UDI_TA_SVCLASS_ID, "UDI TA" }, 1806864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { AV_SVCLASS_ID, "Audio/Video" }, 1816864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { SAP_SVCLASS_ID, "SIM Access" }, 1828ce8108e712e40e1b9530c96f7ff6cbb32b5cb8bMarcel Holtmann { PBAP_PCE_SVCLASS_ID, "Phonebook Access - PCE" }, 1838ce8108e712e40e1b9530c96f7ff6cbb32b5cb8bMarcel Holtmann { PBAP_PSE_SVCLASS_ID, "Phonebook Access - PSE" }, 18473f2fe893f6801358ea4fb88dc8d24050c7d0ca5Marcel Holtmann { PBAP_SVCLASS_ID, "Phonebook Access" }, 1856864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { PNP_INFO_SVCLASS_ID, "PnP Information" }, 1866864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { GENERIC_NETWORKING_SVCLASS_ID, "Generic Networking" }, 1876864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { GENERIC_FILETRANS_SVCLASS_ID, "Generic File Transfer" }, 1886864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { GENERIC_AUDIO_SVCLASS_ID, "Generic Audio" }, 1896864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { GENERIC_TELEPHONY_SVCLASS_ID, "Generic Telephony" }, 1906864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UPNP_SVCLASS_ID, "UPnP" }, 1916864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UPNP_IP_SVCLASS_ID, "UPnP IP" }, 1926864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UPNP_PAN_SVCLASS_ID, "UPnP PAN" }, 1936864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UPNP_LAP_SVCLASS_ID, "UPnP LAP" }, 1946864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { UPNP_L2CAP_SVCLASS_ID, "UPnP L2CAP" }, 1956864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { VIDEO_SOURCE_SVCLASS_ID, "Video Source" }, 1966864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann { VIDEO_SINK_SVCLASS_ID, "Video Sink" }, 1972fa38208982e7c7bb55ae97acd13dbf82dd24e88Marcel Holtmann { VIDEO_DISTRIBUTION_SVCLASS_ID, "Video Distribution" }, 1981622daf2f8fa0abeb0a11be14558ed30a17fc044Marcel Holtmann { MDP_SVCLASS_ID, "MDP" }, 1991622daf2f8fa0abeb0a11be14558ed30a17fc044Marcel Holtmann { MDP_SOURCE_SVCLASS_ID, "MDP Source" }, 2001622daf2f8fa0abeb0a11be14558ed30a17fc044Marcel Holtmann { MDP_SINK_SVCLASS_ID, "MDP Sink" }, 20142e0ce5b430ac5e36c0d21bdddcaf1fe83e025f5Marcel Holtmann { APPLE_AGENT_SVCLASS_ID, "Apple Agent" }, 202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann { 0 } 203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann}; 204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2056864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann#define Profile ServiceClass 206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 207542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic char *string_lookup(struct tupla *pt0, int index) 208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann struct tupla *pt; 2106864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann 211542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (pt = pt0; pt->index; pt++) 2126864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann if (pt->index == index) 213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return pt->str; 2146864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann 215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return ""; 216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2183df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmannstatic char *string_lookup_uuid(struct tupla *pt0, const uuid_t* uuid) 2193df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann{ 2203df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann uuid_t tmp_uuid; 2213df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann 2223df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid)); 2233df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann 2243df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann if (sdp_uuid128_to_uuid(&tmp_uuid)) { 2253df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann switch (tmp_uuid.type) { 2263df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann case SDP_UUID16: 2273df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann return string_lookup(pt0, tmp_uuid.value.uuid16); 2283df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann case SDP_UUID32: 2293df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann return string_lookup(pt0, tmp_uuid.value.uuid32); 2303df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann } 2313df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann } 2323df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann 2333df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann return ""; 2343df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann} 2353df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann 236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Prints into a string the Protocol UUID 238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * coping a maximum of n characters. 239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n) 241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann char *str2; 243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!uuid) { 245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann snprintf(str, n, "NULL"); 246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -2; 247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2486864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann 249542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (uuid->type) { 250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann str2 = string_lookup(message, uuid->value.uuid16); 252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann snprintf(str, n, str2); 253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 2550e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann str2 = string_lookup(message, uuid->value.uuid32); 2560e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann snprintf(str, n, str2); 2570e6eb45baedd15cc65beb454ec00cefb5fb7962dMarcel Holtmann break; 258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 2593df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann str2 = string_lookup_uuid(message, uuid); 2603df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann snprintf(str, n, str2); 2613df8390f8e7be37d0adfac2192c425219941d844Marcel Holtmann break; 262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann default: 263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); 264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2666864c723272d4790a2fec4a1c23fa5e46ac15e5fMarcel Holtmann 267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n) 271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return uuid2str(Protocol, uuid, str, n); 273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n) 276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return uuid2str(ServiceClass, uuid, str, n); 278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n) 281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return uuid2str(Profile, uuid, str, n); 283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * convert the UUID to string, copying a maximum of n characters. 287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n) 289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!uuid) { 291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann snprintf(str, n, "NULL"); 292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -2; 293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (uuid->type) { 295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann snprintf(str, n, "%.4x", uuid->value.uuid16); 297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann snprintf(str, n, "%.8x", uuid->value.uuid32); 300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128:{ 302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned int data0; 303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned short data1; 304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned short data2; 305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned short data3; 306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned int data4; 307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned short data5; 308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data0, &uuid->value.uuid128.data[0], 4); 310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data1, &uuid->value.uuid128.data[4], 2); 311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data2, &uuid->value.uuid128.data[6], 2); 312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data3, &uuid->value.uuid128.data[8], 2); 313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data4, &uuid->value.uuid128.data[10], 4); 314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data5, &uuid->value.uuid128.data[14], 2); 315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", 317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann ntohl(data0), ntohs(data1), 318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann ntohs(data2), ntohs(data3), 319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann ntohl(data4), ntohs(data5)); 320542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 322542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann default: 323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); 324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; // Enum type of UUID not set 325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 326542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG 330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Function prints the UUID in hex as per defined syntax - 332542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 4bytes-2bytes-2bytes-2bytes-6bytes 334542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * There is some ugly code, including hardcoding, but 336542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * that is just the way it is converting 16 and 32 bit 337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUIDs to 128 bit as defined in the SDP doc 338542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 339542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid_print(const uuid_t *uuid) 340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (uuid == NULL) { 342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Null passed to print UUID\n"); 343542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return; 344542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 345542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (uuid->type == SDP_UUID16) { 346542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG(" uint16_t : 0x%.4x\n", uuid->value.uuid16); 347542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } else if (uuid->type == SDP_UUID32) { 348542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG(" uint32_t : 0x%.8x\n", uuid->value.uuid32); 349542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } else if (uuid->type == SDP_UUID128) { 350542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned int data0; 351542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned short data1; 352542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned short data2; 353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned short data3; 354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned int data4; 355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned short data5; 356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data0, &uuid->value.uuid128.data[0], 4); 358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data1, &uuid->value.uuid128.data[4], 2); 359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data2, &uuid->value.uuid128.data[6], 2); 360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data3, &uuid->value.uuid128.data[8], 2); 361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data4, &uuid->value.uuid128.data[10], 4); 362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data5, &uuid->value.uuid128.data[14], 2); 363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG(" uint128_t : 0x%.8x-", ntohl(data0)); 365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("%.4x-", ntohs(data1)); 366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("%.4x-", ntohs(data2)); 367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("%.4x-", ntohs(data3)); 368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("%.8x", ntohl(data4)); 369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("%.4x\n", ntohs(data5)); 370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } else 371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Enum type of UUID not set\n"); 372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif 374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 375641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, uint32_t length) 376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *seq; 37821f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann sdp_data_t *d = malloc(sizeof(sdp_data_t)); 379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!d) 381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return NULL; 382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(d, 0, sizeof(sdp_data_t)); 384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->dtd = dtd; 385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize = sizeof(uint8_t); 386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (dtd) { 388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_DATA_NIL: 389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT8: 391aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.uint8 = *(uint8_t *) value; 392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint8_t); 393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT8: 395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_BOOL: 396aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.int8 = *(int8_t *) value; 397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(int8_t); 398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT16: 400aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.uint16 = bt_get_unaligned((uint16_t *) value); 401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint16_t); 402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT16: 404aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.int16 = bt_get_unaligned((int16_t *) value); 405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(int16_t); 406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT32: 408aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.uint32 = bt_get_unaligned((uint32_t *) value); 409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint32_t); 410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT32: 412aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.int32 = bt_get_unaligned((int32_t *) value); 413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(int32_t); 414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT64: 416aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.int64 = bt_get_unaligned((int64_t *) value); 417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(int64_t); 418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT64: 420aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.uint64 = bt_get_unaligned((uint64_t *) value); 421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint64_t); 422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT128: 424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&d->val.uint128.data, value, sizeof(uint128_t)); 425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint128_t); 426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT128: 428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&d->val.int128.data, value, sizeof(uint128_t)); 429542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint128_t); 430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 432aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value)); 433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint16_t); 434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 436aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value)); 437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint32_t); 438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_uuid128_create(&d->val.uuid, value); 441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint128_t); 442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR8: 444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR16: 445641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann case SDP_TEXT_STR8: 446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR16: 447641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann if (!value) { 448641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann free(d); 449641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann return NULL; 450641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann } 451641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 452641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann d->unitSize += length; 453641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann if (length <= USHRT_MAX) { 454641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann d->val.str = malloc(length); 455641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann if (!d->val.str) { 456641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann free(d); 457641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann return NULL; 458641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann } 459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 460641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann memcpy(d->val.str, value, length); 461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } else { 462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Strings of size > USHRT_MAX not supported\n"); 463641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann free(d); 464641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann d = NULL; 465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR32: 468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR32: 469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Strings of size > USHRT_MAX not supported\n"); 470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT8: 472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT16: 473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT32: 474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ8: 475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ16: 476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ32: 477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (dtd == SDP_ALT8 || dtd == SDP_SEQ8) 478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint8_t); 479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16) 480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint16_t); 481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32) 482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += sizeof(uint32_t); 483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seq = (sdp_data_t *)value; 484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->val.dataseq = seq; 485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (; seq; seq = seq->next) 486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->unitSize += seq->unitSize; 487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann default: 489641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann free(d); 490641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann d = NULL; 491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 492641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return d; 494641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann} 495641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 496641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) 497641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann{ 498641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann uint32_t length; 499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 500641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann switch (dtd) { 501641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann case SDP_URL_STR8: 502641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann case SDP_URL_STR16: 503641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann case SDP_TEXT_STR8: 504641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann case SDP_TEXT_STR16: 505641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann if (!value) 506641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann return NULL; 507641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 508641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann length = strlen((char *) value); 509641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann break; 510641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann default: 511641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann length = 0; 512641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann break; 513641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann } 514641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 515641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann return sdp_data_alloc_with_length(dtd, value, length); 516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d) 519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (seq) { 521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *p; 522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (p = seq; p->next; p = p->next); 523542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p->next = d; 524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } else 525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seq = d; 526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->next = NULL; 527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return seq; 528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 530641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmannsdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length, int len) 531641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann{ 532641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann sdp_data_t *curr = NULL, *seq = NULL; 533641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann int i; 534641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 535641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann for (i = 0; i < len; i++) { 536641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann sdp_data_t *data; 537641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann int8_t dtd = *(uint8_t *) dtds[i]; 538641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 539641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32) 540641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann data = (sdp_data_t *) values[i]; 541641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann else 542641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann data = sdp_data_alloc_with_length(dtd, values[i], length[i]); 543641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 544641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann if (!data) 545641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann return NULL; 546641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 547641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann if (curr) 548641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann curr->next = data; 549641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann else 550641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann seq = data; 551641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 552641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann curr = data; 553641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann } 554641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 555641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann return sdp_data_alloc_with_length(SDP_SEQ8, seq, length[i]); 556641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann} 557641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len) 559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *curr = NULL, *seq = NULL; 561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int i; 562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (i = 0; i < len; i++) { 564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *data; 565641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann uint8_t dtd = *(uint8_t *) dtds[i]; 566641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32) 568641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann data = (sdp_data_t *) values[i]; 569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else 570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data = sdp_data_alloc(dtd, values[i]); 571641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!data) 573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return NULL; 574641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 575542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (curr) 576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann curr->next = data; 577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else 578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seq = data; 579641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann curr = data; 581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 582641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return sdp_data_alloc(SDP_SEQ8, seq); 584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 5864c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmannstatic void extract_svclass_uuid(sdp_data_t *data, uuid_t *uuid) 5874c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann{ 5884c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann sdp_data_t *d; 5894c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 5904c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann if (!data || data->dtd < SDP_SEQ8 || data->dtd > SDP_SEQ32) 5914c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann return; 5924c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 5934c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann d = data->val.dataseq; 5944c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann if (!d) 5954c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann return; 5964c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 5974c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) 5984c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann return; 5994c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 6004c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann *uuid = d->val.uuid; 6014c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann} 6024c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d) 604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 605542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *p = sdp_data_get(rec, attr); 606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (p) 608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 6094c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->attrId = attr; 611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func); 6124c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 6134c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann if (attr == SDP_ATTR_SVCLASS_ID_LIST) 6144c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann extract_svclass_uuid(d, &rec->svclass); 6154c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_attr_remove(sdp_record_t *rec, uint16_t attr) 620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d = sdp_data_get(rec, attr); 6224c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (d) 624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rec->attrlist = sdp_list_remove(rec->attrlist, d); 6254c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 6264c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann if (attr == SDP_ATTR_SVCLASS_ID_LIST) 6274c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann memset(&rec->svclass, 0, sizeof(rec->svclass)); 628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 630cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannvoid sdp_set_seq_len(uint8_t *ptr, uint32_t length) 631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 632aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann uint8_t dtd = *(uint8_t *) ptr++; 633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (dtd) { 635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ8: 636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT8: 637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR8: 638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR8: 639aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann *(uint8_t *)ptr = (uint8_t) length; 640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ16: 642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT16: 643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR16: 644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR16: 645aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htons(length), (uint16_t *) ptr); 646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ32: 648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT32: 649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR32: 650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR32: 651aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htonl(length), (uint32_t *) ptr); 652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd) 657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int orig = buf->data_size; 659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t *p = buf->data + buf->data_size; 660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *p++ = dtd; 662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann buf->data_size += sizeof(uint8_t); 663641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (dtd) { 665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ8: 666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR8: 667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR8: 668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT8: 669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann buf->data_size += sizeof(uint8_t); 670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ16: 672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR16: 673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR16: 674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT16: 675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann buf->data_size += sizeof(uint16_t); 676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ32: 678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR32: 679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR32: 680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT32: 681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann buf->data_size += sizeof(uint32_t); 682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 684641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 685542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return buf->data_size - orig; 686542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 687542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 688542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_attrid(sdp_buf_t *buf, uint16_t attr) 689542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 690542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t *p = buf->data; 691542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 692542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // data type for attr 693542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *p++ = SDP_UINT16; 694542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann buf->data_size = sizeof(uint8_t); 695aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htons(attr), (uint16_t *) p); 696542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint16_t); 697542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann buf->data_size += sizeof(uint16_t); 698542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 699542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 700542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata) 701542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 702542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d; 703542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int n = 0; 704542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 705542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (d = sdpdata->val.dataseq; d; d = d->next) 706542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann n += sdp_gen_pdu(buf, d); 707641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 708542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return n; 709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 711542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) 712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 713cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t pdu_size = 0, data_size = 0; 714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned char *src = NULL, is_seq = 0, is_alt = 0; 715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t dtd = d->dtd; 716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint16_t u16; 717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint32_t u32; 718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint64_t u64; 719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint128_t u128; 720cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *seqp = buf->data + buf->data_size; 721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 722542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdu_size = sdp_set_data_type(buf, dtd); 723641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (dtd) { 725542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_DATA_NIL: 726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT8: 728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann src = &d->val.uint8; 729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(uint8_t); 730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT16: 732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u16 = htons(d->val.uint16); 733cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u16; 734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(uint16_t); 735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT32: 737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u32 = htonl(d->val.uint32); 738cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u32; 739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(uint32_t); 740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT64: 742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u64 = hton64(d->val.uint64); 743cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u64; 744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(uint64_t); 745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT128: 747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann hton128(&d->val.uint128, &u128); 748cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u128; 749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(uint128_t); 750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT8: 752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_BOOL: 753cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &d->val.int8; 754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(int8_t); 755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT16: 757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u16 = htons(d->val.int16); 758cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u16; 759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(int16_t); 760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT32: 762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u32 = htonl(d->val.int32); 763cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u32; 764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(int32_t); 765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT64: 767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u64 = hton64(d->val.int64); 768cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u64; 769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(int64_t); 770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT128: 772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann hton128(&d->val.int128, &u128); 773cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u128; 774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(uint128_t); 775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR8: 777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR16: 778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR32: 779641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann case SDP_URL_STR8: 780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR16: 781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR32: 782cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) d->val.str; 783cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann data_size = d->unitSize - sizeof(uint8_t); 784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_set_seq_len(seqp, data_size); 785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ8: 787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ16: 788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ32: 789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann is_seq = 1; 790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = get_data_size(buf, d); 791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_set_seq_len(seqp, data_size); 792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT8: 794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT16: 795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT32: 796542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann is_alt = 1; 797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = get_data_size(buf, d); 798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_set_seq_len(seqp, data_size); 799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 801542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u16 = htons(d->val.uuid.value.uuid16); 802cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u16; 803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(uint16_t); 804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u32 = htonl(d->val.uuid.value.uuid32); 807cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &u32; 808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(uint32_t); 809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 811cb08fcdb50544c554e1275ede85605e4542b5b1bMarcel Holtmann src = (unsigned char *) &d->val.uuid.value.uuid128; 812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_size = sizeof(uint128_t); 813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann default: 815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 817641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!is_seq && !is_alt) { 819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (src && buf) { 820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(buf->data + buf->data_size, src, data_size); 821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann buf->data_size += data_size; 822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } else if (dtd != SDP_DATA_NIL) 823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Gen PDU : Cant copy from NULL source or dest\n"); 824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 825641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdu_size += data_size; 827641d636fb24fb0dea567388a4f0d0f135d4ea48cMarcel Holtmann 828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return pdu_size; 829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 830542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void sdp_attr_pdu(void *value, void *udata) 832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 833542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value); 834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf) 837542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 838cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann buf->data = malloc(SDP_PDU_CHUNK_SIZE); 839997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann if (!buf->data) 840997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann return -ENOMEM; 841997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann 842997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann buf->buf_size = SDP_PDU_CHUNK_SIZE; 843997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann buf->data_size = 0; 844997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann memset(buf->data, 0, buf->buf_size); 845997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf); 846997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann 847997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann return 0; 848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d) 851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *p = sdp_data_get(rec, attr); 853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (p) { 855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rec->attrlist = sdp_list_remove(rec->attrlist, p); 856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_free(p); 857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 8584c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->attrId = attr; 8604c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func); 8614c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 8624c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann if (attr == SDP_ATTR_SVCLASS_ID_LIST) 8634c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann extract_svclass_uuid(d, &rec->svclass); 864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attrid_comp_func(const void *key1, const void *key2) 867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann const sdp_data_t *d1 = (const sdp_data_t *)key1; 869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann const sdp_data_t *d2 = (const sdp_data_t *)key2; 870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (d1 && d2) 872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return d1->attrId - d2->attrId; 873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void data_seq_free(sdp_data_t *seq) 877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d = seq->val.dataseq; 879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann while (d) { 881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *next = d->next; 882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_free(d); 883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d = next; 884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_free(sdp_data_t *d) 888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (d->dtd) { 890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ8: 891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ16: 892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ32: 893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data_seq_free(d); 894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR8: 896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR16: 897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR32: 898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR8: 899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR16: 900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR32: 901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(d->val.str); 902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(d); 905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 907a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannint sdp_uuid_extract_safe(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned) 908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 909a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann uint8_t type; 910a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 911a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint8_t)) { 912a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 913a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return -1; 914a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 915a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 916a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann type = *(const uint8_t *) p; 917a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 918a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (!SDP_IS_UUID(type)) { 919a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unknown data type : %d expecting a svc UUID\n", type); 920a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return -1; 921a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 922a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann p += sizeof(uint8_t); 923a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *scanned += sizeof(uint8_t); 924a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann bufsize -= sizeof(uint8_t); 925a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (type == SDP_UUID16) { 926a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint16_t)) { 927a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Not enough room for 16-bit UUID"); 928a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return -1; 929a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 930a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p))); 931a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *scanned += sizeof(uint16_t); 932a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann p += sizeof(uint16_t); 933a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } else if (type == SDP_UUID32) { 934a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint32_t)) { 935a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Not enough room for 32-bit UUID"); 936a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return -1; 937a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 938a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p))); 939a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *scanned += sizeof(uint32_t); 940a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann p += sizeof(uint32_t); 941a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } else { 942a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint128_t)) { 943a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Not enough room for 128-bit UUID"); 944a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return -1; 945a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 946a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann sdp_uuid128_create(uuid, p); 947a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *scanned += sizeof(uint128_t); 948a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann p += sizeof(uint128_t); 949a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 950a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return 0; 951a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann} 952a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 953a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannint sdp_uuid_extract(const uint8_t *p, uuid_t *uuid, int *scanned) 954a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann{ 955a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann /* Assume p points to a buffer of size at least SDP_MAX_ATTR_LEN, 956a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann because we don't have any better information */ 957a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return sdp_uuid_extract_safe(p, SDP_MAX_ATTR_LEN, uuid, scanned); 958a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann} 959a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 960a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannstatic sdp_data_t *extract_int(const void *p, int bufsize, int *len) 961a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann{ 962a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann sdp_data_t *d; 963a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 964a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint8_t)) { 965a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 966a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 967a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 968a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 969a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann d = malloc(sizeof(sdp_data_t)); 970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Extracting integer\n"); 972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(d, 0, sizeof(sdp_data_t)); 973aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->dtd = *(uint8_t *) p; 974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint8_t); 975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *len += sizeof(uint8_t); 976a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann bufsize -= sizeof(uint8_t); 977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (d->dtd) { 979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_DATA_NIL: 980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_BOOL: 982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT8: 983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT8: 984a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint8_t)) { 985a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 986a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 987a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 988a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *len += sizeof(uint8_t); 990aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.uint8 = *(uint8_t *) p; 991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT16: 993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT16: 994a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint16_t)) { 995a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 996a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 997a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 998a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *len += sizeof(uint16_t); 1000aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p)); 1001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT32: 1003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT32: 1004a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint32_t)) { 1005a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1006a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 1007a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1008a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *len += sizeof(uint32_t); 1010aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p)); 1011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT64: 1013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT64: 1014a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint64_t)) { 1015a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1016a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 1017a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1018a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *len += sizeof(uint64_t); 1020aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p)); 1021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT128: 1023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT128: 1024a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint128_t)) { 1025a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1026a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 1027a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1028a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *len += sizeof(uint128_t); 1030aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann ntoh128((uint128_t *) p, &d->val.uint128); 1031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann default: 1033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(d); 1034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d = NULL; 1035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1036542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return d; 1037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1039a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannstatic sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len, sdp_record_t *rec) 1040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 104121f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann sdp_data_t *d = malloc(sizeof(sdp_data_t)); 1042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Extracting UUID"); 1044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(d, 0, sizeof(sdp_data_t)); 1045a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (sdp_uuid_extract_safe(p, bufsize, &d->val.uuid, len) < 0) { 1046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(d); 1047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return NULL; 1048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1049aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->dtd = *(uint8_t *) p; 10509d9a7646b189cc2471b925cc448862e14c10c0c4Marcel Holtmann if (rec) 10519d9a7646b189cc2471b925cc448862e14c10c0c4Marcel Holtmann sdp_pattern_add_uuid(rec, &d->val.uuid); 1052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return d; 1053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 1056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract strings from the PDU (could be service description and similar info) 1057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 1058a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannstatic sdp_data_t *extract_str(const void *p, int bufsize, int *len) 1059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann char *s; 1061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int n; 1062a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann sdp_data_t *d; 1063a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1064a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint8_t)) { 1065a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1066a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1067a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1068a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1069a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann d = malloc(sizeof(sdp_data_t)); 1070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(d, 0, sizeof(sdp_data_t)); 1072aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann d->dtd = *(uint8_t *) p; 1073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint8_t); 1074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *len += sizeof(uint8_t); 1075a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann bufsize -= sizeof(uint8_t); 1076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (d->dtd) { 1078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR8: 1079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR8: 1080a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint8_t)) { 1081a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1082a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 1083a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1084a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1085aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann n = *(uint8_t *) p; 1086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint8_t); 1087a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *len += sizeof(uint8_t); 1088a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann bufsize -= sizeof(uint8_t); 1089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR16: 1091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR16: 1092a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint16_t)) { 1093a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1094a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 1095a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1096a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1097aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann n = ntohs(bt_get_unaligned((uint16_t *) p)); 1098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint16_t); 1099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *len += sizeof(uint16_t) + n; 1100a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann bufsize -= sizeof(uint16_t); 1101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann default: 1103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Sizeof text string > UINT16_MAX\n"); 1104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(d); 1105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1108a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < n) { 1109a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("String too long to fit in packet"); 1110a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 1111a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1112a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1113a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1114ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann s = malloc(n + 1); 1115a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (!s) { 1116a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Not enough memory for incoming string"); 1117a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 1118a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1119a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(s, 0, n + 1); 1121ff3922238b4258eb2f9f9458589d3cecd177f7bcMarcel Holtmann memcpy(s, p, n); 1122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1123a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *len += n; 1124a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Len : %d\n", n); 1126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Str : %s\n", s); 1127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->val.str = s; 11290ed4f8572e1b32b4dd57304db14351f0e0c59119Marcel Holtmann d->unitSize = n + sizeof(uint8_t); 1130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return d; 1131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1133a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann/* 1134a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann * Extract the sequence type and its length, and return offset into buf 1135a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann * or 0 on failure. 1136a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann */ 1137a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannint sdp_extract_seqtype_safe(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size) 1138a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann{ 1139a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann uint8_t dtd; 1140a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann int scanned = sizeof(uint8_t); 1141a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1142a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint8_t)) { 1143a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1144a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return 0; 1145a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1146a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1147a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann dtd = *(uint8_t *) buf; 1148a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann buf += sizeof(uint8_t); 1149a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann bufsize -= sizeof(uint8_t); 1150a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *dtdp = dtd; 1151a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann switch (dtd) { 1152a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann case SDP_SEQ8: 1153a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann case SDP_ALT8: 1154a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint8_t)) { 1155a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1156a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return 0; 1157a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1158a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *size = *(uint8_t *) buf; 1159a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann scanned += sizeof(uint8_t); 1160a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann break; 1161a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann case SDP_SEQ16: 1162a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann case SDP_ALT16: 1163a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint16_t)) { 1164a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1165a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return 0; 1166a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1167a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *size = ntohs(bt_get_unaligned((uint16_t *) buf)); 1168a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann scanned += sizeof(uint16_t); 1169a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann break; 1170a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann case SDP_SEQ32: 1171a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann case SDP_ALT32: 1172a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint32_t)) { 1173a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1174a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return 0; 1175a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1176a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *size = ntohl(bt_get_unaligned((uint32_t *) buf)); 1177a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann scanned += sizeof(uint32_t); 1178a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann break; 1179a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann default: 1180a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unknown sequence type, aborting\n"); 1181a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return 0; 1182a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1183a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return scanned; 1184a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann} 1185a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1186a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannint sdp_extract_seqtype(const uint8_t *buf, uint8_t *dtdp, int *size) 1187a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann{ 1188a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann /* Assume buf points to a buffer of size at least SDP_MAX_ATTR_LEN, 1189a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann because we don't have any better information */ 1190a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return sdp_extract_seqtype_safe(buf, SDP_MAX_ATTR_LEN, dtdp, size); 1191a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann} 1192a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1193a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannstatic sdp_data_t *extract_seq(const void *p, int bufsize, int *len, sdp_record_t *rec) 1194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int seqlen, n = 0; 1196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *curr, *prev; 119721f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann sdp_data_t *d = malloc(sizeof(sdp_data_t)); 1198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Extracting SEQ"); 1200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(d, 0, sizeof(sdp_data_t)); 1201a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann *len = sdp_extract_seqtype_safe(p, bufsize, &d->dtd, &seqlen); 1202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen); 1203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (*len == 0) 1205542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return d; 1206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1207a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (*len > bufsize) { 1208a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Packet not big enough to hold sequence."); 1209a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann free(d); 1210a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1211a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1212a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += *len; 1214a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann bufsize -= *len; 1215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann curr = prev = NULL; 1216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann while (n < seqlen) { 1217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int attrlen = 0; 1218a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann curr = sdp_extract_attr_safe(p, bufsize, &attrlen, rec); 1219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (curr == NULL) 1220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1222542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (prev) 1223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann prev->next = curr; 1224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else 1225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d->val.dataseq = curr; 1226542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann prev = curr; 1227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += attrlen; 1228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann n += attrlen; 1229a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann bufsize -= attrlen; 1230542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen); 1232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *len += n; 1235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return d; 1236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1238a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannsdp_data_t *sdp_extract_attr_safe(const uint8_t *p, int bufsize, int *size, sdp_record_t *rec) 1239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *elem; 1241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int n = 0; 1242a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann uint8_t dtd; 1243a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1244a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann if (bufsize < sizeof(uint8_t)) { 1245a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann SDPERR("Unexpected end of packet"); 1246a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return NULL; 1247a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann } 1248a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1249a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann dtd = *(const uint8_t *)p; 1250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("extract_attr: dtd=0x%x", dtd); 1252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (dtd) { 1253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_DATA_NIL: 1254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_BOOL: 1255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT8: 1256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT16: 1257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT32: 1258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT64: 1259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT128: 1260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT8: 1261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT16: 1262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT32: 1263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT64: 1264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT128: 1265a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann elem = extract_int(p, bufsize, &n); 1266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 1268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 1269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 1270a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann elem = extract_uuid(p, bufsize, &n, rec); 1271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR8: 1273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR16: 1274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR32: 1275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR8: 1276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR16: 1277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR32: 1278a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann elem = extract_str(p, bufsize, &n); 1279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ8: 1281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ16: 1282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ32: 1283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT8: 1284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT16: 1285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT32: 1286a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann elem = extract_seq(p, bufsize, &n, rec); 1287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann default: 1289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd); 1290542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return NULL; 1291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *size += n; 1293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return elem; 1294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1296a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannsdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec) 1297a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann{ 1298a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann /* Assume p points to a buffer of size at least SDP_MAX_ATTR_LEN, 1299a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann because we don't have any better information */ 1300a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann return sdp_extract_attr_safe(p, SDP_MAX_ATTR_LEN, size, rec); 1301a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann} 1302a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 1303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG 1304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void attr_print_func(void *value, void *userData) 1305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d = (sdp_data_t *)value; 1307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1308542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("=====================================\n"); 1309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n", d->attrId); 1310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value); 1311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (d) 1312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_print(d); 1313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else 1314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("NULL value\n"); 1315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("=====================================\n"); 1316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_print_service_attr(sdp_list_t *svcAttrList) 1319542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 13208bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann SDPDBG("Printing service attr list %p\n", svcAttrList); 1321542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_foreach(svcAttrList, attr_print_func, NULL); 13228bd7ef87e49b68c3090448f337454a1704f5e048Marcel Holtmann SDPDBG("Printed service attr list %p\n", svcAttrList); 1323542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1324542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif 1325542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 13260e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmannsdp_record_t *sdp_extract_pdu_safe(const uint8_t *buf, int bufsize, int *scanned) 1327542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1328542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int extracted = 0, seqlen = 0; 1329542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t dtd; 1330542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint16_t attr; 1331542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_record_t *rec = sdp_record_alloc(); 1332cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann const uint8_t *p = buf; 1333542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 13340e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann *scanned = sdp_extract_seqtype_safe(buf, bufsize, &dtd, &seqlen); 1335542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += *scanned; 13360e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann bufsize -= *scanned; 1337542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rec->attrlist = NULL; 13380e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann 13390e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann while (extracted < seqlen && bufsize > 0) { 1340542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int n = sizeof(uint8_t), attrlen = 0; 1341542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *data = NULL; 1342542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 13430e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", 13440e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann seqlen, extracted); 13450e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann 13460e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann if (bufsize < n + sizeof(uint16_t)) { 13470e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann SDPERR("Unexpected end of packet"); 13480e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann break; 13490e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann } 13500e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann 1351aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann dtd = *(uint8_t *) p; 1352aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann attr = ntohs(bt_get_unaligned((uint16_t *) (p + n))); 1353542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann n += sizeof(uint16_t); 1354542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr); 1356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 13570e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann data = sdp_extract_attr_safe(p + n, bufsize - n, &attrlen, rec); 1358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen); 1360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann n += attrlen; 1362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (data == NULL) { 1363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Terminating extraction of attributes"); 1364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 13664c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 1367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (attr == SDP_ATTR_RECORD_HANDLE) 1368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rec->handle = data->val.uint32; 13694c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 13704c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann if (attr == SDP_ATTR_SVCLASS_ID_LIST) 13714c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann extract_svclass_uuid(data, &rec->svclass); 13724c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann 1373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann extracted += n; 1374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += n; 13750e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann bufsize -= n; 1376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_replace(rec, attr, data); 13770e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann 1378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d", 13790e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann seqlen, extracted); 1380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG 1382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Successful extracting of Svc Rec attributes\n"); 1383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_print_service_attr(rec->attrlist); 1384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif 1385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *scanned += seqlen; 1386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return rec; 1387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 13890e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmannsdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned) 13900e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann{ 13910e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann /* Assume buf points to a buffer of size at least SDP_MAX_ATTR_LEN, 13920e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann because we don't have any better information */ 13930e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann return sdp_extract_pdu_safe(buf, SDP_MAX_ATTR_LEN, scanned); 13940e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann} 13950e1789b3f1897512eb30d63c8e9803f1461446c1Marcel Holtmann 1396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG 1397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic void print_dataseq(sdp_data_t *p) 1398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d; 1400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (d = p; d; d = d->next) 1402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_print(d); 1403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif 1405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_print(const sdp_record_t *rec) 1407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); 1409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (d) 14106d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann printf("Service Name: %.*s\n", d->unitSize, d->val.str); 1411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); 1412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (d) 14136d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann printf("Service Description: %.*s\n", d->unitSize, d->val.str); 1414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY); 1415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (d) 14166d83e9274971235c05b40349dbbaf3f826853ff5Marcel Holtmann printf("Service Provider: %.*s\n", d->unitSize, d->val.str); 1417542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG 1420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_data_print(sdp_data_t *d) 1421542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (d->dtd) { 1423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_DATA_NIL: 1424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("NIL\n"); 1425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_BOOL: 1427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT8: 1428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT16: 1429542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT32: 1430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT64: 1431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT128: 1432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT8: 1433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT16: 1434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT32: 1435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT64: 1436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_INT128: 1437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Integer : 0x%x\n", d->val.uint32); 1438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1439542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 1440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 1441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 1442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("UUID\n"); 1443542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_uuid_print(&d->val.uuid); 1444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR8: 1446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR16: 1447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_TEXT_STR32: 1448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Text : %s\n", d->val.str); 1449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR8: 1451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR16: 1452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_URL_STR32: 1453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("URL : %s\n", d->val.str); 1454542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ8: 1456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ16: 1457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ32: 1458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann print_dataseq(d->val.dataseq); 1459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT8: 1461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT16: 1462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_ALT32: 1463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Data Sequence Alternates\n"); 1464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann print_dataseq(d->val.dataseq); 1465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif 1469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId) 1471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rec->attrlist) { 1473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t sdpTemplate; 1474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *p; 1475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1476542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdpTemplate.attrId = attrId; 1477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func); 1478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (p) 1479542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return (sdp_data_t *)p->data; 1480542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 14814c6bbf0a08426efd008c1b9e439c693a826ee708Marcel Holtmann return NULL; 1482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1483542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1484cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size) 1485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1486cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t sent = 0; 1487542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann while (sent < size) { 1489542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int n = send(session->sock, buf + sent, size - sent, 0); 1490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (n < 0) 1491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1492542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sent += n; 1493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1494542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1495542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1496542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1497cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size) 1498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann fd_set readFds; 1500542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 }; 1501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 150273fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann FD_ZERO(&readFds); 1503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann FD_SET(session->sock, &readFds); 1504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Waiting for response\n"); 150573fa16fccbb85592973068a25949d4c331f7f475Marcel Holtmann if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) { 1506542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Client timed out\n"); 1507542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ETIMEDOUT; 1508542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1509542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1510542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return recv(session->sock, buf, size, 0); 1511542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1512542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1513542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 1514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * generic send request, wait for response method. 1515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 1516cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannint sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf, uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize) 1517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int n; 1519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)reqbuf; 1520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *)rspbuf; 1521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG(""); 1523542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (0 > sdp_send_req(session, reqbuf, reqsize)) { 1524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Error sending data:%s", strerror(errno)); 1525542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1526542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE); 1528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (0 > n) 1529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Read : %d\n", n); 1531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (n == 0 || reqhdr->tid != rsphdr->tid) { 1532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EPROTO; 1533542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1534542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *rspsize = n; 1536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1537542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1538542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 1540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * singly-linked lists (after openobex implementation) 1541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 1542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_append(sdp_list_t *p, void *d) 1543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 154421f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann sdp_list_t *q, *n = malloc(sizeof(sdp_list_t)); 1545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!n) 1547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann n->data = d; 1550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann n->next = 0; 1551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!p) 1553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return n; 1554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (q = p; q->next; q = q->next); 1556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann q->next = n; 1557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return p; 1559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1560542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_remove(sdp_list_t *list, void *d) 1562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *p, *q; 1564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1565542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (q = 0, p = list; p; q = p, p = p->next) 1566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (p->data == d) { 1567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (q) 1568542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann q->next = p->next; 1569542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else 1570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann list = p->next; 1571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(p); 1572542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1574542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1575542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return list; 1576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d, sdp_comp_func_t f) 1579542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *q, *p, *n; 1581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 158221f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann n = malloc(sizeof(sdp_list_t)); 1583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!n) 1584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1585542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann n->data = d; 1586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (q = 0, p = list; p; q = p, p = p->next) 1587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (f(p->data, d) >= 0) 1588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1589542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // insert between q and p; if !q insert at head 1590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (q) 1591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann q->next = n; 1592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else 1593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann list = n; 1594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann n->next = p; 1595542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return list; 1596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1597542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 1599542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Every element of the list points to things which need 1600542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to be free()'d. This method frees the list's contents 1601542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 1602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_list_free(sdp_list_t *list, sdp_free_func_t f) 1603542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *next; 1605542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann while (list) { 1606542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann next = list->next; 1607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (f) 1608542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann f(list->data); 1609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(list); 1610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann list = next; 1611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1614542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int __find_port(sdp_data_t *seq, int proto) 1615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1616542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!seq || !seq->next) 1617542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) { 1620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seq = seq->next; 1621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (seq->dtd) { 1622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT8: 1623542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return seq->val.uint8; 1624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT16: 1625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return seq->val.uint16; 1626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1629542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1630542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1631542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_proto_port(const sdp_list_t *list, int proto) 1632542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1633542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (proto != L2CAP_UUID && proto != RFCOMM_UUID) { 1634542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; 1635542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1636542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1637542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1638542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (; list; list = list->next) { 1639542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *p; 1640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (p = list->data; p; p = p->next) { 1641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *seq = (sdp_data_t *) p->data; 1642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int port = __find_port(seq, proto); 1643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (port) 1644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return port; 1645542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1646542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1648542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1649542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1650542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto) 1651542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1652542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (; list; list = list->next) { 1653542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *p; 1654542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (p = list->data; p; p = p->next) { 1655542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *seq = (sdp_data_t *) p->data; 1656542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (SDP_IS_UUID(seq->dtd) && 1657542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_uuid_to_proto(&seq->val.uuid) == proto) 1658542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return seq->next; 1659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1660542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return NULL; 1662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1664542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap) 1665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *pdlist, *curr; 1667542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *ap = 0; 1668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdlist = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST); 1670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (pdlist == NULL) { 1671542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENODATA; 1672542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1673542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1674542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("AP type : 0%x\n", pdlist->dtd); 1675542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1676542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (; pdlist; pdlist = pdlist->next) { 1677542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *pds = 0; 1678542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (curr = pdlist->val.dataseq; curr; curr = curr->next) 1679542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pds = sdp_list_append(pds, curr->val.dataseq); 1680542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann ap = sdp_list_append(ap, pds); 1681542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1682542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *pap = ap; 1683542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1684542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1685542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1686233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmannint sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap) 1687233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann{ 1688233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann sdp_data_t *pdlist, *curr; 1689233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann sdp_list_t *ap = 0; 1690233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann 1691233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST); 1692233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann if (pdlist == NULL) { 1693233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann errno = ENODATA; 1694233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann return -1; 1695233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann } 1696233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann SDPDBG("AP type : 0%x\n", pdlist->dtd); 1697233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann 1698233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann pdlist = pdlist->val.dataseq; 1699233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann 1700233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann for (; pdlist; pdlist = pdlist->next) { 1701233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann sdp_list_t *pds = 0; 1702233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann for (curr = pdlist->val.dataseq; curr; curr = curr->next) 1703233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann pds = sdp_list_append(pds, curr->val.dataseq); 1704233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann ap = sdp_list_append(ap, pds); 1705233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann } 1706233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann *pap = ap; 1707233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann return 0; 1708233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann} 1709233bd39dee08afc5176b203e6348184da56d7bffMarcel Holtmann 1710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **seqp) 1711542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1712542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *sdpdata = sdp_data_get(rec, attr); 1713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1714542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *seqp = NULL; 1715542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) { 1716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d; 1717542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (d = sdpdata->val.dataseq; d; d = d->next) { 17181f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi uuid_t *u; 17191f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) 1720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto fail; 17211f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi 17221f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi u = malloc(sizeof(uuid_t)); 17231f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi memset(u, 0, sizeof(uuid_t)); 17241f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi *u = d->val.uuid; 17251f9ec47e02cc789ab45c85e855c4f9e377df7e3cClaudio Takahasi *seqp = sdp_list_append(*seqp, u); 1726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail: 1730542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_free(*seqp, free); 1731542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; 1732542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq) 1736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int status = 0, i, len; 1738542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void **dtds, **values; 1739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t uuid16 = SDP_UUID16; 1740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t uuid32 = SDP_UUID32; 1741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t uuid128 = SDP_UUID128; 1742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *p; 1743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1744542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann len = sdp_list_len(seq); 1745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!seq || len == 0) 1746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds = (void **)malloc(len * sizeof(void *)); 1748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values = (void **)malloc(len * sizeof(void *)); 1749542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (p = seq, i = 0; i < len; i++, p = p->next) { 1750542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uuid_t *uuid = (uuid_t *)p->data; 1751542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (uuid) 1752542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (uuid->type) { 1753542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 1754542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[i] = &uuid16; 1755542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[i] = &uuid->value.uuid16; 1756542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1757542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 1758542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[i] = &uuid32; 1759542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[i] = &uuid->value.uuid32; 1760542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1761542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 1762542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[i] = &uuid128; 1763542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[i] = &uuid->value.uuid128; 1764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann default: 1766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 1767542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else { 1770542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 1771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1774542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (status == 0) { 1775542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *data = sdp_seq_alloc(dtds, values, len); 1776542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_replace(rec, aid, data); 1777542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pattern_add_uuidseq(rec, seq); 1778542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1779542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(dtds); 1780542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(values); 1781542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return status; 1782542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1783542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1784542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq) 1785542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1786542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_lang_attr_t *lang; 1787542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *sdpdata, *curr_data; 1788542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1789542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *langSeq = NULL; 1790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST); 1791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (sdpdata == NULL) { 1792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENODATA; 1793542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1794542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1795542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann curr_data = sdpdata->val.dataseq; 1796542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann while (curr_data) { 1797542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *pCode = curr_data; 1798542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *pEncoding = pCode->next; 1799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *pOffset = pEncoding->next; 1800542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (pCode && pEncoding && pOffset) { 180121f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann lang = malloc(sizeof(sdp_lang_attr_t)); 1802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann lang->code_ISO639 = pCode->val.uint16; 1803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann lang->encoding = pEncoding->val.uint16; 1804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann lang->base_offset = pOffset->val.uint16; 1805542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("code_ISO639 : 0x%02x\n", lang->code_ISO639); 1806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("encoding : 0x%02x\n", lang->encoding); 1807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("base_offfset : 0x%02x\n", lang->base_offset); 1808542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *langSeq = sdp_list_append(*langSeq, lang); 1809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann curr_data = pOffset->next; 1811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq) 1816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_profile_desc_t *profDesc; 1818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *sdpdata, *seq; 1819542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1820542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *profDescSeq = NULL; 1821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST); 1822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!sdpdata || !sdpdata->val.dataseq) { 1823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENODATA; 1824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1826542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) { 18270f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann uuid_t *uuid = NULL; 18280f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann uint16_t version = 0x100; 18290f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann 18300f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann if (SDP_IS_UUID(seq->dtd)) { 18310f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann uuid = &seq->val.uuid; 18320f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann } else { 18330f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann sdp_data_t *puuid = seq->val.dataseq; 18340f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann sdp_data_t *pVnum = seq->val.dataseq->next; 18350f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann if (puuid && pVnum) { 18360f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann uuid = &puuid->val.uuid; 18370f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann version = pVnum->val.uint16; 18380f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann } 18390f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann } 18400f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann 18410f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann if (uuid != NULL) { 184221f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann profDesc = malloc(sizeof(sdp_profile_desc_t)); 18430f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann profDesc->uuid = *uuid; 18440f5a5a9580084a3c4e0644ef5cd75689aeb5ff40Marcel Holtmann profDesc->version = version; 1845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#ifdef SDP_DEBUG 1846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_uuid_print(&profDesc->uuid); 1847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Vnum : 0x%04x\n", profDesc->version); 1848542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#endif 1849542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *profDescSeq = sdp_list_append(*profDescSeq, profDesc); 1850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1853542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1854542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1855542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16) 1856542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1857542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d, *curr; 1858542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1859542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *u16 = NULL; 1860542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST); 1861542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (d == NULL) { 1862542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENODATA; 1863542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (curr = d->val.dataseq; curr; curr = curr->next) 1866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *u16 = sdp_list_append(*u16, &curr->val.uint16); 1867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* flexible extraction of basic attributes - Jean II */ 1871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* How do we expect caller to extract predefined data sequences? */ 1872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value) 1873542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1874542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *sdpdata = sdp_data_get(rec, attrid); 1875542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1876542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (sdpdata) 1877542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann /* Verify that it is what the caller expects */ 1878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 || 1879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 || 1880542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 || 1881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdpdata->dtd == SDP_INT32) { 1882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *value = sdpdata->val.uint32; 1883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; 1886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value, int valuelen) 1890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *sdpdata = sdp_data_get(rec, attrid); 1892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (sdpdata) 1893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann /* Verify that it is what the caller expects */ 1894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (sdpdata->dtd == SDP_TEXT_STR8 || sdpdata->dtd == SDP_TEXT_STR16 || sdpdata->dtd == SDP_TEXT_STR32) 1895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (strlen(sdpdata->val.str) < valuelen) { 1896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann strcpy(value, sdpdata->val.str); 1897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; 1900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann#define get_basic_attr(attrID, pAttrValue, fieldName) \ 1904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *data = sdp_data_get(rec, attrID); \ 1905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (data) { \ 1906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *pAttrValue = data->val.fieldName; \ 1907542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; \ 1908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } \ 1909542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; \ 1910542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1911542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid) 1913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid); 1915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid) 1918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid); 1920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1921542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState) 1923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32); 1925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1926542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail) 1928542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1929542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8); 1930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1931542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1932542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo) 1933542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1934542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32); 1935542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState) 1938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32); 1940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 1943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * NOTE that none of the setXXX() functions below will 1944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * actually update the SDP server, unless the 1945542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * {register, update}sdp_record_t() function is invoked. 1946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 1947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd, const void *value) 1949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d = sdp_data_alloc(dtd, value); 1951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (d) { 1952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_replace(rec, attr, d); 1953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 1954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 1955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 1956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 1959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Set the information attributes of the service 1960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by rec. The attributes are 1961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * service name, description and provider name 1962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 1963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov, const char *desc) 1964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (name) 1966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY, SDP_TEXT_STR8, (void *)name); 1967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (prov) 1968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY, SDP_TEXT_STR8, (void *)prov); 1969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (desc) 1970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY, SDP_TEXT_STR8, (void *)desc); 1971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 1972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto) 1974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 1975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *seq = NULL; 1976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void *dtds[10], *values[10]; 1977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void **seqDTDs, **seqs; 1978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int i, seqlen; 1979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *p; 1980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 1981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqlen = sdp_list_len(proto); 1982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqDTDs = (void **)malloc(seqlen * sizeof(void *)); 1983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqs = (void **)malloc(seqlen * sizeof(void *)); 1984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (i = 0, p = proto; p; p = p->next, i++) { 1985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *elt = (sdp_list_t *)p->data; 1986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *s; 1987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int pslen = 0; 1988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (; elt && pslen < sizeof(dtds); elt = elt->next, pslen++) { 1989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *d = (sdp_data_t *)elt->data; 1990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[pslen] = &d->dtd; 1991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (d->dtd) { 1992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 1993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[pslen] = &((uuid_t *)d)->value.uuid16; 1994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1995542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 1996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[pslen] = &((uuid_t *)d)->value.uuid32; 1997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 1998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 1999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[pslen] = &((uuid_t *)d)->value.uuid128; 2000542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT8: 2002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[pslen] = &d->val.uint8; 2003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UINT16: 2005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[pslen] = &d->val.uint16; 2006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ8: 2008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ16: 2009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ32: 2010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[pslen] = d; 2011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // FIXME: more 2013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann s = sdp_seq_alloc(dtds, values, pslen); 2016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (s) { 2017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqDTDs[i] = &s->dtd; 2018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqs[i] = s; 2019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2020542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seq = sdp_seq_alloc(seqDTDs, seqs, seqlen); 2022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(seqDTDs); 2023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(seqs); 2024542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return seq; 2025542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2026542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2027542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2028542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets the access protocols of the service specified 2029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * to the value specified in "access_proto" 2030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Note that if there are alternate mechanisms by 2032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * which the service is accessed, then they should 2033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * be specified as sequences 2034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for accessProtocols has 2036542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set) 2037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the existing sdp_access_proto_t 2039542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified. 2040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2041542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure. 2042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap) 2044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2045542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann const sdp_list_t *p; 2046aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann sdp_data_t *protos = NULL; 2047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (p = ap; p; p = p->next) { 2049aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data); 2050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann protos = sdp_seq_append(protos, seq); 2051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2052aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann 2053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos); 2054aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann 2055aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann return 0; 2056aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann} 2057aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann 2058aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmannint sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap) 2059aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann{ 2060aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann const sdp_list_t *p; 2061aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann sdp_data_t *protos = NULL; 2062aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann 2063aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann for (p = ap; p; p = p->next) { 2064aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data); 2065aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann protos = sdp_seq_append(protos, seq); 2066aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann } 2067aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann 2068aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST, 2069aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL); 2070aa8d087a052ab9c54dde1b0ddaf3a47494ef899aMarcel Holtmann 2071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 2072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the "LanguageBase" attributes of the service record 2076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * record to the value specified in "langAttrList". 2077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * "langAttrList" is a linked list of "sdp_lang_attr_t" 2079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * objects, one for each language in which user visible 2080542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attributes are present in the service record. 2081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2082542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for langAttrList has 2083542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set) 2084542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2085542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting sdp_lang_attr_t 2086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified. 2087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure. 2089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq) 2091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2092542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t uint16 = SDP_UINT16; 2093542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int status = 0, i = 0, seqlen = sdp_list_len(seq); 2094542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void **dtds = (void **)malloc(3 * seqlen * sizeof(void *)); 2095542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void **values = (void **)malloc(3 * seqlen * sizeof(void *)); 2096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann const sdp_list_t *p; 2097542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (p = seq; p; p = p->next) { 2099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_lang_attr_t *lang = (sdp_lang_attr_t *)p->data; 2100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!lang) { 2101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 2102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[i] = &uint16; 2105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[i] = &lang->code_ISO639; 2106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann i++; 2107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[i] = &uint16; 2108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[i] = &lang->encoding; 2109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann i++; 2110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[i] = &uint16; 2111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[i] = &lang->base_offset; 2112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann i++; 2113542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (status == 0) { 2115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen); 2116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq); 2117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(dtds); 2119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(values); 2120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return status; 2121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the "ServiceID" attribute of the service. 2125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is the UUID of the service. 2127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure. 2129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_service_id(sdp_record_t *rec, uuid_t uuid) 2131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (uuid.type) { 2133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 2134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16, &uuid.value.uuid16); 2135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 2137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32, &uuid.value.uuid32); 2138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 2140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128, &uuid.value.uuid128); 2141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pattern_add_uuid(rec, &uuid); 2144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the GroupID attribute of the service record defining a group. 2148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is the UUID of the group. 2150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure. 2152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_group_id(sdp_record_t *rec, uuid_t uuid) 2154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (uuid.type) { 2156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 2157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16, &uuid.value.uuid16); 2158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 2160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32, &uuid.value.uuid32); 2161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 2163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128, &uuid.value.uuid128); 2164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pattern_add_uuid(rec, &uuid); 2167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set the ProfileDescriptorList attribute of the service record 2171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record to the value specified in "profileDesc". 2172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Each element in the list is an object of type 2174542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_profile_desc_t which is a definition of the 2175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Bluetooth profile that this service conforms to. 2176542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2177542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Using a value of NULL for profileDesc has 2178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * effect of removing this attribute (if previously set) 2179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function replaces the exisiting ProfileDescriptorList 2181542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * structure (if any) with the new one specified. 2182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if successful or -1 if there is a failure. 2184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2185542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles) 2186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int status = 0; 2188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t uuid16 = SDP_UUID16; 2189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t uuid32 = SDP_UUID32; 2190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t uuid128 = SDP_UUID128; 2191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t uint16 = SDP_UINT16; 2192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int i = 0, seqlen = sdp_list_len(profiles); 2193542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void **seqDTDs = (void **)malloc(seqlen * sizeof(void *)); 2194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void **seqs = (void **)malloc(seqlen * sizeof(void *)); 2195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann const sdp_list_t *p; 2196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (p = profiles; p; p = p->next) { 2198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *seq; 2199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void *dtds[2], *values[2]; 2200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_profile_desc_t *profile = (sdp_profile_desc_t *)p->data; 2201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!profile) { 2202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 2203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2205542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (profile->uuid.type) { 2206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 2207542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[0] = &uuid16; 2208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[0] = &profile->uuid.value.uuid16; 2209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2210542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 2211542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[0] = &uuid32; 2212542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[0] = &profile->uuid.value.uuid32; 2213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2214542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 2215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[0] = &uuid128; 2216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[0] = &profile->uuid.value.uuid128; 2217542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2218542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann default: 2219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 2220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2222542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtds[1] = &uint16; 2223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[1] = &profile->version; 2224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seq = sdp_seq_alloc(dtds, values, 2); 2225542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (seq) { 2226542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqDTDs[i] = &seq->dtd; 2227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqs[i] = seq; 2228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pattern_add_uuid(rec, &profile->uuid); 2229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2230542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann i++; 2231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (status == 0) { 2233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen); 2234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq); 2235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(seqDTDs); 2237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(seqs); 2238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return status; 2239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sets various URL attributes of the service 2243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pointed to by record. The URL include 2244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * client: a URL to the client's 2246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * platform specific (WinCE, PalmOS) executable 2247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * code that can be used to access this service. 2248542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2249542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * doc: a URL pointing to service documentation 2250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * icon: a URL to an icon that can be used to represent 2252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * this service. 2253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Note that you need to pass NULL for any URLs 2255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * that you don't want to set or remove 2256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc, const char *icon) 2258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client); 2260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc); 2261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon); 2262542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The code in this function is executed only once per 2266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * thread. We compute the actual bit value of the Bluetooth 2267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * base UUID which is a string defined in bt_std_values.h 2268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * and is assumed to be of the standard form with "-" separators. 2269542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The algorithm however converts the string to 4 unsigned longs 2271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * using the strtoul() and assigns the values in sequence to 2272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * the 128bit value 2273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2274542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuint128_t *sdp_create_base_uuid(void) 2275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 22763f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann uint128_t *base_uuid; 2277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann char baseStr[128]; 2278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int delim = '-'; 2279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned long dataLongValue; 2280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann char *delimPtr; 2281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann char *dataPtr; 2282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann char temp[10]; 2283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int toBeCopied; 2284cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *data; 2285542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 22863f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann strcpy(baseStr, BASE_UUID); 22873f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann base_uuid = malloc(sizeof(uint128_t)); 22883f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann if (!base_uuid) 22893f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann return NULL; 22903f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann 22913f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann data = base_uuid->data; 22923f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memset(data, '\0', sizeof(uint128_t)); 22933f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memset(temp, '\0', 10); 22943f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann dataPtr = baseStr; 22953f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann delimPtr = NULL; 22963f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann delimPtr = strchr(dataPtr, delim); 22973f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann toBeCopied = delimPtr - dataPtr; 22983f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann if (toBeCopied != 8) { 22993f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann SDPDBG("To be copied(1) : %d\n", toBeCopied); 23003f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann free(base_uuid); 23013f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann return NULL; 2302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 23033f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann strncpy(temp, dataPtr, toBeCopied); 23043f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann dataLongValue = htonl(strtoul(temp, NULL, 16)); 23053f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memcpy(&data[0], &dataLongValue, 4); 23063f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann 23073f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann /* 23083f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann * Get the next 4 bytes (note that there is a "-" 23093f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann * between them now) 23103f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann */ 23113f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memset(temp, '\0', 10); 23123f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann dataPtr = delimPtr + 1; 23133f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann delimPtr = strchr(dataPtr, delim); 23143f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann toBeCopied = delimPtr - dataPtr; 23153f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann if (toBeCopied != 4) { 23163f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann SDPDBG("To be copied(2) : %d\n", toBeCopied); 23173f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann free(base_uuid); 23183f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann return NULL; 23193f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann } 23203f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann strncpy(temp, dataPtr, toBeCopied); 23213f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann dataPtr = delimPtr + 1; 23223f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann delimPtr = strchr(dataPtr, delim); 23233f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann toBeCopied = delimPtr - dataPtr; 23243f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann if (toBeCopied != 4) { 23253f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann SDPDBG("To be copied(3) : %d\n", toBeCopied); 23263f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann free(base_uuid); 23273f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann return NULL; 23283f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann } 23293f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann strncat(temp, dataPtr, toBeCopied); 23303f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann dataLongValue = htonl(strtoul(temp, NULL, 16)); 23313f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memcpy(&data[4], &dataLongValue, 4); 23323f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann 23333f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann /* 23343f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann * Get the last 4 bytes (note that there are 6 bytes 23353f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann * after the last separator, which is truncated (2+4) 23363f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann */ 23373f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memset(temp, '\0', 10); 23383f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann dataPtr = delimPtr + 1; 23393f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann dataPtr = delimPtr + 1; 23403f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann delimPtr = strchr(dataPtr, delim); 23413f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann toBeCopied = delimPtr - dataPtr; 23423f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann if (toBeCopied != 4) { 23433f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann SDPDBG("To be copied(4) : %d\n", toBeCopied); 23443f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann free(base_uuid); 23453f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann return NULL; 23463f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann } 23473f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann strncpy(temp, dataPtr, toBeCopied); 23483f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann strncat(temp, (delimPtr + 1), 4); 23493f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann dataLongValue = htonl(strtoul(temp, NULL, 16)); 23503f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memcpy(&data[8], &dataLongValue, 4); 23513f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann dataLongValue = htonl(strtoul(delimPtr + 5, NULL, 16)); 23523f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memcpy(&data[12], &dataLongValue, 4); 23533f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann 23543f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann return base_uuid; 2355542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2356542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2357542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val) 2358542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2359542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(u, 0, sizeof(uuid_t)); 2360542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u->type = SDP_UUID16; 2361542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u->value.uuid16 = val; 2362542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return u; 2363542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2364542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2365542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val) 2366542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2367542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(u, 0, sizeof(uuid_t)); 2368542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u->type = SDP_UUID32; 2369542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u->value.uuid32 = val; 2370542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return u; 2371542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2372542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2373542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid128_create(uuid_t *u, const void *val) 2374542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2375542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(u, 0, sizeof(uuid_t)); 2376542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann u->type = SDP_UUID128; 2377542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&u->value.uuid128, val, sizeof(uint128_t)); 2378542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return u; 2379542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2380542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2381542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2382542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function 2383542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1 2384542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2385542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid16_cmp(const void *p1, const void *p2) 2386542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2387542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann const uuid_t *u1 = (const uuid_t *)p1; 2388542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann const uuid_t *u2 = (const uuid_t *)p2; 2389542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t)); 2390542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2391542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2392542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2393542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * UUID comparison function 2394542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns 0 if uuidValue1 == uuidValue2 else -1 2395542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2396542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_cmp(const void *p1, const void *p2) 2397542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2398542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann const uuid_t *u1 = (const uuid_t *)p1; 2399542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann const uuid_t *u2 = (const uuid_t *)p2; 2400542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t)); 2401542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2402542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2403542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2404542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 128 to 16 bit and 32 to 16 bit UUID conversion functions 2405542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * yet to be implemented. Note that the input is in NBO in 2406542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * both 32 and 128 bit UUIDs and conversion is needed 2407542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2408542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid16_to_uuid128(uuid_t *uuid128, uuid_t *uuid16) 2409542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2410542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann /* 2411542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * We have a 16 bit value, which needs to be added to 2412542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base 2413542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2414542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned short data1; 2415542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2416542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // allocate a 128bit UUID and init to the Bluetooth base UUID 24173f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann uuid128->value.uuid128 = bluetooth_base_uuid; 2418542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uuid128->type = SDP_UUID128; 2419542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2420542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // extract bytes 2 and 3 of 128bit BT base UUID 24213f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memcpy(&data1, &bluetooth_base_uuid.data[2], 2); 2422542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2423542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // add the given UUID (16 bits) 2424542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data1 += htons(uuid16->value.uuid16); 2425542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2426542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // set bytes 2 and 3 of the 128 bit value 2427542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&uuid128->value.uuid128.data[2], &data1, 2); 2428542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2429542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2430542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_uuid32_to_uuid128(uuid_t *uuid128, uuid_t *uuid32) 2431542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2432542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann /* 2433542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * We have a 32 bit value, which needs to be added to 2434542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base 2435542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2436542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann unsigned int data0; 2437542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2438542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // allocate a 128bit UUID and init to the Bluetooth base UUID 24393f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann uuid128->value.uuid128 = bluetooth_base_uuid; 2440542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uuid128->type = SDP_UUID128; 2441542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2442542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // extract first 4 bytes 24433f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann memcpy(&data0, &bluetooth_base_uuid.data[0], 4); 2444542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2445542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // add the given UUID (32bits) 2446542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data0 += htonl(uuid32->value.uuid32); 2447542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2448542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // set the 4 bytes of the 128 bit value 2449542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&uuid128->value.uuid128.data[0], &data0, 4); 2450542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2451542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2452542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannuuid_t *sdp_uuid_to_uuid128(uuid_t *uuid) 2453542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 245421f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann uuid_t *uuid128 = bt_malloc(sizeof(uuid_t)); 2455542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(uuid128, 0, sizeof(uuid_t)); 2456542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (uuid->type) { 2457542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID128: 2458542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *uuid128 = *uuid; 2459542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2460542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID32: 2461542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_uuid32_to_uuid128(uuid128, uuid); 2462542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2463542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_UUID16: 2464542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_uuid16_to_uuid128(uuid128, uuid); 2465542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2466542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2467542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return uuid128; 2468542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2469542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2470542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2471542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * converts a 128-bit uuid to a 16/32-bit one if possible 2472542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * returns true if uuid contains a 16/32-bit UUID at exit 2473542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2474542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid128_to_uuid(uuid_t *uuid) 2475542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 24763f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann uint128_t *b = &bluetooth_base_uuid; 2477542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint128_t *u = &uuid->value.uuid128; 2478542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint32_t data; 24793f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann int i; 2480a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann 2481542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (uuid->type != SDP_UUID128) 2482542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 1; 2483a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann 2484542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (i = 4; i < sizeof(b->data); i++) 2485542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (b->data[i] != u->data[i]) 2486542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 2487a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann 2488542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(&data, u->data, 4); 2489542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data = htonl(data); 2490542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (data <= 0xffff) { 2491542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uuid->type = SDP_UUID16; 24923f8700636d21bb868c2dbb8d2403e550a7750cebMarcel Holtmann uuid->value.uuid16 = (uint16_t) data; 2493542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } else { 2494542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uuid->type = SDP_UUID32; 2495542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uuid->value.uuid32 = data; 2496542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2497542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 1; 2498542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2499542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2500542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2501542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * convert a UUID to the 16-bit short-form 2502542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2503542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_uuid_to_proto(uuid_t *uuid) 2504542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2505542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uuid_t u = *uuid; 2506a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann if (sdp_uuid128_to_uuid(&u)) { 2507a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann switch (u.type) { 2508a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann case SDP_UUID16: 2509a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann return u.value.uuid16; 2510a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann case SDP_UUID32: 2511a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann return u.value.uuid32; 2512a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann } 2513a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708Marcel Holtmann } 2514542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 2515542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2516542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2517542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2518542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This function appends data to the PDU buffer "dst" from source "src". 2519542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The data length is also computed and set. 2520542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Should the PDU length exceed 2^8, then sequence type is 2521542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * set accordingly and the data is memmove()'d. 2522542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2523cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannvoid sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len) 2524542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2525cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *p = dst->data; 2526aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann uint8_t dtd = *(uint8_t *) p; 2527542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2528542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Append src size: %d\n", len); 2529542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Append dst size: %d\n", dst->data_size); 2530542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Dst buffer size: %d\n", dst->buf_size); 2531542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (dst->data_size + len > dst->buf_size) { 2532542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int need = SDP_PDU_CHUNK_SIZE * ((len / SDP_PDU_CHUNK_SIZE) + 1); 2533cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann dst->data = realloc(dst->data, dst->buf_size + need); 2534542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2535542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Realloc'ing : %d\n", need); 2536542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2537542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (dst->data == NULL) { 2538542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Realloc fails \n"); 2539542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2540542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dst->buf_size += need; 2541542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2542542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (dst->data_size == 0 && dtd == 0) { 2543542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // create initial sequence 2544542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *(uint8_t *)p = SDP_SEQ8; 2545542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint8_t); 2546542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dst->data_size += sizeof(uint8_t); 2547542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // reserve space for sequence size 2548542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint8_t); 2549542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dst->data_size += sizeof(uint8_t); 2550542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2551542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2552542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(dst->data + dst->data_size, data, len); 2553542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dst->data_size += len; 2554542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2555542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dtd = *(uint8_t *)dst->data; 2556542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) { 2557542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann short offset = sizeof(uint8_t) + sizeof(uint8_t); 2558542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memmove(dst->data + offset + 1, dst->data + offset, dst->data_size - offset); 2559542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p = dst->data; 2560aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann *(uint8_t *) p = SDP_SEQ16; 2561542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint8_t); 2562542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dst->data_size += 1; 2563542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2564542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p = dst->data; 2565aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann dtd = *(uint8_t *) p; 2566542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint8_t); 2567542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann switch (dtd) { 2568542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ8: 2569aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann *(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t); 2570542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2571542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ16: 2572aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *) p); 2573542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2574542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann case SDP_SEQ32: 2575aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *) p); 2576542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann break; 2577542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2578542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2579542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2580542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) 2581542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2582997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann uint8_t buf[256]; 2583542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_buf_t append; 2584542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2585997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann memset(&append, 0, sizeof(sdp_buf_t)); 2586542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann append.data = buf; 2587542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann append.buf_size = sizeof(buf); 2588542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann append.data_size = 0; 2589997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann 2590542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_set_attrid(&append, d->attrId); 2591542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_gen_pdu(&append, d); 2592542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_append_to_buf(pdu, append.data, append.data_size); 2593542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2594542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2595542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2596542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Registers an sdp record. 2597542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 2598542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * It is incorrect to call this method on a record that 2599542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * has been already registered with the server. 2600542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 26018b11908eac4e0b4e14534ec2d44ae62806fdfd2fStephen Crane * Returns zero on success, otherwise -1 (and sets errno). 2602542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 260382817924a25fb0eaaeb9824372106870c45c9db9Marcel 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) 2604542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2605cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *req, *rsp, *p; 2606cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t reqsize, rspsize; 2607542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pdu_hdr_t *reqhdr, *rsphdr; 260882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann int status; 2609542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2610542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG(""); 2611542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2612542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!session->local) { 2613542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EREMOTE; 2614542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 2615542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2616cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann req = malloc(SDP_REQ_BUFFER_SIZE); 2617cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann rsp = malloc(SDP_RSP_BUFFER_SIZE); 2618542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (req == NULL || rsp == NULL) { 2619542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 2620542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENOMEM; 2621542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 2622542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 262382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2624542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr = (sdp_pdu_hdr_t *)req; 2625542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->pdu_id = SDP_SVC_REGISTER_REQ; 2626542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->tid = htons(sdp_gen_tid(session)); 2627542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize = sizeof(sdp_pdu_hdr_t) + 1; 2628542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p = req + sizeof(sdp_pdu_hdr_t); 262982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2630fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann if (bacmp(device, BDADDR_ANY)) { 2631fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann *p++ = flags | SDP_DEVICE_RECORD; 2632fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann bacpy((bdaddr_t *) p, device); 2633fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann p += sizeof(bdaddr_t); 26346db62cfa3a8de69270cc5e5689b633f43c02e041Marcel Holtmann reqsize += sizeof(bdaddr_t); 2635fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann } else 2636fb1557c4111ca9993e4927af6f65bdbf9c2fa8ecMarcel Holtmann *p++ = flags; 263782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 263882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann memcpy(p, data, size); 263982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann reqsize += size; 2640542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 2641542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2642542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize); 2643542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (status < 0) 2644542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 264582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2646aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann rsphdr = (sdp_pdu_hdr_t *) rsp; 2647542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p = rsp + sizeof(sdp_pdu_hdr_t); 264882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2649a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi if (rsphdr->pdu_id == SDP_ERROR_RSP) { 2650a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi /* Invalid service record */ 2651a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi errno = EINVAL; 2652a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi status = -1; 2653a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi } else if (rsphdr->pdu_id != SDP_SVC_REGISTER_RSP) { 2654a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi errno = EPROTO; 2655a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi status = -1; 2656a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi } else { 265782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann if (handle) 265882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann *handle = ntohl(bt_get_unaligned((uint32_t *) p)); 2659542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 266082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2661542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend: 2662542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (req) 2663542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(req); 266482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2665542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rsp) 2666542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(rsp); 266782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2668542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return status; 2669542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2670542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 267182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags) 267282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{ 267382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann sdp_buf_t pdu; 267482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann uint32_t handle; 267582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann int err; 267682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 267782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann SDPDBG(""); 267882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 267982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann if (rec->handle && rec->handle != 0xffffffff) { 268082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann uint32_t handle = rec->handle; 268182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); 268282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); 268382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann } 268482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 268582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann if (sdp_gen_record_pdu(rec, &pdu) < 0) { 268682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann errno = ENOMEM; 268782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann return -1; 268882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann } 268982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 269082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann err = sdp_device_record_register_binary(session, device, 269182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann pdu.data, pdu.data_size, flags, &handle); 269282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 269382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann free(pdu.data); 269482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 269582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann if (err == 0) { 269682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); 269782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann rec->handle = handle; 269882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); 269982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann } 270082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 270182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann return err; 270282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann} 270382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2704a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags) 2705a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{ 2706a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann return sdp_device_record_register(session, BDADDR_ANY, rec, flags); 2707a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann} 2708a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann 2709542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2710542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * unregister a service record 2711542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 271282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle) 2713542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2714cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *reqbuf, *rspbuf, *p; 2715cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t reqsize = 0, rspsize = 0; 2716542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pdu_hdr_t *reqhdr, *rsphdr; 271782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann int status; 2718542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2719542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG(""); 2720542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2721542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (handle == SDP_SERVER_RECORD_HANDLE) { 2722542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; 2723542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 2724542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 272582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2726542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!session->local) { 2727542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EREMOTE; 2728542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 2729542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 273082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2731cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 2732cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 2733542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!reqbuf || !rspbuf) { 2734542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENOMEM; 2735542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 2736542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 2737542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2738aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann reqhdr = (sdp_pdu_hdr_t *) reqbuf; 2739542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->pdu_id = SDP_SVC_REMOVE_REQ; 2740542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->tid = htons(sdp_gen_tid(session)); 2741542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2742542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p = reqbuf + sizeof(sdp_pdu_hdr_t); 2743542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize = sizeof(sdp_pdu_hdr_t); 2744aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htonl(handle), (uint32_t *) p); 2745542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += sizeof(uint32_t); 2746542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2747542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 2748542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 2749a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi if (status < 0) 2750a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi goto end; 2751a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi 2752a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi rsphdr = (sdp_pdu_hdr_t *) rspbuf; 2753a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi p = rspbuf + sizeof(sdp_pdu_hdr_t); 2754a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi status = bt_get_unaligned((uint16_t *) p); 275582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2756a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi if (rsphdr->pdu_id == SDP_ERROR_RSP) { 2757a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi /* For this case the status always is invalid record handle */ 2758a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi errno = EINVAL; 2759a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi status = -1; 2760a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi } else if (rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) { 2761a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi errno = EPROTO; 2762a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi status = -1; 2763a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi } 2764542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend: 2765542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (reqbuf) 2766542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(reqbuf); 276782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2768542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rspbuf) 2769542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(rspbuf); 277082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2771542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return status; 2772542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2773542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 277482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec) 277582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{ 277682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann int err; 277782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 277882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann err = sdp_device_record_unregister_binary(session, device, rec->handle); 277982817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann if (err == 0) 278082817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann sdp_record_free(rec); 278182817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 278282817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann return err; 278382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann} 278482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2785a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) 2786a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{ 2787a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann return sdp_device_record_unregister(session, BDADDR_ANY, rec); 2788a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann} 2789a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann 2790542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2791542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * modify an existing service record 2792542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 279382817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmannint sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size) 279482817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann{ 279582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann return -1; 279682817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann} 279782817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2798a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec) 2799542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2800cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *reqbuf, *rspbuf, *p; 2801cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t reqsize, rspsize; 2802542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pdu_hdr_t *reqhdr, *rsphdr; 2803542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint32_t handle; 2804542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_buf_t pdu; 280582817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann int status; 2806542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2807542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG(""); 280882817924a25fb0eaaeb9824372106870c45c9db9Marcel Holtmann 2809542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann handle = rec->handle; 2810542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2811542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (handle == SDP_SERVER_RECORD_HANDLE) { 2812542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; 2813542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 2814542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2815542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!session->local) { 2816542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EREMOTE; 2817542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 2818542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2819cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 2820cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 2821542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!reqbuf || !rspbuf) { 2822542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENOMEM; 2823542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 2824542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 2825542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2826aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann reqhdr = (sdp_pdu_hdr_t *) reqbuf; 2827542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->pdu_id = SDP_SVC_UPDATE_REQ; 2828542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->tid = htons(sdp_gen_tid(session)); 2829542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2830cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann p = reqbuf + sizeof(sdp_pdu_hdr_t); 2831542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize = sizeof(sdp_pdu_hdr_t); 2832542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2833aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htonl(handle), (uint32_t *) p); 2834542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += sizeof(uint32_t); 2835542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann p += sizeof(uint32_t); 2836542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2837c5621bfbf9071ed359d904bdd91308f6599dc5e5Claudio Takahasi if (sdp_gen_record_pdu(rec, &pdu) < 0) { 2838542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENOMEM; 2839542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 2840542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 2841542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2842542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(p, pdu.data, pdu.data_size); 2843542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += pdu.data_size; 2844c5621bfbf9071ed359d904bdd91308f6599dc5e5Claudio Takahasi free(pdu.data); 2845542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2846542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 2847542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 2848a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi if (status < 0) 2849a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi goto end; 2850542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2851542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Send req status : %d\n", status); 2852542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2853a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi rsphdr = (sdp_pdu_hdr_t *) rspbuf; 2854a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi p = rspbuf + sizeof(sdp_pdu_hdr_t); 2855a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi status = bt_get_unaligned((uint16_t *) p); 2856a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi 2857a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi if (rsphdr->pdu_id == SDP_ERROR_RSP) { 2858a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi /* The status can be invalid sintax or invalid record handle */ 2859a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi errno = EINVAL; 2860a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi status = -1; 2861a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi } else if (rsphdr->pdu_id != SDP_SVC_UPDATE_RSP) { 2862a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi errno = EPROTO; 2863a7c82c586998da5b64e680a9027a6f5aeba915f5Claudio Takahasi status = -1; 2864542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2865542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannend: 2866542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (reqbuf) 2867542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(reqbuf); 2868542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rspbuf) 2869542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(rspbuf); 2870542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return status; 2871542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2872542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2873a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmannint sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) 2874a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann{ 2875a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann return sdp_device_record_update(session, BDADDR_ANY, rec); 2876a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann} 2877a1454c0f12421da1849ca347f8a30d084778d679Marcel Holtmann 2878542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_record_t *sdp_record_alloc() 2879542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 288021f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann sdp_record_t *rec = malloc(sizeof(sdp_record_t)); 2881542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset((void *)rec, 0, sizeof(sdp_record_t)); 2882542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rec->handle = 0xffffffff; 2883542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return rec; 2884542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2885542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2886542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2887542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Free the contents of a service record 2888542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2889542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_record_free(sdp_record_t *rec) 2890542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2891542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_free(rec->attrlist, (sdp_free_func_t)sdp_data_free); 2892542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_free(rec->pattern, free); 2893542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(rec); 2894542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2895542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2896542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid) 2897542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2898542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid); 2899542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2900542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("SvcRec : 0x%lx\n", (unsigned long)rec); 2901542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern)); 2902542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Trying to add : 0x%lx\n", (unsigned long)uuid128); 2903542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2904542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL) 2905542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp); 2906542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann else 290721f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann bt_free(uuid128); 2908542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2909542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern)); 2910542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2911542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2912542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannvoid sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq) 2913542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2914542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (; seq; seq = seq->next) { 2915542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uuid_t *uuid = (uuid_t *)seq->data; 2916542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pattern_add_uuid(rec, uuid); 2917542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2918542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2919542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2920542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2921542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Extract a sequence of service record handles from a PDU buffer 2922542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * and add the entries to a sdp_list_t. Note that the service record 2923542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * handles are not in "data element sequence" form, but just like 2924542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * an array of service handles 2925542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2926cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic void extract_record_handle_seq(uint8_t *pdu, sdp_list_t **seq, int count, int *scanned) 2927542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2928542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *pSeq = *seq; 2929cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *pdata = pdu; 2930542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int n; 2931542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2932542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (n = 0; n < count; n++) { 293321f2a5244f0c6195e17ff71868328bc71d77f4d9Marcel Holtmann uint32_t *pSvcRec = malloc(sizeof(uint32_t)); 2934aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann *pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata)); 2935542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pSeq = sdp_list_append(pSeq, pSvcRec); 2936542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += sizeof(uint32_t); 2937542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *scanned += sizeof(uint32_t); 2938542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2939542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *seq = pSeq; 2940542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2941542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 2942542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Generate the attribute sequence pdu form 2943542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * from sdp_list_t elements. Return length of attr seq 2944542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 2945cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd) 2946542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2947542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_t *dataseq; 2948542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void **types, **values; 2949542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_buf_t buf; 2950542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int i, seqlen = sdp_list_len(seq); 2951542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // Fill up the value and the dtd arrays 2953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG(""); 2954a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmann 2955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset(&buf, 0, sizeof(sdp_buf_t)); 2956997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann buf.data = malloc(256); 2957997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann buf.buf_size = 256; 2958997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann 2959997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann if (!buf.data) 2960997f54c70b25706839544018ad15a718911eb45fMarcel Holtmann return -ENOMEM; 2961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Seq length : %d\n", seqlen); 2963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann types = malloc(seqlen * sizeof(void *)); 2965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values = malloc(seqlen * sizeof(void *)); 2966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann for (i = 0; i < seqlen; i++) { 2967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann void *data = seq->data; 2968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann types[i] = &dtd; 2969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (SDP_IS_UUID(dtd)) 2970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann data = &((uuid_t *)data)->value; 2971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann values[i] = data; 2972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seq = seq->next; 2973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 2974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann dataseq = sdp_seq_alloc(types, values, seqlen); 2976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Data Seq : 0x%p\n", seq); 2977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqlen = sdp_gen_pdu(&buf, dataseq); 2978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Copying : %d\n", buf.data_size); 2979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(dst, buf.data, buf.data_size); 2980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_data_free(dataseq); 2982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(types); 2984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(values); 2985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(buf.data); 2986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return seqlen; 2987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2989cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq) 2990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2991cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uuid_t *uuid = (uuid_t *) seq->data; 2992542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return gen_dataseq_pdu(dst, seq, uuid->type); 2993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 2995cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType) 2996542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 2997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return gen_dataseq_pdu(dst, seq, dataType); 2998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 2999542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3000113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmanntypedef struct { 3001113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann uint8_t length; 3002113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann unsigned char data[16]; 3003113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann} __attribute__ ((packed)) sdp_cstate_t; 3004113a53acaec2519108f0cab944687b7abc537e74Marcel Holtmann 3005cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmannstatic int copy_cstate(uint8_t *pdata, const sdp_cstate_t *cstate) 3006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 3007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (cstate) { 3008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *pdata++ = cstate->length; 3009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(pdata, cstate->data, cstate->length); 3010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return cstate->length + 1; 3011542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3012542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *pdata = 0; 3013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 1; 3014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 3015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 3017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service search request. 3018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT : 3020542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 302141064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim * sdp_list_t *search 3022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Singly linked list containing elements of the search 3023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16) 3024542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * of the service to be searched 3025542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3026542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * uint16_t max_rec_num 3027542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * A 16 bit integer which tells the service, the maximum 3028542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * entries that the client can handle in the response. The 3029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * server is obliged not to return > max_rec_num entries 3030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT : 3032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * int return value 3034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 0: 3035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The request completed successfully. This does not 3036542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * mean the requested services were found 3037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * -1: 3038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * On any failure and sets errno 3039542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_list_t **rsp_list 3041542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This variable is set on a successful return if there are 3042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * non-zero service handles. It is a singly linked list of 304328b4f0aea5b15ed7c0acd17ab79705a38ffe7c2fStephen Crane * service record handles (uint16_t) 3044542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 3045542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, 3046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint16_t max_rec_num, sdp_list_t **rsp) 3047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 3048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int status = 0; 3049cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t reqsize = 0, _reqsize; 3050cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t rspsize = 0, rsplen; 3051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int seqlen = 0; 3052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int scanned, total_rec_count, rec_count; 3053cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *pdata, *_pdata; 3054cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *reqbuf, *rspbuf; 3055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pdu_hdr_t *reqhdr, *rsphdr; 3056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_cstate_t *cstate = NULL; 3057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 3059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 3060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!reqbuf || !rspbuf) { 3061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENOMEM; 3062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 3063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 3064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3065aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann reqhdr = (sdp_pdu_hdr_t *) reqbuf; 3066542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->pdu_id = SDP_SVC_SEARCH_REQ; 3067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata = reqbuf + sizeof(sdp_pdu_hdr_t); 3068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize = sizeof(sdp_pdu_hdr_t); 3069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // add service class IDs for search 3071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqlen = gen_searchseq_pdu(pdata, search); 3072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Data seq added : %d\n", seqlen); 3074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // set the length and increment the pointer 3076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += seqlen; 3077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += seqlen; 3078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3079542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // specify the maximum svc rec count that client expects 3080aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata); 3081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += sizeof(uint16_t); 3082542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += sizeof(uint16_t); 3083542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3084542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann _reqsize = reqsize; 3085542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann _pdata = pdata; 3086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *rsp = NULL; 3087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann do { 3089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // Add continuation state or NULL (first time) 3090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize = _reqsize + copy_cstate(_pdata, cstate); 3091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3092542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // Set the request header's param length 3093542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 3094542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3095542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->tid = htons(sdp_gen_tid(session)); 3096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann /* 3097542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Send the request, wait for response and if 3098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * no error, set the appropriate values and return 3099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 3100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 3101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (status < 0) 3102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 3103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rsplen = 0; 3105aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann rsphdr = (sdp_pdu_hdr_t *) rspbuf; 3106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rsplen = ntohs(rsphdr->plen); 3107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rsphdr->pdu_id == SDP_ERROR_RSP) { 3109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Status : 0x%x\n", rsphdr->pdu_id); 3110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 3111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 3112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3113542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann scanned = 0; 3114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata = rspbuf + sizeof(sdp_pdu_hdr_t); 3115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // net service record match count 3117aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 3118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += sizeof(uint16_t); 3119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann scanned += sizeof(uint16_t); 3120aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 3121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += sizeof(uint16_t); 3122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann scanned += sizeof(uint16_t); 3123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Total svc count: %d\n", total_rec_count); 3125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Current svc count: %d\n", rec_count); 3126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("ResponseLength: %d\n", rsplen); 3127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!rec_count) { 3129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 3130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 3131542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3132542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann extract_record_handle_seq(pdata, rsp, rec_count, &scanned); 3133542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("BytesScanned : %d\n", scanned); 3134542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rsplen > scanned) { 3136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t cstate_len; 3137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned; 3139aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann cstate_len = *(uint8_t *) pdata; 3140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (cstate_len > 0) { 3141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann cstate = (sdp_cstate_t *)pdata; 3142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Cont state length: %d\n", cstate_len); 3143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } else 3144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann cstate = NULL; 3145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } while (cstate); 3147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3148a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannend: 3149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (reqbuf) 3150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(reqbuf); 3151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rspbuf) 3152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(rspbuf); 3153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return status; 3155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 3156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 3158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service attribute request. 3159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT : 3161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * uint32_t handle 3163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The handle of the service for which the attribute(s) are 3164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * requested 3165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_attrreq_type_t reqtype 3167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Attribute identifiers are 16 bit unsigned integers specified 3168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * in one of 2 ways described below : 3169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers 3170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * They are the actual attribute identifiers in ascending order 3171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * SDP_ATTR_REQ_RANGE - 32bit identifier range 3173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The high-order 16bits is the start of range 3174542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * the low-order 16bits are the end of range 3175542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 0x0000 to 0xFFFF gets all attributes 3176542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3177542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_list_t *attrid 3178542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Singly linked list containing attribute identifiers desired. 3179542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) 3180542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) 3181542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3182542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT : 3183542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * return sdp_record_t * 3184542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 0: 3185542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * On any error and sets errno 3186542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * !0: 3187542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The service record 3188542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 3189542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannsdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, 3190542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_attrreq_type_t reqtype, const sdp_list_t *attrids) 3191542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 3192542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int status = 0; 3193cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t reqsize = 0, _reqsize; 3194cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t rspsize = 0, rsp_count; 3195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int attr_list_len = 0; 3196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int seqlen = 0; 3197cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *pdata, *_pdata; 3198cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *reqbuf, *rspbuf; 3199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pdu_hdr_t *reqhdr, *rsphdr; 3200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_cstate_t *cstate = NULL; 3201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t cstate_len = 0; 3202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_buf_t rsp_concat_buf; 3203542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_record_t *rec = 0; 3204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3205542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) { 3206542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; 3207542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 3208542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3209542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3210cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 3211cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 3212542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!reqbuf || !rspbuf) { 3213542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENOMEM; 3214542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 3215542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 3216542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3217aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann memset((char *) &rsp_concat_buf, 0, sizeof(sdp_buf_t)); 3218aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann reqhdr = (sdp_pdu_hdr_t *) reqbuf; 3219542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->pdu_id = SDP_SVC_ATTR_REQ; 3220542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3221542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata = reqbuf + sizeof(sdp_pdu_hdr_t); 3222542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize = sizeof(sdp_pdu_hdr_t); 3223542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3224542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // add the service record handle 3225aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htonl(handle), (uint32_t *) pdata); 3226542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += sizeof(uint32_t); 3227542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += sizeof(uint32_t); 3228542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3229542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // specify the response limit 3230aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htons(65535), (uint16_t *) pdata); 3231542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += sizeof(uint16_t); 3232542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += sizeof(uint16_t); 3233542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3234542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // get attr seq PDU form 3235542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqlen = gen_attridseq_pdu(pdata, attrids, 3236542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32); 3237542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (seqlen == -1) { 3238542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; 3239542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 3240542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 3241542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3242542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += seqlen; 3243542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += seqlen; 3244542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Attr list length : %d\n", seqlen); 3245542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3246542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // save before Continuation State 3247542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann _pdata = pdata; 3248542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann _reqsize = reqsize; 3249542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3250542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann do { 3251542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // add NULL continuation state 3252542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize = _reqsize + copy_cstate(_pdata, cstate); 3253542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3254542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // set the request header's param length 3255542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->tid = htons(sdp_gen_tid(session)); 3256542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 3257542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3258542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 3259542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (status < 0) 3260542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 3261542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rsp_count = 0; 3262aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann rsphdr = (sdp_pdu_hdr_t *) rspbuf; 3263542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rsphdr->pdu_id == SDP_ERROR_RSP) { 3264542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id); 3265542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 3266542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 3267542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3268542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata = rspbuf + sizeof(sdp_pdu_hdr_t); 3269aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 3270542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann attr_list_len += rsp_count; 3271542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += sizeof(uint16_t); 3272542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3273542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // if continuation state set need to re-issue request before parsing 3274aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann cstate_len = *(uint8_t *) (pdata + rsp_count); 3275542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3276542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Response id : %d\n", rsphdr->pdu_id); 3277542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Attrlist byte count : %d\n", rsp_count); 3278542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("sdp_cstate_t length : %d\n", cstate_len); 3279542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3280542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann /* 3281542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * a split response: concatenate intermediate responses 3282542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * and the last one (which has cstate_len == 0) 3283542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 3284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { 3285cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *targetPtr = NULL; 3286542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3287aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; 3288542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3289542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // build concatenated response buffer 3290cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); 3291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; 3292542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; 3293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(targetPtr, pdata, rsp_count); 3294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rsp_concat_buf.data_size += rsp_count; 3295542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3296542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } while (cstate); 3297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3298542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (attr_list_len > 0) { 3299542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int scanned = 0; 3300542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rsp_concat_buf.data_size != 0) 3301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata = rsp_concat_buf.data; 3302542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rec = sdp_extract_pdu(pdata, &scanned); 3303542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3304542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!rec) 3305542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 3306542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 3307542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3308a3648e0df0ff53fef74e5437ff089aef96209db2Marcel Holtmannend: 3309542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (reqbuf) 3310542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(reqbuf); 3311542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rsp_concat_buf.data) 3312542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(rsp_concat_buf.data); 3313542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rspbuf) 3314542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(rspbuf); 3315542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return rec; 3316542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 3317542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 3318542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 33198be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * SDP transaction structure for asynchronous search 33208be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */ 33218be090b298a02108146d3bf48271f8408ac31917Claudio Takahasistruct sdp_transaction { 3322c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann sdp_callback_t *cb; /* called when the transaction finishes */ 3323c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann void *udata; /* client user data */ 3324c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann uint8_t *reqbuf; /* pointer to request PDU */ 33258be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi sdp_buf_t rsp_concat_buf; 3326c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann uint32_t reqsize; /* without cstate */ 33275ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi int err; /* ZERO if success or the errno if failed */ 33288be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi}; 33298be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 33308be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/* 33318be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * Creates a new sdp session for asynchronous search 33328be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * INPUT: 33338be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * int sk 33341be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim * non-blocking L2CAP socket 33351be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim * 33368be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * RETURN: 33378be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * sdp_session_t * 33388be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi * NULL - On memory allocation failure 33398be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi */ 33408be090b298a02108146d3bf48271f8408ac31917Claudio Takahasisdp_session_t *sdp_create(int sk, uint32_t flags) 33418be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi{ 3342a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann sdp_session_t *session; 33438be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi struct sdp_transaction *t; 3344a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann 3345a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann session = malloc(sizeof(sdp_session_t)); 33468be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi if (!session) { 33478be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi errno = ENOMEM; 33488be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi return NULL; 33498be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi } 33508be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi memset(session, 0, sizeof(*session)); 33518be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 33528be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi session->flags = flags; 33538be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi session->sock = sk; 33548be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 33558be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi t = malloc(sizeof(struct sdp_transaction)); 33568be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi if (!t) { 33578be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi errno = ENOMEM; 33588be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi free(session); 33598be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi return NULL; 33608be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi } 33618be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi memset(t, 0, sizeof(*t)); 33628be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 33638be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi session->priv = t; 33648be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 33658be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi return session; 33668be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi} 33678be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 33688be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi/* 3369adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Sets the callback function/user data used to notify the application 3370adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * that the asynchronous transaction finished. This function must be 3371adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called before request an asynchronous search. 3372dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * 3373dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * INPUT: 3374dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * sdp_session_t *session 3375dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * Current sdp session to be handled 3376dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * sdp_callback_t *cb 3377dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * callback to be called when the transaction finishes 3378dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * void *udata 3379dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * user data passed to callback 3380dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * RETURN: 3381adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 0 - Success 3382dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann * -1 - Failure 3383dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann */ 3384dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmannint sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) 3385dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann{ 3386dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann struct sdp_transaction *t; 3387dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann 3388dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann if (!session || !session->priv) 3389dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann return -1; 3390dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann 3391dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann t = session->priv; 3392dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann t->cb = func; 3393dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann t->udata = udata; 3394dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann 3395dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann return 0; 3396dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann} 3397dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann 3398adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi/* 3399adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service search request. 3400adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * The incomming and outgoing data are stored in the transaction structure 3401adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * buffers. When there is incomming data the sdp_process function must be 3402adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called to get the data and handle the continuation state. 3403adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3404adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * INPUT : 3405adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * sdp_session_t *session 3406adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Current sdp session to be handled 3407adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 340841064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim * sdp_list_t *search 3409adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Singly linked list containing elements of the search 3410adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16) 3411adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * of the service to be searched 3412adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3413adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * uint16_t max_rec_num 3414adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * A 16 bit integer which tells the service, the maximum 3415adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * entries that the client can handle in the response. The 3416adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * server is obliged not to return > max_rec_num entries 3417adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3418adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * OUTPUT : 3419adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3420adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * int return value 3421adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 0 - if the request has been sent properly 3422adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * -1 - On any failure and sets errno 3423adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi */ 3424adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi 342541064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquimint sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num) 3426453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{ 3427e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi struct sdp_transaction *t; 3428e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi sdp_pdu_hdr_t *reqhdr; 3429e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi uint8_t *pdata; 3430c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann int cstate_len, seqlen = 0; 3431e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 343212f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi if (!session || !session->priv) 3433e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi return -1; 3434e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3435e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi t = session->priv; 343618a82a6fce76be0883a431380495510010515fffClaudio Takahasi 343718a82a6fce76be0883a431380495510010515fffClaudio Takahasi /* check if the buffer is already allocated */ 343818a82a6fce76be0883a431380495510010515fffClaudio Takahasi if (t->rsp_concat_buf.data) 343918a82a6fce76be0883a431380495510010515fffClaudio Takahasi free(t->rsp_concat_buf.data); 344018a82a6fce76be0883a431380495510010515fffClaudio Takahasi memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); 344118a82a6fce76be0883a431380495510010515fffClaudio Takahasi 3442e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi if (!t->reqbuf) { 344318a82a6fce76be0883a431380495510010515fffClaudio Takahasi t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 344418a82a6fce76be0883a431380495510010515fffClaudio Takahasi if (!t->reqbuf) { 344518a82a6fce76be0883a431380495510010515fffClaudio Takahasi t->err = ENOMEM; 344618a82a6fce76be0883a431380495510010515fffClaudio Takahasi goto end; 344718a82a6fce76be0883a431380495510010515fffClaudio Takahasi } 3448e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi } 3449e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); 3450e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3451e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; 3452e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi reqhdr->tid = htons(sdp_gen_tid(session)); 3453e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi reqhdr->pdu_id = SDP_SVC_SEARCH_REQ; 3454e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3455e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi // generate PDU 3456e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); 3457e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi t->reqsize = sizeof(sdp_pdu_hdr_t); 3458e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3459e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi // add service class IDs for search 346041064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim seqlen = gen_searchseq_pdu(pdata, search); 3461e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3462e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi SDPDBG("Data seq added : %d\n", seqlen); 3463e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3464e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi // now set the length and increment the pointer 3465e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi t->reqsize += seqlen; 3466e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi pdata += seqlen; 3467e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3468e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata); 3469e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi t->reqsize += sizeof(uint16_t); 3470e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi pdata += sizeof(uint16_t); 3471e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3472e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi // set the request header's param length 3473c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann cstate_len = copy_cstate(pdata, NULL); 3474c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); 3475e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3476c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { 3477e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi SDPERR("Error sendind data:%s", strerror(errno)); 347812f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi t->err = errno; 3479e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi goto end; 3480e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi } 3481e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3482453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann return 0; 3483e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasiend: 3484e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3485f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi if (t->reqbuf) { 3486f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi free(t->reqbuf); 3487f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi t->reqbuf = NULL; 3488e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi } 3489e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi 3490e9527af7533e35a59580cda37ff58152cb356103Claudio Takahasi return -1; 3491453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann} 3492453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann 3493adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi/* 3494adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service attribute request. 3495adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * The incomming and outgoing data are stored in the transaction structure 3496adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * buffers. When there is incomming data the sdp_process function must be 3497adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * called to get the data and handle the continuation state. 3498adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3499adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * INPUT : 3500adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * sdp_session_t *session 3501adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Current sdp session to be handled 3502adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3503adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * uint32_t handle 3504adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * The handle of the service for which the attribute(s) are 3505adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * requested 3506adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3507adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * sdp_attrreq_type_t reqtype 3508adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Attribute identifiers are 16 bit unsigned integers specified 3509adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * in one of 2 ways described below : 3510adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers 3511adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * They are the actual attribute identifiers in ascending order 3512adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3513adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * SDP_ATTR_REQ_RANGE - 32bit identifier range 3514adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * The high-order 16bits is the start of range 3515adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * the low-order 16bits are the end of range 3516adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 0x0000 to 0xFFFF gets all attributes 3517adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3518adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * sdp_list_t *attrid_list 3519adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Singly linked list containing attribute identifiers desired. 3520adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) 3521adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) 3522adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 3523adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * OUTPUT : 3524adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * int return value 3525adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 0 - if the request has been sent properly 3526adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * -1 - On any failure and sets errno 3527adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi */ 3528adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi 3529453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmannint sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) 3530453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann{ 3531ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi struct sdp_transaction *t; 3532ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi sdp_pdu_hdr_t *reqhdr; 3533ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi uint8_t *pdata; 3534c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann int cstate_len, seqlen = 0; 3535ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 353612f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi if (!session || !session->priv) 3537ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi return -1; 3538ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3539ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi t = session->priv; 354018a82a6fce76be0883a431380495510010515fffClaudio Takahasi 354118a82a6fce76be0883a431380495510010515fffClaudio Takahasi /* check if the buffer is already allocated */ 354218a82a6fce76be0883a431380495510010515fffClaudio Takahasi if (t->rsp_concat_buf.data) 354318a82a6fce76be0883a431380495510010515fffClaudio Takahasi free(t->rsp_concat_buf.data); 354418a82a6fce76be0883a431380495510010515fffClaudio Takahasi memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); 354518a82a6fce76be0883a431380495510010515fffClaudio Takahasi 3546ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi if (!t->reqbuf) { 354718a82a6fce76be0883a431380495510010515fffClaudio Takahasi t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 354818a82a6fce76be0883a431380495510010515fffClaudio Takahasi if (!t->reqbuf) { 354918a82a6fce76be0883a431380495510010515fffClaudio Takahasi t->err = ENOMEM; 355018a82a6fce76be0883a431380495510010515fffClaudio Takahasi goto end; 355118a82a6fce76be0883a431380495510010515fffClaudio Takahasi } 3552ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi } 3553ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); 3554ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3555ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; 3556ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi reqhdr->tid = htons(sdp_gen_tid(session)); 3557ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi reqhdr->pdu_id = SDP_SVC_ATTR_REQ; 3558ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3559ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi // generate PDU 3560ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); 3561ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi t->reqsize = sizeof(sdp_pdu_hdr_t); 3562ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3563ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi // add the service record handle 3564ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi bt_put_unaligned(htonl(handle), (uint32_t *) pdata); 3565ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi t->reqsize += sizeof(uint32_t); 3566ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi pdata += sizeof(uint32_t); 3567ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3568ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi // specify the response limit 3569ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi bt_put_unaligned(htons(65535), (uint16_t *) pdata); 3570ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi t->reqsize += sizeof(uint16_t); 3571ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi pdata += sizeof(uint16_t); 3572ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3573ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi // get attr seq PDU form 3574ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi seqlen = gen_attridseq_pdu(pdata, attrid_list, 3575ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32); 3576ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi if (seqlen == -1) { 357712f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi t->err = EINVAL; 3578ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi goto end; 3579ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi } 3580ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3581ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi // now set the length and increment the pointer 3582ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi t->reqsize += seqlen; 3583ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi pdata += seqlen; 3584ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi SDPDBG("Attr list length : %d\n", seqlen); 3585ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3586ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi // set the request header's param length 3587c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann cstate_len = copy_cstate(pdata, NULL); 3588c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); 3589ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3590c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { 3591ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi SDPERR("Error sendind data:%s", strerror(errno)); 359212f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi t->err = errno; 3593ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi goto end; 3594ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi } 3595ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3596453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann return 0; 3597ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasiend: 3598ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3599f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi if (t->reqbuf) { 3600f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi free(t->reqbuf); 3601f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi t->reqbuf = NULL; 3602ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi } 3603ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi 3604ef1fe5feaa0dde16562723bcb36343c7bc4c31beClaudio Takahasi return -1; 3605453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann} 3606453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann 3607dd610a12694a42aeb67417c95d87384f2eef8e70Marcel Holtmann/* 3608adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * This function starts an asynchronous service search attributes. 3609adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * It is a service search request combined with attribute request. The incomming 3610adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * and outgoing data are stored in the transaction structure buffers. When there 3611adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * is incomming data the sdp_process function must be called to get the data 3612adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * and handle the continuation state. 3613f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 3614f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT: 3615f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * sdp_session_t *session 3616f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * Current sdp session to be handled 3617453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * 3618453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * sdp_list_t *search 3619453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * Singly linked list containing elements of the search 3620453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16) 3621453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * of the service to be searched 3622453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * 3623453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * AttributeSpecification attrSpec 3624453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * Attribute identifiers are 16 bit unsigned integers specified 3625453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * in one of 2 ways described below : 3626453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers 3627453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * They are the actual attribute identifiers in ascending order 3628453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * 3629453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * SDP_ATTR_REQ_RANGE - 32bit identifier range 3630453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * The high-order 16bits is the start of range 3631453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * the low-order 16bits are the end of range 3632453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * 0x0000 to 0xFFFF gets all attributes 3633453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * 3634adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * sdp_list_t *attrid_list 3635453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * Singly linked list containing attribute identifiers desired. 3636453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) 3637453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) 3638453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann * 3639453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann 3640f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN: 3641adff4cad15e4e13bb9847a0ff62b355caddf89e3Claudio Takahasi * 0 - if the request has been sent properly 3642f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * -1 - On any failure 3643f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */ 364441064d605ba2f88f967c8388c9b20b92a7868a87Ulisses 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) 3645f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{ 3646f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi struct sdp_transaction *t; 3647f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi sdp_pdu_hdr_t *reqhdr; 3648f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi uint8_t *pdata; 3649c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann int cstate_len, seqlen = 0; 3650f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 365112f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi if (!session || !session->priv) 3652f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi return -1; 3653f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3654f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi t = session->priv; 365518a82a6fce76be0883a431380495510010515fffClaudio Takahasi 365618a82a6fce76be0883a431380495510010515fffClaudio Takahasi /* check if the buffer is already allocated */ 365718a82a6fce76be0883a431380495510010515fffClaudio Takahasi if (t->rsp_concat_buf.data) 365818a82a6fce76be0883a431380495510010515fffClaudio Takahasi free(t->rsp_concat_buf.data); 365918a82a6fce76be0883a431380495510010515fffClaudio Takahasi memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); 366018a82a6fce76be0883a431380495510010515fffClaudio Takahasi 3661f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi if (!t->reqbuf) { 366218a82a6fce76be0883a431380495510010515fffClaudio Takahasi t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 366318a82a6fce76be0883a431380495510010515fffClaudio Takahasi if (!t->reqbuf) { 366418a82a6fce76be0883a431380495510010515fffClaudio Takahasi t->err = ENOMEM; 366518a82a6fce76be0883a431380495510010515fffClaudio Takahasi goto end; 366618a82a6fce76be0883a431380495510010515fffClaudio Takahasi } 3667f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi } 3668f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); 3669f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3670f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; 3671f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi reqhdr->tid = htons(sdp_gen_tid(session)); 3672f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ; 3673f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3674f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi // generate PDU 3675f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); 3676f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi t->reqsize = sizeof(sdp_pdu_hdr_t); 3677f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3678f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi // add service class IDs for search 367941064d605ba2f88f967c8388c9b20b92a7868a87Ulisses Furquim seqlen = gen_searchseq_pdu(pdata, search); 3680f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3681f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi SDPDBG("Data seq added : %d\n", seqlen); 3682f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3683f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi // now set the length and increment the pointer 3684f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi t->reqsize += seqlen; 3685f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi pdata += seqlen; 3686f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3687f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata); 3688f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi t->reqsize += sizeof(uint16_t); 3689f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi pdata += sizeof(uint16_t); 3690f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3691f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN); 3692f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3693f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi // get attr seq PDU form 3694453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann seqlen = gen_attridseq_pdu(pdata, attrid_list, 3695453a0cedb6c909047553ffc7145bcef26a3ae94cMarcel Holtmann reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32); 3696f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi if (seqlen == -1) { 369712f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi t->err = EINVAL; 3698f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi goto end; 3699f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi } 3700f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3701f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi pdata += seqlen; 3702f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi SDPDBG("Attr list length : %d\n", seqlen); 3703f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi t->reqsize += seqlen; 3704f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3705f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi // set the request header's param length 3706c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann cstate_len = copy_cstate(pdata, NULL); 3707c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); 3708f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3709c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { 3710f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi SDPERR("Error sendind data:%s", strerror(errno)); 371112f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi t->err = errno; 3712f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi goto end; 3713f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi } 3714f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3715f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi return 0; 3716f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend: 3717f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3718f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi if (t->reqbuf) { 3719f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi free(t->reqbuf); 3720f207a4f0f6d5d38a3e357f62d4976bedaed2cf4fClaudio Takahasi t->reqbuf = NULL; 3721f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi } 3722f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3723f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi return -1; 3724f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi} 3725f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3726f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/* 37275ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * Function used to get the error reason after sdp_callback_t function has been called 372812f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1. 372912f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly 373012f41aa6ff9529a80a182754d0855dccb11978acClaudio Takahasi * is not safe because multiple transactions can be triggered. 37315ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * This function must be used with asynchronous sdp functions only. 37325ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 37335ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * INPUT: 37345ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * sdp_session_t *session 37355ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * Current sdp session to be handled 37365ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * RETURN: 37375ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 0 = No error in the current transaction 37385ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * -1 - if the session is invalid 37395ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * positive value - the errno value 37405ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * 37415ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi */ 37425ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasiint sdp_get_error(sdp_session_t *session) 37435ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi{ 37445ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi struct sdp_transaction *t; 37455ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi 37465ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi if (!session || !session->priv) { 37475ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi SDPERR("Invalid session"); 37485ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi return -1; 37495ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi } 37505ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi 37515ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi t = session->priv; 37525ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi 37535ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi return t->err; 37545ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi} 37555ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi 37565ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi/* 3757f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * Receive the incomming SDP PDU. This function must be called when there is data 3758f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * available to be read. On continuation state, the original request (with a new 3759f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * transaction ID) and the continuation state data will be appended in the initial PDU. 3760f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * If an error happens or the transaction finishes the callback function will be called. 3761f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 3762f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * INPUT: 3763f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * sdp_session_t *session 3764f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * Current sdp session to be handled 3765f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * RETURN: 3766f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * 0 - if the transaction is on continuation state 3767f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * -1 - On any failure or the transaction finished 3768f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */ 3769f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiint sdp_process(sdp_session_t *session) 3770f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi{ 37715ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi struct sdp_transaction *t; 37725ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi sdp_pdu_hdr_t *reqhdr, *rsphdr; 37735ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi sdp_cstate_t *pcstate; 37745ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi uint8_t *pdata, *rspbuf, *targetPtr; 37755ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi int rsp_count, err = -1; 3776c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann size_t size = 0; 37779203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi int n, plen; 37785ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi uint16_t status = 0xffff; 37795ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi uint8_t pdu_id = 0x00; 3780f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3781f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi if (!session || !session->priv) { 3782c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi SDPERR("Invalid session"); 3783c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi return -1; 3784f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi } 3785f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3786f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 37875ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi if (!rspbuf) { 37885ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi SDPERR("Response buffer alloc failure:%s (%d)", 37895ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi strerror(errno), errno); 3790c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi return -1; 37915ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi } 3792c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi 3793c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE); 3794f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3795f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi t = session->priv; 3796f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi reqhdr = (sdp_pdu_hdr_t *)t->reqbuf; 3797f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi rsphdr = (sdp_pdu_hdr_t *)rspbuf; 3798f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 37995ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi pdata = rspbuf + sizeof(sdp_pdu_hdr_t); 3800f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 38019203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE); 38029203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi if (n < 0) { 38035ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi SDPERR("Read response:%s (%d)", strerror(errno), errno); 38045ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi t->err = errno; 3805f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi goto end; 38065ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi } 3807f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 38089203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi if (n == 0 || reqhdr->tid != rsphdr->tid || 38099203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi (n != (ntohs(rsphdr->plen) + sizeof(sdp_pdu_hdr_t)))) { 38105ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi t->err = EPROTO; 38119203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi SDPERR("Protocol error."); 3812343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi goto end; 3813343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi } 3814343f72ba28deaf9ddc68043567baad76e0325e5dClaudio Takahasi 38155ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi pdu_id = rsphdr->pdu_id; 381658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi switch (rsphdr->pdu_id) { 381758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi uint8_t *ssr_pdata; 381858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi uint16_t tsrc, csrc; 381958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi case SDP_SVC_SEARCH_RSP: 382058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi /* 38219203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi * TSRC: Total Service Record Count (2 bytes) 38229203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi * CSRC: Current Service Record Count (2 bytes) 382358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi */ 382458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi ssr_pdata = pdata; 382558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); 38269203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi ssr_pdata += sizeof(uint16_t); 382758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); 382858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi 38299203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi /* csrc should never be larger than tsrc */ 38309203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi if (csrc > tsrc) { 38319203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi t->err = EPROTO; 38329203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi SDPERR("Protocol error: wrong current service record count value."); 38339203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi goto end; 38349203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi } 38359203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi 38369203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi SDPDBG("Total svc count: %d\n", tsrc); 38379203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi SDPDBG("Current svc count: %d\n", csrc); 38389203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi 38399203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi /* parameter length without continuation state */ 38409203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4; 38419203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi 3842c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann if (t->rsp_concat_buf.data_size == 0) { 384358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi /* first fragment */ 384458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4; 384558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi } else { 3846e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi /* point to the first csrc */ 3847e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi uint16_t *pcsrc = (uint16_t *) (t->rsp_concat_buf.data + 2); 3848e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi 3849e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi /* FIXME: update the interface later. csrc doesn't need be passed to clients */ 3850e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi 3851e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi pdata += sizeof(uint16_t); /* point to csrc */ 3852e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi 3853e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi /* the first csrc contains the sum of partial csrc responses */ 3854e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi *pcsrc += bt_get_unaligned((uint16_t *) pdata); 3855e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi 3856e3dbc939bd096c8604d1480e0994f73f65a39f16Claudio Takahasi pdata += sizeof(uint16_t); /* point to the first handle */ 385758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi rsp_count = csrc * 4; 385858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi } 38595ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi status = 0x0000; 386058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi break; 386158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi case SDP_SVC_ATTR_RSP: 386258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi case SDP_SVC_SEARCH_ATTR_RSP: 386358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 386458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi SDPDBG("Attrlist byte count : %d\n", rsp_count); 38659203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi 38669203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi /* 38679203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi * Number of bytes in the AttributeLists parameter(without 38689203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi * continuation state) + AttributeListsByteCount field size. 38699203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi */ 38709203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi plen = sizeof(uint16_t) + rsp_count; 3871f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 387258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi pdata += sizeof(uint16_t); // points to attribute list 38735ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi status = 0x0000; 387458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi break; 38755ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi case SDP_ERROR_RSP: 38765ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi status = ntohs(bt_get_unaligned((uint16_t *) pdata)); 38779203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi size = ntohs(rsphdr->plen); 38789203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi 38799203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi /* error code + error info */ 38809203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi plen = size; 38815ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi goto end; 388258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi default: 38835ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi t->err = EPROTO; 38845ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id); 388558eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi goto end; 388658eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi } 3887f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 388858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi pcstate = (sdp_cstate_t *) (pdata + rsp_count); 388958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi 389058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi SDPDBG("Cstate length : %d\n", pcstate->length); 38919203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi 38929203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi /* 38939203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi * Check out of bound. Continuation state must have at least 38949203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi * 1 byte: ZERO to indicate that it is not a partial response. 38959203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi */ 38969203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi if ((n - sizeof(sdp_pdu_hdr_t)) != (plen + pcstate->length + 1)) { 38979203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi t->err = EPROTO; 38989203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi SDPERR("Protocol error: wrong PDU size."); 38999203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi status = 0xffff; 39009203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi goto end; 39019203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi } 39029203084c0b92805006c133f82fbc0cbd6b203904Claudio Takahasi 3903f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi /* 3904f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi * This is a split response, need to concatenate intermediate 39055ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi * responses and the last one which will have cstate length == 0 3906f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi */ 390758eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count); 390858eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size; 390958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count; 391058eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi memcpy(targetPtr, pdata, rsp_count); 391158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi t->rsp_concat_buf.data_size += rsp_count; 391258eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi 391358eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi if (pcstate->length > 0) { 391458eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi int reqsize, cstate_len; 3915f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3916f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi reqhdr->tid = htons(sdp_gen_tid(session)); 3917f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 39185ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi // add continuation state 391958eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi cstate_len = copy_cstate(t->reqbuf + t->reqsize, pcstate); 3920f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 392158eb769e7620e03c8b0bf2d2bcf38c06ab58065fClaudio Takahasi reqsize = t->reqsize + cstate_len; 3922f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3923f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi // set the request header's param length 3924f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 3925f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3926f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi if (sdp_send_req(session, t->reqbuf, reqsize) < 0) { 39275ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi SDPERR("Error sendind data:%s(%d)", strerror(errno), errno); 39285ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi status = 0xffff; 39295ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi t->err = errno; 3930f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi goto end; 3931f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi } 3932c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi err = 0; 3933f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi } 3934f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3935f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasiend: 3936c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi if (err) { 3937c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann if (t->rsp_concat_buf.data_size != 0) { 3938f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi pdata = t->rsp_concat_buf.data; 3939c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann size = t->rsp_concat_buf.data_size; 3940c01b6039f44d9e78acc26cd8482b5e0c7b23fe14Marcel Holtmann } 3941f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi if (t->cb) 39425ec20cab698055029198b10afb4db20bee06ce72Claudio Takahasi t->cb(pdu_id, status, pdata, size, t->udata); 3943f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi } 3944f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3945f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi if (rspbuf) 3946f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi free(rspbuf); 3947f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3948c8e5a1464ff8edb068e7361a257ef4ae34674cf8Claudio Takahasi return err; 3949f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi} 3950f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi 3951f9264e21a9e0c97e6a4d970c0b31cf01fc18781dClaudio Takahasi/* 3952542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a service search request combined with the service 3953542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * attribute request. First a service class match is done and 3954542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * for matching service, requested attributes are extracted 3955542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3956542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * INPUT : 3957542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3958542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_list_t *search 3959542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Singly linked list containing elements of the search 3960542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16) 3961542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * of the service to be searched 3962542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3963542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * AttributeSpecification attrSpec 3964542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Attribute identifiers are 16 bit unsigned integers specified 3965542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * in one of 2 ways described below : 3966542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers 3967542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * They are the actual attribute identifiers in ascending order 3968542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3969542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * SDP_ATTR_REQ_RANGE - 32bit identifier range 3970542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The high-order 16bits is the start of range 3971542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * the low-order 16bits are the end of range 3972542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 0x0000 to 0xFFFF gets all attributes 3973542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3974542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_list_t *attrids 3975542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Singly linked list containing attribute identifiers desired. 3976542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) 3977542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) 3978542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3979542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * OUTPUT : 3980542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * int return value 3981542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 0: 3982542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * The request completed successfully. This does not 3983542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * mean the requested services were found 3984542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * -1: 3985542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * On any error and sets errno 3986542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * 3987542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_list_t **rsp 3988542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This variable is set on a successful return to point to 3989542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * service(s) found. Each element of this list is of type 3990542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * sdp_record_t* (of the services which matched the search list) 3991542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 3992542fc57346fbb329934152f446f58cc61a5d5d00Marcel 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) 3993542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 3994542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int status = 0; 3995cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t reqsize = 0, _reqsize; 3996cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint32_t rspsize = 0; 3997542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int seqlen = 0, attr_list_len = 0; 3998542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int rsp_count = 0, cstate_len = 0; 3999cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *pdata, *_pdata; 4000cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *reqbuf, *rspbuf; 4001542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_pdu_hdr_t *reqhdr, *rsphdr; 4002542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann uint8_t dataType; 4003542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_list_t *rec_list = NULL; 4004542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_buf_t rsp_concat_buf; 4005542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_cstate_t *cstate = NULL; 4006542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4007542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) { 4008542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = EINVAL; 4009542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 4010542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4011cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 4012cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 4013542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (!reqbuf || !rspbuf) { 4014542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann errno = ENOMEM; 4015542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 4016542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 4017542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4018542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4019542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t)); 4020aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann reqhdr = (sdp_pdu_hdr_t *) reqbuf; 4021542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ; 4022542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4023542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // generate PDU 4024542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata = reqbuf + sizeof(sdp_pdu_hdr_t); 4025542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize = sizeof(sdp_pdu_hdr_t); 4026542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4027542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // add service class IDs for search 4028542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqlen = gen_searchseq_pdu(pdata, search); 4029542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4030542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Data seq added : %d\n", seqlen); 4031542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4032542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // now set the length and increment the pointer 4033542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += seqlen; 4034542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += seqlen; 4035542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4036aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata); 4037542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += sizeof(uint16_t); 4038542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += sizeof(uint16_t); 4039542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4040542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN); 4041542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4042542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // get attr seq PDU form 4043542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann seqlen = gen_attridseq_pdu(pdata, attrids, 4044aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32); 4045542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (seqlen == -1) { 4046542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = EINVAL; 4047542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 4048542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4049542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += seqlen; 4050542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Attr list length : %d\n", seqlen); 4051542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize += seqlen; 4052542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *rsp = 0; 4053542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4054542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // save before Continuation State 4055542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann _pdata = pdata; 4056542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann _reqsize = reqsize; 4057542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4058542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann do { 4059542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->tid = htons(sdp_gen_tid(session)); 4060542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4061542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // add continuation state (can be null) 4062542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqsize = _reqsize + copy_cstate(_pdata, cstate); 4063542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4064542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // set the request header's param length 4065542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 4066aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann rsphdr = (sdp_pdu_hdr_t *) rspbuf; 4067542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 4068542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (status < 0) { 4069542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Status : 0x%x\n", rsphdr->pdu_id); 4070542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 4071542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4072542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4073542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rsphdr->pdu_id == SDP_ERROR_RSP) { 4074542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 4075542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 4076542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4077542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4078542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata = rspbuf + sizeof(sdp_pdu_hdr_t); 4079aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 4080542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann attr_list_len += rsp_count; 4081542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += sizeof(uint16_t); // pdata points to attribute list 4082aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann cstate_len = *(uint8_t *) (pdata + rsp_count); 4083542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4084542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Attrlist byte count : %d\n", attr_list_len); 4085542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Response byte count : %d\n", rsp_count); 4086542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Cstate length : %d\n", cstate_len); 4087542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann /* 4088542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * This is a split response, need to concatenate intermediate 4089542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * responses and the last one which will have cstate_len == 0 4090542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 4091542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { 4092cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann uint8_t *targetPtr = NULL; 4093542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4094aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5Marcel Holtmann cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; 4095542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4096542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann // build concatenated response buffer 4097cfa3a02e2593bd72ce4a83f521e1e89a5874ea7dMarcel Holtmann rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); 4098542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; 4099542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; 4100542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann memcpy(targetPtr, pdata, rsp_count); 4101542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rsp_concat_buf.data_size += rsp_count; 4102542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4103542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } while (cstate); 4104542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4105542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (attr_list_len > 0) { 4106542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int scanned = 0; 4107542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4108542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rsp_concat_buf.data_size != 0) 4109542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata = rsp_concat_buf.data; 4110542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4111542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann /* 4112542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Response is a sequence of sequence(s) for one or 4113542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * more data element sequence(s) representing services 4114542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * for which attributes are returned 4115542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 4116542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann scanned = sdp_extract_seqtype(pdata, &dataType, &seqlen); 4117542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4118542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Bytes scanned : %d\n", scanned); 4119542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Seq length : %d\n", seqlen); 4120542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4121542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (scanned && seqlen) { 4122542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += scanned; 4123542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann do { 4124542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int recsize = 0; 4125542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann sdp_record_t *rec = sdp_extract_pdu(pdata, &recsize); 4126542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rec == NULL) { 4127542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("SVC REC is null\n"); 4128542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann status = -1; 4129542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann goto end; 4130542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 41318db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann if (!recsize) { 41328db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann sdp_record_free(rec); 41338db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann break; 41348db4e616c0107df21e3cacd981d073a64414de77Marcel Holtmann } 4135542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann scanned += recsize; 4136542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann pdata += recsize; 4137542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4138542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Loc seq length : %d\n", recsize); 4139542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle); 4140542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Bytes scanned : %d\n", scanned); 4141542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Attrlist byte count : %d\n", attr_list_len); 4142542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann rec_list = sdp_list_append(rec_list, rec); 4143542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } while (scanned < attr_list_len); 4144542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4145542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPDBG("Successful scan of service attr lists\n"); 4146542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *rsp = rec_list; 4147542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4148542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4149542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann end: 4150542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rsp_concat_buf.data) 4151542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(rsp_concat_buf.data); 4152542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (reqbuf) 4153542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(reqbuf); 4154542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (rspbuf) 4155542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(rspbuf); 4156542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return status; 4157542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 4158542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4159542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann/* 4160542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann * Find devices in the piconet. 4161542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann */ 4162542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found) 4163542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 4164542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0); 4165542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (n < 0) { 4166542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann SDPERR("Inquiry failed:%s", strerror(errno)); 4167542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return -1; 4168542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4169542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann *found = n; 4170542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return 0; 4171542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 4172542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4173542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannint sdp_close(sdp_session_t *session) 4174542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 41758be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi struct sdp_transaction *t; 41768be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi int ret; 41778be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 41788be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi if (!session) 41798be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi return -1; 41808be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 41818be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi ret = close(session->sock); 41828be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 41838be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi t = session->priv; 41848be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 41858be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi if (t) { 41868be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi if (t->reqbuf) 41878be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi free(t->reqbuf); 41888be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 41898be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi if (t->rsp_concat_buf.data) 41908be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi free(t->rsp_concat_buf.data); 41918be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi 41928be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi free(t); 41938be090b298a02108146d3bf48271f8408ac31917Claudio Takahasi } 4194542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(session); 4195542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return ret; 4196542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 4197542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 4198542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannstatic inline int sdp_is_local(const bdaddr_t *device) 4199542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 4200542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0; 4201542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 4202542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann 42031be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimstatic int sdp_connect_local(sdp_session_t *session) 4204542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann{ 42051be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim struct sockaddr_un sa; 4206a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann 42071be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim session->sock = socket(PF_UNIX, SOCK_STREAM, 0); 42081be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (session->sock < 0) 42091be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return -1; 42101be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim session->local = 1; 4211a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann 42121be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim sa.sun_family = AF_UNIX; 42131be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim strcpy(sa.sun_path, SDP_UNIX_PATH); 4214a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann 4215aa7577018bb1faac4b67b52dc8b003663cdd03adUlisses Furquim return connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)); 42161be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim} 42171be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42181be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimstatic int sdp_connect_l2cap(const bdaddr_t *src, 42191be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim const bdaddr_t *dst, sdp_session_t *session) 42201be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim{ 42211be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim uint32_t flags = session->flags; 42221be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim struct sockaddr_l2 sa; 42231be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim int sk; 42241be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42251be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); 42261be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (session->sock < 0) 42271be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return -1; 42281be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim session->local = 0; 42291be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42301be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim sk = session->sock; 42311be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42321be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (flags & SDP_NON_BLOCKING) { 42331be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim long arg = fcntl(sk, F_GETFL, 0); 42341be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim fcntl(sk, F_SETFL, arg | O_NONBLOCK); 4235a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann } 4236a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann 42371be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim sa.l2_family = AF_BLUETOOTH; 42381be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim sa.l2_psm = 0; 4239a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann 42401be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (bacmp(src, BDADDR_ANY)) { 42411be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim sa.l2_bdaddr = *src; 42421be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0) 42431be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return -1; 42441be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim } 4245a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann 42461be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (flags & SDP_WAIT_ON_CLOSE) { 42471be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim struct linger l = { .l_onoff = 1, .l_linger = 1 }; 42481be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)); 42491be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim } 42501be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42511be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim sa.l2_psm = htobs(SDP_PSM); 42521be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim sa.l2_bdaddr = *dst; 42531be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42541be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim do { 42551be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa)); 4256aa7577018bb1faac4b67b52dc8b003663cdd03adUlisses Furquim if (!ret) 42571be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return 0; 42581be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (ret < 0 && (flags & SDP_NON_BLOCKING) && 42591be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim (errno == EAGAIN || errno == EINPROGRESS)) 42601be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return 0; 42611be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim } while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY)); 42621be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42631be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return -1; 42641be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim} 42651be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42661be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquimsdp_session_t *sdp_connect(const bdaddr_t *src, 42671be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim const bdaddr_t *dst, uint32_t flags) 42681be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim{ 42691be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim sdp_session_t *session; 42701be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim int err; 42711be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42721be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) { 42731be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim errno = EINVAL; 42741be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return NULL; 42751be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim } 42761be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42771be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim session = sdp_create(-1, flags); 42781be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (!session) 42791be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return NULL; 42801be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 42811be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (sdp_is_local(dst)) { 42821be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (sdp_connect_local(session) < 0) 42831be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim goto fail; 4284542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } else { 42851be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim if (sdp_connect_l2cap(src, dst, session) < 0) 42861be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim goto fail; 4287542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann } 4288a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann 42891be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return session; 42901be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 4291542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmannfail: 429212862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann err = errno; 4293542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann if (session->sock >= 0) 4294542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann close(session->sock); 4295a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann if (session->priv) 4296a76dc65489dd8959547a97a391e405b2025bbd79Marcel Holtmann free(session->priv); 4297542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann free(session); 429812862715c961bf6dabce2ed4e58da58e5dfe8c6bMarcel Holtmann errno = err; 42991be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim 43001be1f79648ba7aafde6349cfe51f9c929e20d018Ulisses Furquim return NULL; 4301542fc57346fbb329934152f446f58cc61a5d5d00Marcel Holtmann} 43028f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann 43038f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannint sdp_get_socket(const sdp_session_t *session) 43048f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{ 43058f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann return session->sock; 43068f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann} 43078f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann 43088f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmannuint16_t sdp_gen_tid(sdp_session_t *session) 43098f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann{ 43108f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann return session->tid++; 43118f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7Marcel Holtmann} 4312