xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/src/ble_uuid.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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