• 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 <string.h>
21 #include "securec.h"
22 #include "ble_hs_priv.h"
23 #include "host/ble_store.h"
24 
ble_store_read(int obj_type,const union ble_store_key * key,union ble_store_value * val)25 int ble_store_read(int obj_type, const union ble_store_key *key, union ble_store_value *val)
26 {
27     int rc;
28     ble_hs_lock();
29 
30     if (ble_hs_cfg.store_read_cb == NULL) {
31         rc = BLE_HS_ENOTSUP;
32     } else {
33         rc = ble_hs_cfg.store_read_cb(obj_type, key, val);
34     }
35 
36     ble_hs_unlock();
37     return rc;
38 }
39 
ble_store_write(int obj_type,const union ble_store_value * val)40 int ble_store_write(int obj_type, const union ble_store_value *val)
41 {
42     if (ble_hs_cfg.store_write_cb == NULL) {
43         return BLE_HS_ENOTSUP;
44     }
45 
46     while (1) {
47         ble_hs_lock();
48         int rc = ble_hs_cfg.store_write_cb(obj_type, val);
49         ble_hs_unlock();
50 
51         switch (rc) {
52             case 0:
53                 return 0;
54 
55             case BLE_HS_ESTORE_CAP:
56                 /* Record didn't fit.  Give the application the opportunity to free
57                  * up some space.
58                  */
59                 rc = ble_store_overflow_event(obj_type, val);
60                 if (rc != 0) {
61                     return rc;
62                 }
63 
64                 /* Application made room for the record; try again. */
65                 break;
66 
67             default:
68                 return rc;
69         }
70     }
71 }
72 
ble_store_delete(int obj_type,const union ble_store_key * key)73 int ble_store_delete(int obj_type, const union ble_store_key *key)
74 {
75     int rc;
76     ble_hs_lock();
77 
78     if (ble_hs_cfg.store_delete_cb == NULL) {
79         rc = BLE_HS_ENOTSUP;
80     } else {
81         rc = ble_hs_cfg.store_delete_cb(obj_type, key);
82     }
83 
84     ble_hs_unlock();
85     return rc;
86 }
87 
ble_store_flush(void)88 int ble_store_flush(void)
89 {
90     int rc;
91     ble_hs_lock();
92     if (ble_hs_cfg.store_flush_cb == NULL) {
93         rc = BLE_HS_ENOTSUP;
94     } else {
95         rc = ble_hs_cfg.store_flush_cb();
96     }
97 
98     ble_hs_unlock();
99     return rc;
100 }
101 
ble_store_status(struct ble_store_status_event * event)102 static int ble_store_status(struct ble_store_status_event *event)
103 {
104     int rc;
105     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
106 
107     if (ble_hs_cfg.store_status_cb == NULL) {
108         rc = BLE_HS_ENOTSUP;
109     } else {
110         rc = ble_hs_cfg.store_status_cb(event, ble_hs_cfg.store_status_arg);
111     }
112 
113     return rc;
114 }
115 
ble_store_overflow_event(int obj_type,const union ble_store_value * value)116 int ble_store_overflow_event(int obj_type, const union ble_store_value *value)
117 {
118     struct ble_store_status_event event;
119     event.event_code = BLE_STORE_EVENT_OVERFLOW;
120     event.overflow.obj_type = obj_type;
121     event.overflow.value = value;
122     return ble_store_status(&event);
123 }
124 
ble_store_full_event(int obj_type,uint16_t conn_handle)125 int ble_store_full_event(int obj_type, uint16_t conn_handle)
126 {
127     struct ble_store_status_event event;
128     event.event_code = BLE_STORE_EVENT_FULL;
129     event.full.obj_type = obj_type;
130     event.full.conn_handle = conn_handle;
131     return ble_store_status(&event);
132 }
133 
ble_store_read_our_sec(const struct ble_store_key_sec * key_sec,struct ble_store_value_sec * value_sec)134 int ble_store_read_our_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec)
135 {
136     const union ble_store_key *store_key;
137     union ble_store_value *store_value;
138     int rc;
139     BLE_HS_DBG_ASSERT(key_sec->peer_addr.type == BLE_ADDR_PUBLIC ||
140                       key_sec->peer_addr.type == BLE_ADDR_RANDOM ||
141                       ble_addr_cmp(&key_sec->peer_addr, BLE_ADDR_ANY) == 0);
142     store_key = (void *)key_sec;
143     store_value = (void *)value_sec;
144     rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_SEC, store_key, store_value);
145     return rc;
146 }
147 
ble_store_persist_sec(int obj_type,const struct ble_store_value_sec * value_sec)148 static int ble_store_persist_sec(int obj_type, const struct ble_store_value_sec *value_sec)
149 {
150     union ble_store_value *store_value;
151     int rc;
152     BLE_HS_DBG_ASSERT(value_sec->peer_addr.type == BLE_ADDR_PUBLIC ||
153                       value_sec->peer_addr.type == BLE_ADDR_RANDOM);
154     BLE_HS_DBG_ASSERT(value_sec->ltk_present ||
155                       value_sec->irk_present ||
156                       value_sec->csrk_present);
157     store_value = (void *)value_sec;
158     rc = ble_store_write(obj_type, store_value);
159     return rc;
160 }
161 
ble_store_write_our_sec(const struct ble_store_value_sec * value_sec)162 int ble_store_write_our_sec(const struct ble_store_value_sec *value_sec)
163 {
164     int rc;
165     rc = ble_store_persist_sec(BLE_STORE_OBJ_TYPE_OUR_SEC, value_sec);
166     return rc;
167 }
168 
ble_store_delete_our_sec(const struct ble_store_key_sec * key_sec)169 int ble_store_delete_our_sec(const struct ble_store_key_sec *key_sec)
170 {
171     union ble_store_key *store_key;
172     int rc;
173     store_key = (void *)key_sec;
174     rc = ble_store_delete(BLE_STORE_OBJ_TYPE_OUR_SEC, store_key);
175     return rc;
176 }
177 
ble_store_delete_peer_sec(const struct ble_store_key_sec * key_sec)178 int ble_store_delete_peer_sec(const struct ble_store_key_sec *key_sec)
179 {
180     union ble_store_key *store_key;
181     int rc;
182     store_key = (void *)key_sec;
183     rc = ble_store_delete(BLE_STORE_OBJ_TYPE_PEER_SEC, store_key);
184     return rc;
185 }
186 
ble_store_read_peer_sec(const struct ble_store_key_sec * key_sec,struct ble_store_value_sec * value_sec)187 int ble_store_read_peer_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec)
188 {
189     union ble_store_value *store_value;
190     union ble_store_key *store_key;
191     int rc;
192     BLE_HS_DBG_ASSERT(key_sec->peer_addr.type == BLE_ADDR_PUBLIC ||
193                       key_sec->peer_addr.type == BLE_ADDR_RANDOM);
194     store_key = (void *)key_sec;
195     store_value = (void *)value_sec;
196     rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_SEC, store_key, store_value);
197     if (rc != 0) {
198         return rc;
199     }
200 
201     return 0;
202 }
203 
ble_store_write_peer_sec(const struct ble_store_value_sec * value_sec)204 int ble_store_write_peer_sec(const struct ble_store_value_sec *value_sec)
205 {
206     int rc;
207     rc = ble_store_persist_sec(BLE_STORE_OBJ_TYPE_PEER_SEC, value_sec);
208     if (rc != 0) {
209         return rc;
210     }
211 
212     if (ble_addr_cmp(&value_sec->peer_addr, BLE_ADDR_ANY) &&
213             value_sec->irk_present) {
214         /* Write the peer IRK to the controller keycache
215          * There is not much to do here if it fails */
216         rc = ble_hs_pvcy_add_entry(value_sec->peer_addr.val,
217                                    value_sec->peer_addr.type,
218                                    value_sec->irk);
219         if (rc != 0) {
220             return rc;
221         }
222     }
223 
224     return 0;
225 }
226 
ble_store_read_cccd(const struct ble_store_key_cccd * key,struct ble_store_value_cccd * out_value)227 int ble_store_read_cccd(const struct ble_store_key_cccd *key, struct ble_store_value_cccd *out_value)
228 {
229     union ble_store_value *store_value;
230     union ble_store_key *store_key;
231     int rc;
232     store_key = (void *)key;
233     store_value = (void *)out_value;
234     rc = ble_store_read(BLE_STORE_OBJ_TYPE_CCCD, store_key, store_value);
235     return rc;
236 }
237 
ble_store_write_cccd(const struct ble_store_value_cccd * value)238 int ble_store_write_cccd(const struct ble_store_value_cccd *value)
239 {
240     union ble_store_value *store_value;
241     int rc;
242     store_value = (void *)value;
243     rc = ble_store_write(BLE_STORE_OBJ_TYPE_CCCD, store_value);
244     return rc;
245 }
246 
ble_store_delete_cccd(const struct ble_store_key_cccd * key)247 int ble_store_delete_cccd(const struct ble_store_key_cccd *key)
248 {
249     union ble_store_key *store_key;
250     int rc;
251     store_key = (void *)key;
252     rc = ble_store_delete(BLE_STORE_OBJ_TYPE_CCCD, store_key);
253     return rc;
254 }
255 
ble_store_key_from_value_cccd(struct ble_store_key_cccd * out_key,const struct ble_store_value_cccd * value)256 void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key, const struct ble_store_value_cccd *value)
257 {
258     out_key->peer_addr = value->peer_addr;
259     out_key->chr_val_handle = value->chr_val_handle;
260     out_key->idx = 0;
261 }
262 
ble_store_key_from_value_sec(struct ble_store_key_sec * out_key,const struct ble_store_value_sec * value)263 void ble_store_key_from_value_sec(struct ble_store_key_sec *out_key, const struct ble_store_value_sec *value)
264 {
265     out_key->peer_addr = value->peer_addr;
266     out_key->ediv = value->ediv;
267     out_key->rand_num = value->rand_num;
268     out_key->ediv_rand_present = 1;
269     out_key->idx = 0;
270 }
271 
ble_store_key_from_value(int obj_type,union ble_store_key * out_key,const union ble_store_value * value)272 void ble_store_key_from_value(int obj_type,
273                               union ble_store_key *out_key,
274                               const union ble_store_value *value)
275 {
276     switch (obj_type) {
277         case BLE_STORE_OBJ_TYPE_OUR_SEC:
278         case BLE_STORE_OBJ_TYPE_PEER_SEC:
279             ble_store_key_from_value_sec(&out_key->sec, &value->sec);
280             break;
281 
282         case BLE_STORE_OBJ_TYPE_CCCD:
283             ble_store_key_from_value_cccd(&out_key->cccd, &value->cccd);
284             break;
285 
286         default:
287             BLE_HS_DBG_ASSERT(0);
288             break;
289     }
290 }
291 
ble_store_iterate(int obj_type,ble_store_iterator_fn * callback,void * cookie)292 int ble_store_iterate(int obj_type,
293                       ble_store_iterator_fn *callback,
294                       void *cookie)
295 {
296     union ble_store_key key;
297     union ble_store_value value;
298     int idx = 0;
299     uint8_t *pidx;
300     /* a magic value to retrieve anything */
301     memset_s(&key, sizeof(key), 0, sizeof(key));
302 
303     switch (obj_type) {
304         case BLE_STORE_OBJ_TYPE_PEER_SEC:
305         case BLE_STORE_OBJ_TYPE_OUR_SEC:
306             key.sec.peer_addr = *BLE_ADDR_ANY;
307             pidx = &key.sec.idx;
308             break;
309 
310         case BLE_STORE_OBJ_TYPE_CCCD:
311             key.cccd.peer_addr = *BLE_ADDR_ANY;
312             pidx = &key.cccd.idx;
313             break;
314 
315         default:
316             BLE_HS_DBG_ASSERT(0);
317             return BLE_HS_EINVAL;
318     }
319 
320     while (1) {
321         *pidx = idx;
322         int rc = ble_store_read(obj_type, &key, &value);
323         switch (rc) {
324             case 0:
325                 if (callback != NULL) {
326                     rc = callback(obj_type, &value, cookie);
327                     if (rc != 0) {
328                         /* User function indicates to stop iterating. */
329                         return 0;
330                     }
331                 }
332 
333                 break;
334 
335             case BLE_HS_ENOENT:
336                 /* No more entries. */
337                 return 0;
338 
339             default:
340                 /* Read error. */
341                 return rc;
342         }
343 
344         idx++;
345     }
346 }
347 
348 /**
349  * Deletes all objects from the BLE host store.
350  *
351  * @return                      0 on success; nonzero on failure.
352  */
ble_store_clear(void)353 int ble_store_clear(void)
354 {
355     const uint8_t obj_types[] = {
356         BLE_STORE_OBJ_TYPE_OUR_SEC,
357         BLE_STORE_OBJ_TYPE_PEER_SEC,
358         BLE_STORE_OBJ_TYPE_CCCD,
359     };
360     union ble_store_key key;
361     int rc;
362     int i;
363     /* A zeroed key will always retrieve the first value. */
364     memset_s(&key, sizeof(key), 0, sizeof key);
365 
366     for (i = 0; i < sizeof obj_types / sizeof obj_types[0]; i++) {
367         int obj_type = obj_types[i];
368 
369         do {
370             rc = ble_store_delete(obj_type, &key);
371         } while (rc == 0);
372 
373         /* BLE_HS_ENOENT means we deleted everything. */
374         if (rc != BLE_HS_ENOENT) {
375             return rc;
376         }
377     }
378     return 0;
379 }