• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdint.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include "securec.h"
26 #include "os/os_mbuf.h"
27 #include "nimble/ble.h"
28 #include "ble_hs_priv.h"
29 #include "host/ble_uuid.h"
30 
31 static uint8_t ble_uuid_base[16] = {
32     0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
33     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
34 };
35 
36 #if MYNEWT_VAL(BLE_HS_DEBUG)
37 #define VERIFY_UUID(uuid)                       \
38     assert((uuid->type == BLE_UUID_TYPE_16) ||  \
39            (uuid->type == BLE_UUID_TYPE_32) ||  \
40            (uuid->type == BLE_UUID_TYPE_128))
41 #else
42 #define VERIFY_UUID(uuid)
43 #endif
44 
ble_uuid_init_from_buf(ble_uuid_any_t * uuid,const void * buf,size_t len)45 int ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len)
46 {
47     switch (len) {
48         case 2: // 2:case value
49             uuid->u.type = BLE_UUID_TYPE_16;
50             uuid->u16.value = get_le16(buf);
51             return 0;
52 
53         case 4: // 4:case value
54             uuid->u.type = BLE_UUID_TYPE_32;
55             uuid->u32.value = get_le32(buf);
56             return 0;
57 
58         case 16: // 16:case value
59             uuid->u.type = BLE_UUID_TYPE_128;
60             memcpy_s(uuid->u128.value, sizeof(uuid->u128.value), buf, 16); // 16:size
61             return 0;
62         default:
63             break;
64     }
65 
66     return BLE_HS_EINVAL;
67 }
68 
ble_uuid_cmp(const ble_uuid_t * uuid1,const ble_uuid_t * uuid2)69 int ble_uuid_cmp(const ble_uuid_t *uuid1, const ble_uuid_t *uuid2)
70 {
71     VERIFY_UUID(uuid1);
72     VERIFY_UUID(uuid2);
73 
74     if (uuid1->type != uuid2->type) {
75         return uuid1->type - uuid2->type;
76     }
77 
78     switch (uuid1->type) {
79         case BLE_UUID_TYPE_16:
80             return (int) BLE_UUID16(uuid1)->value - (int) BLE_UUID16(uuid2)->value;
81 
82         case BLE_UUID_TYPE_32:
83             return (int) BLE_UUID32(uuid1)->value - (int) BLE_UUID32(uuid2)->value;
84 
85         case BLE_UUID_TYPE_128:
86             return memcmp(BLE_UUID128(uuid1)->value, BLE_UUID128(uuid2)->value, 16); // 16:size
87 
88         default:
89             break;
90     }
91 
92     BLE_HS_DBG_ASSERT(0);
93     return -1;
94 }
95 
ble_uuid_copy(ble_uuid_any_t * dst,const ble_uuid_t * src)96 void ble_uuid_copy(ble_uuid_any_t *dst, const ble_uuid_t *src)
97 {
98     VERIFY_UUID(src);
99 
100     switch (src->type) {
101         case BLE_UUID_TYPE_16:
102             dst->u16 = *(const ble_uuid16_t *)src;
103             break;
104 
105         case BLE_UUID_TYPE_32:
106             dst->u32 = *(const ble_uuid32_t *)src;
107             break;
108 
109         case BLE_UUID_TYPE_128:
110             dst->u128 = *(const ble_uuid128_t *)src;
111             break;
112 
113         default:
114             BLE_HS_DBG_ASSERT(0);
115             break;
116     }
117 }
118 
ble_uuid_to_str(const ble_uuid_t * uuid,char * dst)119 char *ble_uuid_to_str(const ble_uuid_t *uuid, char *dst)
120 {
121     const uint8_t *u8p;
122 
123     switch (uuid->type) {
124         case BLE_UUID_TYPE_16:
125             sprintf_s(dst, sizeof(*dst), "0x%04x", BLE_UUID16(uuid)->value);
126             break;
127 
128         case BLE_UUID_TYPE_32:
129             sprintf_s(dst, sizeof(*dst), "0x%08x", BLE_UUID32(uuid)->value);
130             break;
131 
132         case BLE_UUID_TYPE_128:
133             u8p = BLE_UUID128(uuid)->value;
134             sprintf_s(dst, sizeof(*dst), "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
135                     "%02x%02x%02x%02x%02x%02x",
136                     u8p[15], u8p[14], // 15:array element, 14:array element
137                     u8p[13], u8p[12], // 13:array element, 12:array element
138                     u8p[11], u8p[10], // 11:array element, 10:array element
139                     u8p[9],  u8p[8], // 9:array element, 9:array element
140                     u8p[7],  u8p[6], // 7:array element, 6:array element
141                     u8p[5],  u8p[4], // 5:array element, 4:array element
142                     u8p[3],  u8p[2], // 3:array element, 2:array element
143                     u8p[1],  u8p[0]);
144             break;
145 
146         default:
147             dst[0] = '\0';
148             break;
149     }
150 
151     return dst;
152 }
153 
ble_uuid_u16(const ble_uuid_t * uuid)154 uint16_t ble_uuid_u16(const ble_uuid_t *uuid)
155 {
156     VERIFY_UUID(uuid);
157     return uuid->type == BLE_UUID_TYPE_16 ? BLE_UUID16(uuid)->value : 0;
158 }
159 
160 /* APIs below are private (ble_uuid_priv.h) */
161 
ble_uuid_init_from_att_mbuf(ble_uuid_any_t * uuid,struct os_mbuf * om,int off,int len)162 int ble_uuid_init_from_att_mbuf(ble_uuid_any_t *uuid, struct os_mbuf *om, int off, int len)
163 {
164     uint8_t val[16];
165     int rc;
166     rc = os_mbuf_copydata(om, off, len, val);
167     if (rc != 0) {
168         return rc;
169     }
170 
171     rc = ble_uuid_init_from_att_buf(uuid, val, len);
172     return rc;
173 }
174 
ble_uuid_init_from_att_buf(ble_uuid_any_t * uuid,const void * buf,size_t len)175 int ble_uuid_init_from_att_buf(ble_uuid_any_t *uuid, const void *buf, size_t len)
176 {
177     int rc = 0;
178 
179     if (len == 2) { // 2:Analyzing conditions
180         uuid->u.type = BLE_UUID_TYPE_16;
181         uuid->u16.value = get_le16(buf);
182     } else if (len == 16) { // 16:Analyzing conditions
183         uuid->u.type = BLE_UUID_TYPE_128;
184         memcpy_s(uuid->u128.value, sizeof(uuid->u128.value), buf, 16); // 16:size
185     } else {
186         rc = BLE_HS_EINVAL;
187     }
188 
189     return rc;
190 }
191 
ble_uuid_to_any(const ble_uuid_t * uuid,ble_uuid_any_t * uuid_any)192 int ble_uuid_to_any(const ble_uuid_t *uuid, ble_uuid_any_t *uuid_any)
193 {
194     VERIFY_UUID(uuid);
195     uuid_any->u.type = uuid->type;
196 
197     switch (uuid->type) {
198         case BLE_UUID_TYPE_16:
199             uuid_any->u16.value = BLE_UUID16(uuid)->value;
200             break;
201 
202         case BLE_UUID_TYPE_32:
203             uuid_any->u32.value = BLE_UUID32(uuid)->value;
204             break;
205 
206         case BLE_UUID_TYPE_128:
207             memcpy_s(uuid_any->u128.value, sizeof(uuid_any->u128.value), BLE_UUID128(uuid)->value, 16); // 16:size
208             break;
209 
210         default:
211             break;
212     }
213 
214     return 0;
215 }
216 
ble_uuid_to_mbuf(const ble_uuid_t * uuid,struct os_mbuf * om)217 int ble_uuid_to_mbuf(const ble_uuid_t *uuid, struct os_mbuf *om)
218 {
219     int len;
220     void *buf;
221     VERIFY_UUID(uuid);
222     len = ble_uuid_length(uuid);
223     buf = os_mbuf_extend(om, len);
224     if (buf == NULL) {
225         return BLE_HS_ENOMEM;
226     }
227 
228     ble_uuid_flat(uuid, buf);
229     return 0;
230 }
231 
ble_uuid_flat(const ble_uuid_t * uuid,void * dst)232 int 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 
241         case BLE_UUID_TYPE_32:
242             memcpy_s(dst, sizeof(*dst), ble_uuid_base, 16); // 16:size
243             put_le32((uint8_t *)dst + 12, BLE_UUID32(uuid)->value); // 12:byte alignment
244             break;
245 
246         case BLE_UUID_TYPE_128:
247             memcpy_s(dst, sizeof(*dst), BLE_UUID128(uuid)->value, 16); // 16:size
248             break;
249 
250         default:
251             return BLE_HS_EINVAL;
252     }
253 
254     return 0;
255 }
256 
ble_uuid_length(const ble_uuid_t * uuid)257 int ble_uuid_length(const ble_uuid_t *uuid)
258 {
259     VERIFY_UUID(uuid);
260     return uuid->type >> 3; // 3:byte alignment
261 }