1 /* $NetBSD: sdp_get.c$ */
4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: sdp_get.c$");
38 /******************************************************************************
39 * sdp_get_xxxx(data, value)
41 * examine first SDP data element in list for xxx type, extracting to given
42 * storage and advancing pointer if found.
43 * - these functions will not modify data pointer unless the value was
44 * extracted successfully
45 * - these functions always update the data pointer before the value pointer,
46 * so where the value is a sdp_data_t the data struct can be discarded.
50 sdp_get_data(sdp_data_t
*data
, sdp_data_t
*value
)
52 uint8_t *p
= data
->next
;
53 ssize_t l
= sdp_data_size(data
);
66 sdp_get_attr(sdp_data_t
*data
, uint16_t *attr
, sdp_data_t
*value
)
68 sdp_data_t v
, d
= *data
;
71 if (sdp_data_type(&d
) != SDP_DATA_UINT16
72 || !sdp_get_uint(&d
, &a
)
73 || !sdp_get_data(&d
, &v
))
83 sdp_get_uuid(sdp_data_t
*data
, uuid_t
*uuid
)
85 uint8_t *p
= data
->next
;
87 if (p
+ 1 > data
->end
)
92 if (p
+ 2 > data
->end
)
95 *uuid
= BLUETOOTH_BASE_UUID
;
96 uuid
->time_low
= be16dec(p
);
100 case SDP_DATA_UUID32
:
101 if (p
+ 4 > data
->end
)
104 *uuid
= BLUETOOTH_BASE_UUID
;
105 uuid
->time_low
= be32dec(p
);
109 case SDP_DATA_UUID128
:
110 if (p
+ 16 > data
->end
)
113 uuid_dec_be(p
, uuid
);
126 sdp_get_bool(sdp_data_t
*data
, bool *value
)
128 uint8_t *p
= data
->next
;
131 if (p
+ 1 > data
->end
)
136 if (p
+ 1 > data
->end
)
148 *value
= ((v
!= 0) ? true : false);
153 sdp_get_uint(sdp_data_t
*data
, uintmax_t *value
)
155 uint8_t *p
= data
->next
;
158 if (p
+ 1 > data
->end
)
163 if (p
+ 1 > data
->end
)
170 case SDP_DATA_UINT16
:
171 if (p
+ 2 > data
->end
)
178 case SDP_DATA_UINT32
:
179 if (p
+ 4 > data
->end
)
186 case SDP_DATA_UINT64
:
187 if (p
+ 8 > data
->end
)
197 case SDP_DATA_UINT128
:
198 if (p
+ 16 > data
->end
)
203 if (x
!= 0 || v
> UINTMAX_MAX
)
214 *value
= (uintmax_t)v
;
219 sdp_get_int(sdp_data_t
*data
, intmax_t *value
)
221 uint8_t *p
= data
->next
;
224 if (p
+ 1 > data
->end
)
229 if (p
+ 1 > data
->end
)
237 if (p
+ 2 > data
->end
)
240 v
= (int16_t)be16dec(p
);
245 if (p
+ 4 > data
->end
)
248 v
= (int32_t)be32dec(p
);
253 if (p
+ 8 > data
->end
)
256 v
= (int64_t)be64dec(p
);
257 if (v
> INTMAX_MAX
|| v
< INTMAX_MIN
)
263 case SDP_DATA_INT128
:
264 if (p
+ 16 > data
->end
)
267 x
= (int64_t)be64dec(p
);
268 v
= (int64_t)be64dec(p
+ 8);
272 } else if (x
== -1) {
287 *value
= (intmax_t)v
;
292 _sdp_get_ext(uint8_t type
, sdp_data_t
*data
, sdp_data_t
*ext
)
294 uint8_t *p
= data
->next
;
297 if (p
+ 1 > data
->end
298 || SDP_DATA_TYPE(*p
) != type
)
301 switch (SDP_DATA_SIZE(*p
++)) {
303 if (p
+ 1 > data
->end
)
311 if (p
+ 2 > data
->end
)
319 if (p
+ 4 > data
->end
)
330 if (p
+ l
> data
->end
)
340 sdp_get_seq(sdp_data_t
*data
, sdp_data_t
*seq
)
343 return _sdp_get_ext(SDP_DATA_SEQ
, data
, seq
);
347 sdp_get_alt(sdp_data_t
*data
, sdp_data_t
*alt
)
350 return _sdp_get_ext(SDP_DATA_ALT
, data
, alt
);
354 sdp_get_str(sdp_data_t
*data
, char **str
, size_t *len
)
358 if (!_sdp_get_ext(SDP_DATA_STR
, data
, &s
))
361 *str
= (char *)s
.next
;
362 *len
= s
.end
- s
.next
;
367 sdp_get_url(sdp_data_t
*data
, char **url
, size_t *len
)
371 if (!_sdp_get_ext(SDP_DATA_URL
, data
, &u
))
374 *url
= (char *)u
.next
;
375 *len
= u
.end
- u
.next
;