Annotation of src/lib/libbluetooth/sdp_put.c, Revision 1.6
1.6 ! plunky 1: /* $NetBSD: sdp_put.c,v 1.5 2011/04/05 18:19:04 plunky Exp $ */
1.1 plunky 2:
3: /*-
4: * Copyright (c) 2009 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Iain Hibbert.
9: *
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.
18: *
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.
30: */
31:
32: #include <sys/cdefs.h>
1.6 ! plunky 33: __RCSID("$NetBSD: sdp_put.c,v 1.5 2011/04/05 18:19:04 plunky Exp $");
1.1 plunky 34:
35: #include <bluetooth.h>
36: #include <limits.h>
37: #include <sdp.h>
38: #include <string.h>
39:
40: /******************************************************************************
41: * sdp_put_xxxx(data, value)
42: *
43: * write a value to data space and advance data pointers,
44: * fail if data space is not large enough
45: */
46:
47: bool
48: sdp_put_data(sdp_data_t *data, sdp_data_t *value)
49: {
50: ssize_t len;
51:
52: len = value->end - value->next;
53:
1.5 plunky 54: if (len > data->end - data->next)
1.1 plunky 55: return false;
56:
57: memcpy(data->next, value->next, (size_t)len);
58: data->next += len;
59: return true;
60: }
61:
62: bool
63: sdp_put_attr(sdp_data_t *data, uint16_t attr, sdp_data_t *value)
64: {
65: sdp_data_t d = *data;
66:
67: if (!sdp_put_uint16(&d, attr)
1.6 ! plunky 68: || sdp_data_size(value) != (value->end - value->next)
1.4 plunky 69: || !sdp_put_data(&d, value))
1.1 plunky 70: return false;
71:
72: *data = d;
73: return true;
74: }
75:
76: bool
77: sdp_put_uuid(sdp_data_t *data, const uuid_t *uuid)
78: {
79: uuid_t u = *uuid;
80:
81: u.time_low = 0;
82:
83: if (uuid_equal(&u, &BLUETOOTH_BASE_UUID, NULL) == 0)
84: return sdp_put_uuid128(data, uuid);
85:
86: if (uuid->time_low > UINT16_MAX)
87: return sdp_put_uuid32(data, (uint32_t)uuid->time_low);
88:
89: return sdp_put_uuid16(data, (uint16_t)uuid->time_low);
90: }
91:
92: bool
93: sdp_put_uuid16(sdp_data_t *data, uint16_t uuid)
94: {
95:
96: if (data->next + 3 > data->end)
97: return false;
98:
99: data->next[0] = SDP_DATA_UUID16;
100: be16enc(data->next + 1, uuid);
101: data->next += 3;
102: return true;
103: }
104:
105: bool
106: sdp_put_uuid32(sdp_data_t *data, uint32_t uuid)
107: {
108:
109: if (data->next + 5 > data->end)
110: return false;
111:
112: data->next[0] = SDP_DATA_UUID32;
113: be32enc(data->next + 1, uuid);
114: data->next += 5;
115: return true;
116: }
117:
118: bool
119: sdp_put_uuid128(sdp_data_t *data, const uuid_t *uuid)
120: {
121:
122: if (data->next + 17 > data->end)
123: return false;
124:
125: data->next[0] = SDP_DATA_UUID128;
126: uuid_enc_be(data->next + 1, uuid);
127: data->next += 17;
128: return true;
129: }
130:
131: bool
132: sdp_put_bool(sdp_data_t *data, bool value)
133: {
134:
135: if (data->next + 2 > data->end)
136: return false;
137:
138: data->next[0] = SDP_DATA_BOOL;
139: data->next[1] = (value ? 0x01 : 0x00);
140: data->next += 2;
141: return true;
142: }
143:
144: bool
145: sdp_put_uint(sdp_data_t *data, uintmax_t value)
146: {
147:
148: if (value > UINT64_MAX)
149: return false;
150:
151: if (value > UINT32_MAX)
152: return sdp_put_uint64(data, (uint64_t)value);
153:
154: if (value > UINT16_MAX)
155: return sdp_put_uint32(data, (uint32_t)value);
156:
157: if (value > UINT8_MAX)
158: return sdp_put_uint16(data, (uint16_t)value);
159:
160: return sdp_put_uint8(data, (uint8_t)value);
161: }
162:
163: bool
164: sdp_put_uint8(sdp_data_t *data, uint8_t value)
165: {
166:
167: if (data->next + 2 > data->end)
168: return false;
169:
170: data->next[0] = SDP_DATA_UINT8;
171: data->next[1] = value;
172: data->next += 2;
173: return true;
174: }
175:
176: bool
177: sdp_put_uint16(sdp_data_t *data, uint16_t value)
178: {
179:
180: if (data->next + 3 > data->end)
181: return false;
182:
183: data->next[0] = SDP_DATA_UINT16;
184: be16enc(data->next + 1, value);
185: data->next += 3;
186: return true;
187: }
188:
189: bool
190: sdp_put_uint32(sdp_data_t *data, uint32_t value)
191: {
192:
193: if (data->next + 5 > data->end)
194: return false;
195:
196: data->next[0] = SDP_DATA_UINT32;
197: be32enc(data->next + 1, value);
198: data->next += 5;
199: return true;
200: }
201:
202: bool
203: sdp_put_uint64(sdp_data_t *data, uint64_t value)
204: {
205:
206: if (data->next + 9 > data->end)
207: return false;
208:
209: data->next[0] = SDP_DATA_UINT64;
210: be64enc(data->next + 1, value);
211: data->next += 9;
212: return true;
213: }
214:
215: bool
216: sdp_put_int(sdp_data_t *data, intmax_t value)
217: {
218:
219: if (value > INT64_MAX || value < INT64_MIN)
220: return false;
221:
222: if (value > INT32_MAX || value < INT32_MIN)
223: return sdp_put_int64(data, (int64_t)value);
224:
225: if (value > INT16_MAX || value < INT16_MIN)
226: return sdp_put_int32(data, (int32_t)value);
227:
228: if (value > INT8_MAX || value < INT8_MIN)
229: return sdp_put_int16(data, (int16_t)value);
230:
231: return sdp_put_int8(data, (int8_t)value);
232: }
233:
234: bool
235: sdp_put_int8(sdp_data_t *data, int8_t value)
236: {
237:
238: if (data->next + 2 > data->end)
239: return false;
240:
241: data->next[0] = SDP_DATA_INT8;
242: data->next[1] = (uint8_t)value;
243: data->next += 2;
244: return true;
245: }
246:
247: bool
248: sdp_put_int16(sdp_data_t *data, int16_t value)
249: {
250:
251: if (data->next + 3 > data->end)
252: return false;
253:
254: data->next[0] = SDP_DATA_INT16;
255: be16enc(data->next + 1, (uint16_t)value);
256: data->next += 3;
257: return true;
258: }
259:
260: bool
261: sdp_put_int32(sdp_data_t *data, int32_t value)
262: {
263:
264: if (data->next + 5 > data->end)
265: return false;
266:
267: data->next[0] = SDP_DATA_INT32;
268: be32enc(data->next + 1, (uint32_t)value);
269: data->next += 5;
270: return true;
271: }
272:
273: bool
274: sdp_put_int64(sdp_data_t *data, int64_t value)
275: {
276:
277: if (data->next + 9 > data->end)
278: return false;
279:
280: data->next[0] = SDP_DATA_INT64;
281: be64enc(data->next + 1, (uint64_t)value);
282: data->next += 9;
283: return true;
284: }
285:
286: static bool
287: _sdp_put_ext(uint8_t type, sdp_data_t *data, ssize_t len)
288: {
289: uint8_t *p = data->next;
290:
291: if (len == -1) {
292: if (p + 2 > data->end)
293: return false;
294:
295: len = data->end - p - 2;
296:
297: if (len > UINT8_MAX)
298: len -= 1;
299:
300: if (len > UINT16_MAX)
301: len -= 2;
302: }
303:
1.2 plunky 304: if ((size_t)len > UINT32_MAX)
1.1 plunky 305: return false;
306:
1.2 plunky 307: if ((size_t)len > UINT16_MAX) {
1.5 plunky 308: if (len > data->end - 5 - p)
1.1 plunky 309: return false;
310:
311: p[0] = type | SDP_DATA_EXT32;
312: be32enc(p + 1, (uint32_t)len);
313: p += 5;
1.2 plunky 314: } else if ((size_t)len > UINT8_MAX) {
1.5 plunky 315: if (len > data->end - 3 - p)
1.1 plunky 316: return false;
317:
318: p[0] = type | SDP_DATA_EXT16;
319: be16enc(p + 1, (uint16_t)len);
320: p += 3;
321: } else {
1.5 plunky 322: if (len > data->end - 2 - p)
1.1 plunky 323: return false;
324:
325: p[0] = type | SDP_DATA_EXT8;
326: p[1] = (uint8_t)len;
327: p += 2;
328: }
329:
330: data->next = p;
331: return true;
332: }
333:
334: bool
335: sdp_put_seq(sdp_data_t *data, ssize_t len)
336: {
337:
338: return _sdp_put_ext(SDP_DATA_SEQ, data, len);
339: }
340:
341: bool
342: sdp_put_alt(sdp_data_t *data, ssize_t len)
343: {
344:
345: return _sdp_put_ext(SDP_DATA_ALT, data, len);
346: }
347:
348: bool
349: sdp_put_str(sdp_data_t *data, const char *str, ssize_t len)
350: {
351:
352: if (len == -1)
353: len = strlen(str);
354:
355: if (!_sdp_put_ext(SDP_DATA_STR, data, len))
356: return false;
357:
1.3 plunky 358: memcpy(data->next, str, (size_t)len);
1.1 plunky 359: data->next += len;
360: return true;
361: }
362:
363: bool
364: sdp_put_url(sdp_data_t *data, const char *url, ssize_t len)
365: {
366:
367: if (len == -1)
368: len = strlen(url);
369:
370: if (!_sdp_put_ext(SDP_DATA_URL, data, len))
371: return false;
372:
1.3 plunky 373: memcpy(data->next, url, (size_t)len);
1.1 plunky 374: data->next += len;
375: return true;
376: }
CVSweb <webmaster@jp.NetBSD.org>