1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include <inttypes.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include "os/os_mbuf.h"
26 #include "nimble/ble.h"
27 #include "ble_hs_priv.h"
28 #include "host/ble_uuid.h"
29
30 static uint8_t ble_uuid_base[16] = {
31 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
32 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
33 };
34
35 #if MYNEWT_VAL(BLE_HS_DEBUG)
36 #define VERIFY_UUID(uuid) \
37 assert((uuid->type == BLE_UUID_TYPE_16) || \
38 (uuid->type == BLE_UUID_TYPE_32) || \
39 (uuid->type == BLE_UUID_TYPE_128))
40 #else
41 #define VERIFY_UUID(uuid)
42 #endif
43
44 int
ble_uuid_init_from_buf(ble_uuid_any_t * uuid,const void * buf,size_t len)45 ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len)
46 {
47 switch (len) {
48 case 2:
49 uuid->u.type = BLE_UUID_TYPE_16;
50 uuid->u16.value = get_le16(buf);
51 return 0;
52 case 4:
53 uuid->u.type = BLE_UUID_TYPE_32;
54 uuid->u32.value = get_le32(buf);
55 return 0;
56 case 16:
57 uuid->u.type = BLE_UUID_TYPE_128;
58 memcpy(uuid->u128.value, buf, 16);
59 return 0;
60 }
61
62 return BLE_HS_EINVAL;
63 }
64
65 int
ble_uuid_cmp(const ble_uuid_t * uuid1,const ble_uuid_t * uuid2)66 ble_uuid_cmp(const ble_uuid_t *uuid1, const ble_uuid_t *uuid2)
67 {
68 VERIFY_UUID(uuid1);
69 VERIFY_UUID(uuid2);
70
71 if (uuid1->type != uuid2->type) {
72 return uuid1->type - uuid2->type;
73 }
74
75 switch (uuid1->type) {
76 case BLE_UUID_TYPE_16:
77 return (int) BLE_UUID16(uuid1)->value - (int) BLE_UUID16(uuid2)->value;
78 case BLE_UUID_TYPE_32:
79 return (int) BLE_UUID32(uuid1)->value - (int) BLE_UUID32(uuid2)->value;
80 case BLE_UUID_TYPE_128:
81 return memcmp(BLE_UUID128(uuid1)->value, BLE_UUID128(uuid2)->value, 16);
82 }
83
84 BLE_HS_DBG_ASSERT(0);
85
86 return -1;
87 }
88
89 void
ble_uuid_copy(ble_uuid_any_t * dst,const ble_uuid_t * src)90 ble_uuid_copy(ble_uuid_any_t *dst, const ble_uuid_t *src)
91 {
92 VERIFY_UUID(src);
93
94 switch (src->type) {
95 case BLE_UUID_TYPE_16:
96 dst->u16 = *(const ble_uuid16_t *)src;
97 break;
98 case BLE_UUID_TYPE_32:
99 dst->u32 = *(const ble_uuid32_t *)src;
100 break;
101 case BLE_UUID_TYPE_128:
102 dst->u128 = *(const ble_uuid128_t *)src;
103 break;
104 default:
105 BLE_HS_DBG_ASSERT(0);
106 break;
107 }
108 }
109
110 char *
ble_uuid_to_str(const ble_uuid_t * uuid,char * dst)111 ble_uuid_to_str(const ble_uuid_t *uuid, char *dst)
112 {
113 const uint8_t *u8p;
114
115 switch (uuid->type) {
116 case BLE_UUID_TYPE_16:
117 sprintf(dst, "0x%04" PRIx16, BLE_UUID16(uuid)->value);
118 break;
119 case BLE_UUID_TYPE_32:
120 sprintf(dst, "0x%08" PRIx32, BLE_UUID32(uuid)->value);
121 break;
122 case BLE_UUID_TYPE_128:
123 u8p = BLE_UUID128(uuid)->value;
124
125 sprintf(dst, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
126 "%02x%02x%02x%02x%02x%02x",
127 u8p[15], u8p[14], u8p[13], u8p[12],
128 u8p[11], u8p[10], u8p[9], u8p[8],
129 u8p[7], u8p[6], u8p[5], u8p[4],
130 u8p[3], u8p[2], u8p[1], u8p[0]);
131 break;
132 default:
133 dst[0] = '\0';
134 break;
135 }
136
137 return dst;
138 }
139
140 uint16_t
ble_uuid_u16(const ble_uuid_t * uuid)141 ble_uuid_u16(const ble_uuid_t *uuid)
142 {
143 VERIFY_UUID(uuid);
144
145 return uuid->type == BLE_UUID_TYPE_16 ? BLE_UUID16(uuid)->value : 0;
146 }
147
148 /* APIs below are private (ble_uuid_priv.h) */
149
150 int
ble_uuid_init_from_att_mbuf(ble_uuid_any_t * uuid,struct os_mbuf * om,int off,int len)151 ble_uuid_init_from_att_mbuf(ble_uuid_any_t *uuid, struct os_mbuf *om, int off,
152 int len)
153 {
154 uint8_t val[16];
155 int rc;
156
157 rc = os_mbuf_copydata(om, off, len, val);
158 if (rc != 0) {
159 return rc;
160 }
161
162 rc = ble_uuid_init_from_att_buf(uuid, val, len);
163
164 return rc;
165 }
166
167 int
ble_uuid_init_from_att_buf(ble_uuid_any_t * uuid,const void * buf,size_t len)168 ble_uuid_init_from_att_buf(ble_uuid_any_t *uuid, const void *buf, size_t len)
169 {
170 int rc = 0;
171
172 if (len == 2) {
173 uuid->u.type = BLE_UUID_TYPE_16;
174 uuid->u16.value = get_le16(buf);
175 } else if (len == 16) {
176 uuid->u.type = BLE_UUID_TYPE_128;
177 memcpy(uuid->u128.value, buf, 16);
178 } else {
179 rc = BLE_HS_EINVAL;
180 }
181
182 return rc;
183 }
184
185 int
ble_uuid_to_any(const ble_uuid_t * uuid,ble_uuid_any_t * uuid_any)186 ble_uuid_to_any(const ble_uuid_t *uuid, ble_uuid_any_t *uuid_any)
187 {
188 VERIFY_UUID(uuid);
189
190 uuid_any->u.type = uuid->type;
191
192 switch (uuid->type) {
193 case BLE_UUID_TYPE_16:
194 uuid_any->u16.value = BLE_UUID16(uuid)->value;
195 break;
196
197 case BLE_UUID_TYPE_32:
198 uuid_any->u32.value = BLE_UUID32(uuid)->value;
199 break;
200
201 case BLE_UUID_TYPE_128:
202 memcpy(uuid_any->u128.value, BLE_UUID128(uuid)->value, 16);
203 break;
204 default:
205 return BLE_HS_EINVAL;
206 }
207
208 return 0;
209 }
210
211 int
ble_uuid_to_mbuf(const ble_uuid_t * uuid,struct os_mbuf * om)212 ble_uuid_to_mbuf(const ble_uuid_t *uuid, struct os_mbuf *om)
213 {
214 int len;
215 void *buf;
216
217 VERIFY_UUID(uuid);
218
219 len = ble_uuid_length(uuid);
220
221 buf = os_mbuf_extend(om, len);
222 if (buf == NULL) {
223 return BLE_HS_ENOMEM;
224 }
225
226 ble_uuid_flat(uuid, buf);
227
228 return 0;
229 }
230
231 int
ble_uuid_flat(const ble_uuid_t * uuid,void * dst)232 ble_uuid_flat(const ble_uuid_t *uuid, void *dst)
233 {
234 VERIFY_UUID(uuid);
235
236 switch (uuid->type) {
237 case BLE_UUID_TYPE_16:
238 put_le16(dst, BLE_UUID16(uuid)->value);
239 break;
240 case BLE_UUID_TYPE_32:
241 memcpy(dst, ble_uuid_base, 16);
242 put_le32(dst + 12, BLE_UUID32(uuid)->value);
243 break;
244 case BLE_UUID_TYPE_128:
245 memcpy(dst, BLE_UUID128(uuid)->value, 16);
246 break;
247 default:
248 return BLE_HS_EINVAL;
249 }
250
251 return 0;
252 }
253
254 int
ble_uuid_length(const ble_uuid_t * uuid)255 ble_uuid_length(const ble_uuid_t *uuid)
256 {
257 VERIFY_UUID(uuid);
258
259 return uuid->type >> 3;
260 }
261