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