Sync usage with man page.
[netbsd-mini2440.git] / lib / libbluetooth / sdp_put.c
blob2a37ce5edc9d5e80a3929d7fb890188eddfd6671
1 /* $NetBSD: sdp_put.c,v 1.1 2009/05/12 10:05:06 plunky Exp $ */
3 /*-
4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Iain Hibbert.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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>
36 #include <limits.h>
37 #include <sdp.h>
38 #include <string.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
47 bool
48 sdp_put_data(sdp_data_t *data, sdp_data_t *value)
50 ssize_t len;
52 len = value->end - value->next;
54 if (data->next + len > data->end)
55 return false;
57 memcpy(data->next, value->next, (size_t)len);
58 data->next += len;
59 return true;
62 bool
63 sdp_put_attr(sdp_data_t *data, uint16_t attr, sdp_data_t *value)
65 sdp_data_t d = *data;
67 if (!sdp_put_uint16(&d, attr)
68 || sdp_put_data(&d, value))
69 return false;
71 *data = d;
72 return true;
75 bool
76 sdp_put_uuid(sdp_data_t *data, const uuid_t *uuid)
78 uuid_t u = *uuid;
80 u.time_low = 0;
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);
91 bool
92 sdp_put_uuid16(sdp_data_t *data, uint16_t uuid)
95 if (data->next + 3 > data->end)
96 return false;
98 data->next[0] = SDP_DATA_UUID16;
99 be16enc(data->next + 1, uuid);
100 data->next += 3;
101 return true;
104 bool
105 sdp_put_uuid32(sdp_data_t *data, uint32_t uuid)
108 if (data->next + 5 > data->end)
109 return false;
111 data->next[0] = SDP_DATA_UUID32;
112 be32enc(data->next + 1, uuid);
113 data->next += 5;
114 return true;
117 bool
118 sdp_put_uuid128(sdp_data_t *data, const uuid_t *uuid)
121 if (data->next + 17 > data->end)
122 return false;
124 data->next[0] = SDP_DATA_UUID128;
125 uuid_enc_be(data->next + 1, uuid);
126 data->next += 17;
127 return true;
130 bool
131 sdp_put_bool(sdp_data_t *data, bool value)
134 if (data->next + 2 > data->end)
135 return false;
137 data->next[0] = SDP_DATA_BOOL;
138 data->next[1] = (value ? 0x01 : 0x00);
139 data->next += 2;
140 return true;
143 bool
144 sdp_put_uint(sdp_data_t *data, uintmax_t value)
147 if (value > UINT64_MAX)
148 return false;
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);
162 bool
163 sdp_put_uint8(sdp_data_t *data, uint8_t value)
166 if (data->next + 2 > data->end)
167 return false;
169 data->next[0] = SDP_DATA_UINT8;
170 data->next[1] = value;
171 data->next += 2;
172 return true;
175 bool
176 sdp_put_uint16(sdp_data_t *data, uint16_t value)
179 if (data->next + 3 > data->end)
180 return false;
182 data->next[0] = SDP_DATA_UINT16;
183 be16enc(data->next + 1, value);
184 data->next += 3;
185 return true;
188 bool
189 sdp_put_uint32(sdp_data_t *data, uint32_t value)
192 if (data->next + 5 > data->end)
193 return false;
195 data->next[0] = SDP_DATA_UINT32;
196 be32enc(data->next + 1, value);
197 data->next += 5;
198 return true;
201 bool
202 sdp_put_uint64(sdp_data_t *data, uint64_t value)
205 if (data->next + 9 > data->end)
206 return false;
208 data->next[0] = SDP_DATA_UINT64;
209 be64enc(data->next + 1, value);
210 data->next += 9;
211 return true;
214 bool
215 sdp_put_int(sdp_data_t *data, intmax_t value)
218 if (value > INT64_MAX || value < INT64_MIN)
219 return false;
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);
233 bool
234 sdp_put_int8(sdp_data_t *data, int8_t value)
237 if (data->next + 2 > data->end)
238 return false;
240 data->next[0] = SDP_DATA_INT8;
241 data->next[1] = (uint8_t)value;
242 data->next += 2;
243 return true;
246 bool
247 sdp_put_int16(sdp_data_t *data, int16_t value)
250 if (data->next + 3 > data->end)
251 return false;
253 data->next[0] = SDP_DATA_INT16;
254 be16enc(data->next + 1, (uint16_t)value);
255 data->next += 3;
256 return true;
259 bool
260 sdp_put_int32(sdp_data_t *data, int32_t value)
263 if (data->next + 5 > data->end)
264 return false;
266 data->next[0] = SDP_DATA_INT32;
267 be32enc(data->next + 1, (uint32_t)value);
268 data->next += 5;
269 return true;
272 bool
273 sdp_put_int64(sdp_data_t *data, int64_t value)
276 if (data->next + 9 > data->end)
277 return false;
279 data->next[0] = SDP_DATA_INT64;
280 be64enc(data->next + 1, (uint64_t)value);
281 data->next += 9;
282 return true;
285 static bool
286 _sdp_put_ext(uint8_t type, sdp_data_t *data, ssize_t len)
288 uint8_t *p = data->next;
290 if (len == -1) {
291 if (p + 2 > data->end)
292 return false;
294 len = data->end - p - 2;
296 if (len > UINT8_MAX)
297 len -= 1;
299 if (len > UINT16_MAX)
300 len -= 2;
303 if ((size_t)len > UINT32_MAX)
304 return false;
306 if ((size_t)len > UINT16_MAX) {
307 if (p + 5 + len > data->end)
308 return false;
310 p[0] = type | SDP_DATA_EXT32;
311 be32enc(p + 1, (uint32_t)len);
312 p += 5;
313 } else if ((size_t)len > UINT8_MAX) {
314 if (p + 3 + len > data->end)
315 return false;
317 p[0] = type | SDP_DATA_EXT16;
318 be16enc(p + 1, (uint16_t)len);
319 p += 3;
320 } else {
321 if (p + 2 + len > data->end)
322 return false;
324 p[0] = type | SDP_DATA_EXT8;
325 p[1] = (uint8_t)len;
326 p += 2;
329 data->next = p;
330 return true;
333 bool
334 sdp_put_seq(sdp_data_t *data, ssize_t len)
337 return _sdp_put_ext(SDP_DATA_SEQ, data, len);
340 bool
341 sdp_put_alt(sdp_data_t *data, ssize_t len)
344 return _sdp_put_ext(SDP_DATA_ALT, data, len);
347 bool
348 sdp_put_str(sdp_data_t *data, const char *str, ssize_t len)
351 if (len == -1)
352 len = strlen(str);
354 if (!_sdp_put_ext(SDP_DATA_STR, data, len))
355 return false;
357 memcpy(data->next, str, len);
358 data->next += len;
359 return true;
362 bool
363 sdp_put_url(sdp_data_t *data, const char *url, ssize_t len)
366 if (len == -1)
367 len = strlen(url);
369 if (!_sdp_put_ext(SDP_DATA_URL, data, len))
370 return false;
372 memcpy(data->next, url, len);
373 data->next += len;
374 return true;