]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.sbin/bluetooth/btpand/sdp.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / usr.sbin / bluetooth / btpand / sdp.c
1 /*      $NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $   */
2
3 /*-
4  * Copyright (c) 2008 Iain Hibbert
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /* $FreeBSD$ */
29
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $");
32
33 #include <string.h>
34
35 #include "sdp.h"
36
37 /*
38  * SDP data stream manipulation routines
39  */
40
41 /* Bluetooth Base UUID */
42 static const uuid_t BASE_UUID = {
43         0x00000000,
44         0x0000,
45         0x1000,
46         0x80,
47         0x00,
48         { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }
49 };
50
51 /*
52  * _sdp_match_uuid16(ptr, limit, uuid)
53  *
54  *      examine SDP data stream at ptr for a UUID, and return
55  *      true if it matches the supplied short alias bluetooth UUID.
56  *      limit is the first address past the end of valid data.
57  */
58 bool
59 _sdp_match_uuid16(uint8_t **ptr, uint8_t *limit, uint16_t uuid)
60 {
61         uint8_t *p = *ptr;
62         uuid_t u1, u2;
63
64         memcpy(&u1, &BASE_UUID, sizeof(uuid_t));
65         u1.time_low = uuid;
66
67         if (!_sdp_get_uuid(&p, limit, &u2)
68             || !uuid_equal(&u1, &u2, NULL))
69                 return false;
70
71         *ptr = p;
72         return true;
73 }
74
75 /*
76  * _sdp_get_uuid(ptr, limit, uuid)
77  *
78  *      examine SDP data stream at ptr for a UUID, and extract
79  *      to given storage, advancing ptr.
80  *      limit is the first address past the end of valid data.
81  */
82 bool
83 _sdp_get_uuid(uint8_t **ptr, uint8_t *limit, uuid_t *uuid)
84 {
85         uint8_t *p = *ptr;
86
87         if (p + 1 > limit)
88                 return false;
89
90         switch (*p++) {
91         case SDP_DATA_UUID16:
92                 if (p + 2 > limit)
93                         return false;
94
95                 memcpy(uuid, &BASE_UUID, sizeof(uuid_t));
96                 uuid->time_low = be16dec(p);
97                 p += 2;
98                 break;
99
100         case SDP_DATA_UUID32:
101                 if (p + 4 > limit)
102                         return false;
103
104                 memcpy(uuid, &BASE_UUID, sizeof(uuid_t));
105                 uuid->time_low = be32dec(p);
106                 p += 4;
107                 break;
108
109         case SDP_DATA_UUID128:
110                 if (p + 16 > limit)
111                         return false;
112
113                 uuid_dec_be(p, uuid);
114                 p += 16;
115                 break;
116
117         default:
118                 return false;
119         }
120
121         *ptr = p;
122         return true;
123 }
124
125 /*
126  * _sdp_get_seq(ptr, limit, seq)
127  *
128  *      examine SDP data stream at ptr for a sequence. return
129  *      seq pointer if found and advance ptr to next object.
130  *      limit is the first address past the end of valid data.
131  */
132 bool
133 _sdp_get_seq(uint8_t **ptr, uint8_t *limit, uint8_t **seq)
134 {
135         uint8_t *p = *ptr;
136         int32_t l;
137
138         if (p + 1 > limit)
139                 return false;
140
141         switch (*p++) {
142         case SDP_DATA_SEQ8:
143                 if (p + 1 > limit)
144                         return false;
145
146                 l = *p;
147                 p += 1;
148                 break;
149
150         case SDP_DATA_SEQ16:
151                 if (p + 2 > limit)
152                         return false;
153
154                 l = be16dec(p);
155                 p += 2;
156                 break;
157
158         case SDP_DATA_SEQ32:
159                 if (p + 4 > limit)
160                         return false;
161
162                 l = be32dec(p);
163                 p += 4;
164                 break;
165
166         default:
167                 return false;
168         }
169         if (p + l > limit)
170                 return false;
171
172         *seq = p;
173         *ptr = p + l;
174         return true;
175 }
176
177 /*
178  * _sdp_get_uint16(ptr, limit, value)
179  *
180  *      examine SDP data stream at ptr for a uint16_t, and
181  *      extract to given storage, advancing ptr.
182  *      limit is the first address past the end of valid data.
183  */
184 bool
185 _sdp_get_uint16(uint8_t **ptr, uint8_t *limit, uint16_t *value)
186 {
187         uint8_t *p = *ptr;
188         uint16_t v;
189
190         if (p + 1 > limit)
191                 return false;
192
193         switch (*p++) {
194         case SDP_DATA_UINT16:
195                 if (p + 2 > limit)
196                         return false;
197
198                 v = be16dec(p);
199                 p += 2;
200                 break;
201
202         default:
203                 return false;
204         }
205
206         *value = v;
207         *ptr = p;
208         return true;
209 }