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