1.\" $NetBSD: sdp_data.3,v 1.6 2010/12/16 10:08:27 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 December 16, 2010 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_int "sdp_data_t *data" "intmax_t value" 127.Ft bool 128.Fn sdp_put_int8 "sdp_data_t *data" "int8_t value" 129.Ft bool 130.Fn sdp_put_int16 "sdp_data_t *data" "int16_t value" 131.Ft bool 132.Fn sdp_put_int32 "sdp_data_t *data" "int32_t value" 133.Ft bool 134.Fn sdp_put_seq "sdp_data_t *data" "ssize_t length" 135.Ft bool 136.Fn sdp_put_alt "sdp_data_t *data" "ssize_t length" 137.Ft bool 138.Fn sdp_put_str "sdp_data_t *data" "const char *str" "ssize_t length" 139.Ft bool 140.Fn sdp_put_url "sdp_data_t *data" "const char *url" "ssize_t length" 141.Ft bool 142.Fn sdp_set_bool "const sdp_data_t *data" "bool value" 143.Ft bool 144.Fn sdp_set_uint "const sdp_data_t *data" "uintmax_t value" 145.Ft bool 146.Fn sdp_set_int "const sdp_data_t *data" "intmax_t value" 147.Ft bool 148.Fn sdp_set_seq "const sdp_data_t *data" "ssize_t length" 149.Ft ssize_t 150.Fn sdp_data_size "const sdp_data_t *data" 151.Ft int 152.Fn sdp_data_type "const sdp_data_t *data" 153.Ft bool 154.Fn sdp_data_valid "const sdp_data_t *data" 155.Ft void 156.Fn sdp_data_print "const sdp_data_t *data" "int indent" 157.Sh DESCRIPTION 158These routines provide for the manipulation of Service Discovery 159Protocol data buffers. 160An SDP data buffer type is defined as: 161.Bd -literal -offset indent 162typedef struct { 163 uint8_t *next; 164 uint8_t *end; 165} sdp_data_t; 166.Ed 167.Pp 168Where 169.Fa next 170points to the next available byte, and 171.Fa end 172points to the first address past end of the data area, such that 173.Qq end = next + length . 174.Pp 175The SDP data consists of byte streams describing data elements, where 176a data element is a typed data representation consisting of a header 177field and a data field. 178The header field consists of type and size descriptors, and the data 179field is a sequence of bytes whose length is specified in the size 180descriptor and whose content is specified by the type descriptor. 181For instance, the byte sequence 182.Qq 0x09, 0x01, 0x00 183describes an 16-bit unsigned integer element (type 0x09) with 184value of 0x0100. 185.Pp 186Data element types including signed and unsigned integers, boolean, 187string, sequence and alternative lists are defined in the 188.In sdp.h 189include file. 190See the 191.Qq Service Discovery Protocol 192chapters of the 193.Qq Bluetooth Core Specifications 194for more information. 195.Pp 196To reduce the burden of storing and transferring 128-bit UUID values, a 197range of UUID values has been pre-allocated for assignment to often-used, 198registered purposes. 199The first UUID in this pre-allocated range is known as the 200.Qq Bluetooth Base UUID , 201defined in the 202.Qq Bluetooth Assigned Numbers 203document and declared in 204.In sdp.h 205as 206.Vt const uuid_t BLUETOOTH_BASE_UUID ; 207.Pp 208The data manipulation routines are arranged into major groups 209by function: 210.Bl -hang 211.It The Fn sdp_match_uuid16 212routine examines the next data element in the data buffer for 213an element of type UUID that matches the Bluetooth short alias 214UUID with 16-bit value given. 215If the UUID matches, the function will return 216.Dv true 217and the 218.Fa next 219field of the SDP data buffer will be advanced to the next element. 220Otherwise 221.Dv false 222will be returned. 223.It The Fn sdp_get_xxxx 224routines examine the next data element in the data buffer for an 225element of the given type. 226If the type matches, the function will extract the typed value to 227the address given and advance the 228.Fa next 229field of the SDP data buffer to the next element then return 230.Dv true . 231Otherwise 232.Dv false 233will be returned. 234Note, these functions will not modify the 235.Fa data 236argument unless the correct type was found, and will update the 237.Fa data 238argument first to allow discarding in the case where a 239.Dv sdp_data_t 240was being returned. 241.It The Fn sdp_put_xxxx 242routines will attempt to write a data element of the given type 243and value to the data buffer. 244If the data buffer is too small to contain the encoded data element, 245the function will return 246.Dv false , 247otherwise 248.Dv true 249will be returned and the 250.Fa next 251field of the SDP data pointer will be advanced. 252In the case of 253.Fn sdp_put_seq 254and 255.Fn sdp_put_alt , 256the 257.Fa length 258argument may be -1, in which case the generated sequence header will 259describe all the remaining buffer space. 260For 261.Fn sdp_put_str 262and 263.Fn sdp_put_url 264the 265.Fa length 266argument may be -1 in which case the string pointer is treated as 267nul terminated. 268.It The Fn sdp_set_xxxx 269routines examine the SDP data buffer for a data element of the given 270type, and replace the content with the passed value. 271If the next data element in the buffer is not of the appropriate 272type, the function will return 273.Dv false , 274otherwise 275.Dv true 276will be returned and the value updated. 277In the case of 278.Fn sdp_set_seq 279and 280.Fn sdp_set_alt , 281the 282.Fa length 283argument may be -1, in which case the sequence header will be 284adjusted to describe the entire data space where possible. 285.It The Fn sdp_data_xxxx 286routines include various functions to provide information about 287the data stream such as 288.Fn sdp_data_size 289to return the size of the next data element, and 290.Fn sdp_data_type 291to return the type of the next data element. 292.Fn sdp_data_valid 293can be used to ensure that the entire data buffer contains 294valid SDP data elements and that all of the elements are contained 295exactly within the data buffer. 296Finally, 297.Fn sdp_data_print 298will print the data buffer in human readable format. 299.El 300.Sh EXAMPLES 301To parse a ServiceAttribute response obtained from a remote server 302using 303.Xr sdp_service_attribute 3 , 304examining various attribute values: 305.Bd -literal 306 sdp_data_t rsp, val; 307 uint16_t attr; 308 uintmax_t handle; 309 310 /* rsp contains remote response */ 311 312 while (sdp_get_attr(\*[Am]rsp, \*[Am]attr, \*[Am]val)) { 313 switch(attr) { 314 case SDP_ATTR_SERVICE_RECORD_HANDLE: 315 sdp_get_uint(\*[Am]val, \*[Am]handle); 316 printf("ServiceRecordHandle: 0x%08x\\n", handle); 317 break; 318 319 case SDP_ATTR_PROFILE_DESCRIPTOR_LIST: 320 printf("ProfileDescriptorList:\\n"); 321 sdp_data_print(\*[Am]val, 0); 322 break; 323 324 default: 325 printf("uninteresting attribute 0x%04x\\n", attr); 326 break; 327 } 328 } 329.Ed 330.Pp 331The following code creates a ProtocolDataList attribute value for a service 332using the L2CAP and RFCOMM protocols and illustrates how to construct sequences 333of known and unknown length. 334.Bd -literal 335 uint8_t buf[SIZE]; 336 sdp_data_t seq; 337 uint16_t psm; 338 uint8_t channel; 339 340 seq.next = buf; 341 seq.end = buf + sizeof(buf); 342 sdp_put_seq(\*[Am]seq, -1); 343 344 sdp_put_seq(\*[Am]seq, 6); 345 sdp_put_uuid16(\*[Am]seq, SDP_UUID_PROTOCOL_L2CAP); 346 sdp_put_uint16(\*[Am]seq, psm); 347 348 sdp_put_seq(\*[Am]seq, 5); 349 sdp_put_uuid16(\*[Am]seq, SDP_UUID_PROTOCOL_RFCOMM); 350 sdp_put_uint8(\*[Am]seq, channel); 351 352 seq.end = seq.next; 353 seq.next = buf; 354 sdp_set_seq(\*[Am]seq, -1); 355.Ed 356.Pp 357Note that although 358.Dv SIZE 359is assumed to be large enough to contain the entire sequence 360in this case, the 361.Fn sdp_put_xxxx 362routines will not overflow the buffer area or write partial data. 363.Pp 364The encoded data stream will be stored in a space efficient 365manner where possible. 366In the above example, it is known that the data element sequence 367containing the L2CAP UUID will be 8 bytes long overall since the 368container length of 6 can be stored in a single byte. 369But, because the value of 370.Dv SIZE 371is unknown, the overall length of the ProtocolDataList may vary 372depending if 8, 16 or 32 bits were needed to represent the original 373buffer size. 374.Fn sdp_seq_seq 375will only modify the content, not the size of the header. 376.Sh SEE ALSO 377.Xr sdpquery 1 , 378.Xr bluetooth 3 , 379.Xr sdp 3 , 380.Xr uuid 3 , 381.Xr sdpd 8 382.Pp 383The 384.Qq Service Discovery Protocol 385section of the Bluetooth Core specifications, available at 386.Qq http://www.bluetooth.com/ 387.Sh HISTORY 388These SDP data parsing and manipulation functions first appeared in 389.Nx 6.0 . 390