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