xref: /netbsd-src/lib/libbluetooth/sdp_data.3 (revision 01869ca4d24a86379a68731bf9706a9f0820fe4e)
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