1.\" $NetBSD: sdp_data.3,v 1.10 2017/07/03 21:32:49 wiz Exp $ 2.\" 3.\" Copyright (c) 2009 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Iain Hibbert. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" SUCH DAMAGE. 29.\" 30.Dd January 15, 2011 31.Dt SDP_DATA 3 32.Os 33.Sh NAME 34.Nm sdp_match_uuid16 35.Nm sdp_get_data 36.Nm sdp_get_attr 37.Nm sdp_get_uuid 38.Nm sdp_get_bool 39.Nm sdp_get_seq 40.Nm sdp_get_alt 41.Nm sdp_get_uint 42.Nm sdp_get_int 43.Nm sdp_get_str 44.Nm sdp_get_url 45.Nm sdp_put_data 46.Nm sdp_put_attr 47.Nm sdp_put_uuid 48.Nm sdp_put_uuid16 49.Nm sdp_put_uuid32 50.Nm sdp_put_uuid128 51.Nm sdp_put_bool 52.Nm sdp_put_uint 53.Nm sdp_put_uint8 54.Nm sdp_put_uint16 55.Nm sdp_put_uint32 56.Nm sdp_put_uint64 57.Nm sdp_put_int 58.Nm sdp_put_int8 59.Nm sdp_put_int16 60.Nm sdp_put_int32 61.Nm sdp_put_int64 62.Nm sdp_put_seq 63.Nm sdp_put_alt 64.Nm sdp_put_str 65.Nm sdp_put_url 66.Nm sdp_set_bool 67.Nm sdp_set_uint 68.Nm sdp_set_int 69.Nm sdp_set_seq 70.Nm sdp_set_alt 71.Nm sdp_data_size 72.Nm sdp_data_type 73.Nm sdp_data_valid 74.Nm sdp_data_print 75.Nd Service Discovery Protocol data manipulation routines 76.Sh LIBRARY 77.Lb libbluetooth 78.Sh SYNOPSIS 79.In sdp.h 80.Vt extern const uuid_t BLUETOOTH_BASE_UUID ; 81.Ft bool 82.Fn sdp_match_uuid16 "sdp_data_t *data" "uint16_t uuid" 83.Ft bool 84.Fn sdp_get_data "sdp_data_t *data" "sdp_data_t *value" 85.Ft bool 86.Fn sdp_get_attr "sdp_data_t *data" "uint16_t *attr" "sdp_data_t *value" 87.Ft bool 88.Fn sdp_get_uuid "sdp_data_t *data" "uuid_t *uuid" 89.Ft bool 90.Fn sdp_get_bool "sdp_data_t *data" "bool *value" 91.Ft bool 92.Fn sdp_get_seq "sdp_data_t *data" "sdp_data_t *seq" 93.Ft bool 94.Fn sdp_get_alt "sdp_data_t *data" "sdp_data_t *alt" 95.Ft bool 96.Fn sdp_get_uint "sdp_data_t *data" "uintmax_t *value" 97.Ft bool 98.Fn sdp_get_int "sdp_data_t *data" "intmax_t *value" 99.Ft bool 100.Fn sdp_get_str "sdp_data_t *data" "char **str" "size_t *length" 101.Ft bool 102.Fn sdp_get_url "sdp_data_t *data" "char **url" "size_t *length" 103.Ft bool 104.Fn sdp_put_data "sdp_data_t *data" "sdp_data_t *value" 105.Ft bool 106.Fn sdp_put_attr "sdp_data_t *data" "uint16_t attr" "sdp_data_t *value" 107.Ft bool 108.Fn sdp_put_uuid "sdp_data_t *data" "const uuid_t *value" 109.Ft bool 110.Fn sdp_put_uuid16 "sdp_data_t *data" "uint16_t value" 111.Ft bool 112.Fn sdp_put_uuid32 "sdp_data_t *data" "uint32_t value" 113.Ft bool 114.Fn sdp_put_uuid128 "sdp_data_t *data" "const uuid_t *value" 115.Ft bool 116.Fn sdp_put_bool "sdp_data_t *data" "bool value" 117.Ft bool 118.Fn sdp_put_uint "sdp_data_t *data" "uintmax_t value" 119.Ft bool 120.Fn sdp_put_uint8 "sdp_data_t *data" "uint8_t value" 121.Ft bool 122.Fn sdp_put_uint16 "sdp_data_t *data" "uint16_t value" 123.Ft bool 124.Fn sdp_put_uint32 "sdp_data_t *data" "uint32_t value" 125.Ft bool 126.Fn sdp_put_uint64 "sdp_data_t *data" "uint64_t value" 127.Ft bool 128.Fn sdp_put_int "sdp_data_t *data" "intmax_t value" 129.Ft bool 130.Fn sdp_put_int8 "sdp_data_t *data" "int8_t value" 131.Ft bool 132.Fn sdp_put_int16 "sdp_data_t *data" "int16_t value" 133.Ft bool 134.Fn sdp_put_int32 "sdp_data_t *data" "int32_t value" 135.Ft bool 136.Fn sdp_put_int64 "sdp_data_t *data" "int64_t value" 137.Ft bool 138.Fn sdp_put_seq "sdp_data_t *data" "ssize_t length" 139.Ft bool 140.Fn sdp_put_alt "sdp_data_t *data" "ssize_t length" 141.Ft bool 142.Fn sdp_put_str "sdp_data_t *data" "const char *str" "ssize_t length" 143.Ft bool 144.Fn sdp_put_url "sdp_data_t *data" "const char *url" "ssize_t length" 145.Ft bool 146.Fn sdp_set_bool "const sdp_data_t *data" "bool value" 147.Ft bool 148.Fn sdp_set_uint "const sdp_data_t *data" "uintmax_t value" 149.Ft bool 150.Fn sdp_set_int "const sdp_data_t *data" "intmax_t value" 151.Ft bool 152.Fn sdp_set_seq "const sdp_data_t *data" "ssize_t length" 153.Ft ssize_t 154.Fn sdp_data_size "const sdp_data_t *data" 155.Ft int 156.Fn sdp_data_type "const sdp_data_t *data" 157.Ft bool 158.Fn sdp_data_valid "const sdp_data_t *data" 159.Ft void 160.Fn sdp_data_print "const sdp_data_t *data" "int indent" 161.Sh DESCRIPTION 162These routines provide for the manipulation of Service Discovery 163Protocol data buffers. 164An SDP data buffer type is defined as: 165.Bd -literal -offset indent 166typedef struct { 167 uint8_t *next; 168 uint8_t *end; 169} sdp_data_t; 170.Ed 171.Pp 172Where 173.Fa next 174points to the next available byte, and 175.Fa end 176points to the first address past end of the data area, such that 177.Qq end = next + length . 178.Pp 179The SDP data consists of byte streams describing data elements, where 180a data element is a typed data representation consisting of a header 181field and a data field. 182The header field consists of type and size descriptors, and the data 183field is a sequence of bytes whose length is specified in the size 184descriptor and whose content is specified by the type descriptor. 185For instance, the byte sequence 186.Qq 0x09, 0x01, 0x00 187describes an 16-bit unsigned integer element (type 0x09) with 188value of 0x0100. 189.Pp 190Data element types including signed and unsigned integers, boolean, 191string, sequence and alternative lists are defined in the 192.In sdp.h 193include file. 194See the 195.Qq Service Discovery Protocol 196chapters of the 197.Qq Bluetooth Core Specifications 198for more information. 199.Pp 200To reduce the burden of storing and transferring 128-bit UUID values, a 201range of UUID values has been pre-allocated for assignment to often-used, 202registered purposes. 203The first UUID in this pre-allocated range is known as the 204.Qq Bluetooth Base UUID , 205defined in the 206.Qq Bluetooth Assigned Numbers 207document and declared in 208.In sdp.h 209as 210.Vt const uuid_t BLUETOOTH_BASE_UUID ; 211.Pp 212The data manipulation routines are arranged into major groups 213by function: 214.Bl -hang 215.It The Fn sdp_match_uuid16 216routine examines the next data element in the data buffer for 217an element of type UUID that matches the Bluetooth short alias 218UUID with 16-bit value given. 219If the UUID matches, the function will return 220.Dv true 221and the 222.Fa next 223field of the SDP data buffer will be advanced to the next element. 224Otherwise 225.Dv false 226will be returned. 227.It The Fn sdp_get_xxxx 228routines examine the next data element in the data buffer for an 229element of the given type. 230If the type matches, the function will extract the typed value to 231the address given and advance the 232.Fa next 233field of the SDP data buffer to the next element then return 234.Dv true . 235Otherwise 236.Dv false 237will be returned. 238Note, these functions will not modify the 239.Fa data 240argument unless the correct type was found, and will update the 241.Fa data 242argument first to allow discarding in the case where a 243.Dv sdp_data_t 244was being returned. 245.It The Fn sdp_put_xxxx 246routines will attempt to write a data element of the given type 247and value to the data buffer. 248If the data buffer is too small to contain the encoded data element, 249the function will return 250.Dv false , 251otherwise 252.Dv true 253will be returned and the 254.Fa next 255field of the SDP data pointer will be advanced. 256In the case of 257.Fn sdp_put_seq 258and 259.Fn sdp_put_alt , 260the 261.Fa length 262argument may be -1, in which case the generated sequence header will 263describe all the remaining buffer space. 264For 265.Fn sdp_put_str 266and 267.Fn sdp_put_url 268the 269.Fa length 270argument may be -1 in which case the string pointer is treated as 271nul terminated. 272.It The Fn sdp_set_xxxx 273routines examine the SDP data buffer for a data element of the given 274type, and replace the content with the passed value. 275If the next data element in the buffer is not of the appropriate 276type, the function will return 277.Dv false , 278otherwise 279.Dv true 280will be returned and the value updated. 281In the case of 282.Fn sdp_set_seq 283and 284.Fn sdp_set_alt , 285the 286.Fa length 287argument may be -1, in which case the sequence header will be 288adjusted to describe the entire data space where possible. 289.It The Fn sdp_data_xxxx 290routines include various functions to provide information about 291the data stream such as 292.Fn sdp_data_size 293to return the size of the next data element, and 294.Fn sdp_data_type 295to return the type of the next data element. 296.Fn sdp_data_valid 297can be used to ensure that the entire data buffer contains 298valid SDP data elements and that all of the elements are contained 299exactly within the data buffer. 300Finally, 301.Fn sdp_data_print 302will print the data buffer in human readable format. 303.El 304.Sh EXAMPLES 305To parse a ServiceAttribute response obtained from a remote server 306using 307.Xr sdp_service_attribute 3 , 308examining various attribute values: 309.Bd -literal 310 sdp_data_t rsp, val; 311 uint16_t attr; 312 uintmax_t handle; 313 314 /* rsp contains remote response */ 315 316 while (sdp_get_attr(&rsp, &attr, &val)) { 317 switch(attr) { 318 case SDP_ATTR_SERVICE_RECORD_HANDLE: 319 sdp_get_uint(&val, &handle); 320 printf("ServiceRecordHandle: 0x%08x\\n", handle); 321 break; 322 323 case SDP_ATTR_PROFILE_DESCRIPTOR_LIST: 324 printf("ProfileDescriptorList:\\n"); 325 sdp_data_print(&val, 0); 326 break; 327 328 default: 329 printf("uninteresting attribute 0x%04x\\n", attr); 330 break; 331 } 332 } 333.Ed 334.Pp 335The following code creates a ProtocolDataList attribute value for a service 336using the L2CAP and RFCOMM protocols and illustrates how to construct sequences 337of known and unknown length. 338.Bd -literal 339 uint8_t buf[SIZE]; 340 sdp_data_t seq; 341 uint16_t psm; 342 uint8_t channel; 343 344 seq.next = buf; 345 seq.end = buf + sizeof(buf); 346 sdp_put_seq(&seq, -1); 347 348 sdp_put_seq(&seq, 6); 349 sdp_put_uuid16(&seq, SDP_UUID_PROTOCOL_L2CAP); 350 sdp_put_uint16(&seq, psm); 351 352 sdp_put_seq(&seq, 5); 353 sdp_put_uuid16(&seq, SDP_UUID_PROTOCOL_RFCOMM); 354 sdp_put_uint8(&seq, channel); 355 356 seq.end = seq.next; 357 seq.next = buf; 358 sdp_set_seq(&seq, -1); 359.Ed 360.Pp 361Note that although 362.Dv SIZE 363is assumed to be large enough to contain the entire sequence 364in this case, the 365.Fn sdp_put_xxxx 366routines will not overflow the buffer area or write partial data. 367.Pp 368The encoded data stream will be stored in a space efficient 369manner where possible. 370In the above example, it is known that the data element sequence 371containing the L2CAP UUID will be 8 bytes long overall since the 372container length of 6 can be stored in a single byte. 373But, because the value of 374.Dv SIZE 375is unknown, the overall length of the ProtocolDataList may vary 376depending if 8, 16 or 32 bits were needed to represent the original 377buffer size. 378.Fn sdp_set_seq 379will only modify the content, not the size of the header. 380.Sh SEE ALSO 381.Xr sdpquery 1 , 382.Xr bluetooth 3 , 383.Xr sdp 3 , 384.Xr uuid 3 , 385.Xr sdpd 8 386.Pp 387The 388.Qq Service Discovery Protocol 389section of the Bluetooth Core specifications, available at 390.Lk http://www.bluetooth.com/ 391.Sh HISTORY 392These SDP data parsing and manipulation functions first appeared in 393.Nx 6.0 . 394