1 /* $NetBSD: sdp_put.c,v 1.1 2009/05/12 10:05:06 plunky Exp $ */
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_put.c,v 1.1 2009/05/12 10:05:06 plunky Exp $");
35 #include <bluetooth.h>
40 /******************************************************************************
41 * sdp_put_xxxx(data, value)
43 * write a value to data space and advance data pointers,
44 * fail if data space is not large enough
48 sdp_put_data(sdp_data_t
*data
, sdp_data_t
*value
)
52 len
= value
->end
- value
->next
;
54 if (data
->next
+ len
> data
->end
)
57 memcpy(data
->next
, value
->next
, (size_t)len
);
63 sdp_put_attr(sdp_data_t
*data
, uint16_t attr
, sdp_data_t
*value
)
67 if (!sdp_put_uint16(&d
, attr
)
68 || sdp_put_data(&d
, value
))
76 sdp_put_uuid(sdp_data_t
*data
, const uuid_t
*uuid
)
82 if (uuid_equal(&u
, &BLUETOOTH_BASE_UUID
, NULL
) == 0)
83 return sdp_put_uuid128(data
, uuid
);
85 if (uuid
->time_low
> UINT16_MAX
)
86 return sdp_put_uuid32(data
, (uint32_t)uuid
->time_low
);
88 return sdp_put_uuid16(data
, (uint16_t)uuid
->time_low
);
92 sdp_put_uuid16(sdp_data_t
*data
, uint16_t uuid
)
95 if (data
->next
+ 3 > data
->end
)
98 data
->next
[0] = SDP_DATA_UUID16
;
99 be16enc(data
->next
+ 1, uuid
);
105 sdp_put_uuid32(sdp_data_t
*data
, uint32_t uuid
)
108 if (data
->next
+ 5 > data
->end
)
111 data
->next
[0] = SDP_DATA_UUID32
;
112 be32enc(data
->next
+ 1, uuid
);
118 sdp_put_uuid128(sdp_data_t
*data
, const uuid_t
*uuid
)
121 if (data
->next
+ 17 > data
->end
)
124 data
->next
[0] = SDP_DATA_UUID128
;
125 uuid_enc_be(data
->next
+ 1, uuid
);
131 sdp_put_bool(sdp_data_t
*data
, bool value
)
134 if (data
->next
+ 2 > data
->end
)
137 data
->next
[0] = SDP_DATA_BOOL
;
138 data
->next
[1] = (value
? 0x01 : 0x00);
144 sdp_put_uint(sdp_data_t
*data
, uintmax_t value
)
147 if (value
> UINT64_MAX
)
150 if (value
> UINT32_MAX
)
151 return sdp_put_uint64(data
, (uint64_t)value
);
153 if (value
> UINT16_MAX
)
154 return sdp_put_uint32(data
, (uint32_t)value
);
156 if (value
> UINT8_MAX
)
157 return sdp_put_uint16(data
, (uint16_t)value
);
159 return sdp_put_uint8(data
, (uint8_t)value
);
163 sdp_put_uint8(sdp_data_t
*data
, uint8_t value
)
166 if (data
->next
+ 2 > data
->end
)
169 data
->next
[0] = SDP_DATA_UINT8
;
170 data
->next
[1] = value
;
176 sdp_put_uint16(sdp_data_t
*data
, uint16_t value
)
179 if (data
->next
+ 3 > data
->end
)
182 data
->next
[0] = SDP_DATA_UINT16
;
183 be16enc(data
->next
+ 1, value
);
189 sdp_put_uint32(sdp_data_t
*data
, uint32_t value
)
192 if (data
->next
+ 5 > data
->end
)
195 data
->next
[0] = SDP_DATA_UINT32
;
196 be32enc(data
->next
+ 1, value
);
202 sdp_put_uint64(sdp_data_t
*data
, uint64_t value
)
205 if (data
->next
+ 9 > data
->end
)
208 data
->next
[0] = SDP_DATA_UINT64
;
209 be64enc(data
->next
+ 1, value
);
215 sdp_put_int(sdp_data_t
*data
, intmax_t value
)
218 if (value
> INT64_MAX
|| value
< INT64_MIN
)
221 if (value
> INT32_MAX
|| value
< INT32_MIN
)
222 return sdp_put_int64(data
, (int64_t)value
);
224 if (value
> INT16_MAX
|| value
< INT16_MIN
)
225 return sdp_put_int32(data
, (int32_t)value
);
227 if (value
> INT8_MAX
|| value
< INT8_MIN
)
228 return sdp_put_int16(data
, (int16_t)value
);
230 return sdp_put_int8(data
, (int8_t)value
);
234 sdp_put_int8(sdp_data_t
*data
, int8_t value
)
237 if (data
->next
+ 2 > data
->end
)
240 data
->next
[0] = SDP_DATA_INT8
;
241 data
->next
[1] = (uint8_t)value
;
247 sdp_put_int16(sdp_data_t
*data
, int16_t value
)
250 if (data
->next
+ 3 > data
->end
)
253 data
->next
[0] = SDP_DATA_INT16
;
254 be16enc(data
->next
+ 1, (uint16_t)value
);
260 sdp_put_int32(sdp_data_t
*data
, int32_t value
)
263 if (data
->next
+ 5 > data
->end
)
266 data
->next
[0] = SDP_DATA_INT32
;
267 be32enc(data
->next
+ 1, (uint32_t)value
);
273 sdp_put_int64(sdp_data_t
*data
, int64_t value
)
276 if (data
->next
+ 9 > data
->end
)
279 data
->next
[0] = SDP_DATA_INT64
;
280 be64enc(data
->next
+ 1, (uint64_t)value
);
286 _sdp_put_ext(uint8_t type
, sdp_data_t
*data
, ssize_t len
)
288 uint8_t *p
= data
->next
;
291 if (p
+ 2 > data
->end
)
294 len
= data
->end
- p
- 2;
299 if (len
> UINT16_MAX
)
303 if ((size_t)len
> UINT32_MAX
)
306 if ((size_t)len
> UINT16_MAX
) {
307 if (p
+ 5 + len
> data
->end
)
310 p
[0] = type
| SDP_DATA_EXT32
;
311 be32enc(p
+ 1, (uint32_t)len
);
313 } else if ((size_t)len
> UINT8_MAX
) {
314 if (p
+ 3 + len
> data
->end
)
317 p
[0] = type
| SDP_DATA_EXT16
;
318 be16enc(p
+ 1, (uint16_t)len
);
321 if (p
+ 2 + len
> data
->end
)
324 p
[0] = type
| SDP_DATA_EXT8
;
334 sdp_put_seq(sdp_data_t
*data
, ssize_t len
)
337 return _sdp_put_ext(SDP_DATA_SEQ
, data
, len
);
341 sdp_put_alt(sdp_data_t
*data
, ssize_t len
)
344 return _sdp_put_ext(SDP_DATA_ALT
, data
, len
);
348 sdp_put_str(sdp_data_t
*data
, const char *str
, ssize_t len
)
354 if (!_sdp_put_ext(SDP_DATA_STR
, data
, len
))
357 memcpy(data
->next
, str
, len
);
363 sdp_put_url(sdp_data_t
*data
, const char *url
, ssize_t len
)
369 if (!_sdp_put_ext(SDP_DATA_URL
, data
, len
))
372 memcpy(data
->next
, url
, len
);