• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements.  See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership.  The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License.  You may obtain a copy of the License at
10 *
11 *  http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied.  See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 */
20 
21 #include "syscfg/syscfg.h"
22 #include "securec.h"
23 #if MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST)
24 
25 #include <string.h>
26 #include "sysinit/sysinit.h"
27 #include "host/ble_hs.h"
28 #include "nimble/nimble_port.h"
29 #include "store/config/ble_store_config.h"
30 #include "ble_store_config_priv.h"
31 #include "store/config/wm_bt_storage.h"
32 
33 #define NIMBLE_NVS_STR_NAME_MAX_LEN              16
34 
35 typedef struct ble_store_value_noaddr_cccd {
36     uint16_t chr_val_handle;
37     uint16_t flags;
38     unsigned value_changed : 1;
39 } ble_store_value_t;
40 
41 typedef struct cccd_nvram {
42     ble_addr_t addr;
43     uint8_t offset;
44     ble_store_value_t value[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)];
45 } cccd_nvram_t;
46 
47 /*****************************************************************************
48  * $ NVS                                                                     *
49  *****************************************************************************/
50 
51 /* Gets the database in RAM filled up with keys stored in NVS. The sequence of
52  * the keys in database may get lost.
53  */
ble_hs_log_flat_buf_tmp(const void * data,int len)54 static void ble_hs_log_flat_buf_tmp(const void *data, int len)
55 {
56     const uint8_t *u8ptr;
57     int i;
58     u8ptr = data;
59 
60     for (i = 0; i < len; i++) {
61         BLE_HS_LOG(ERROR, "0x%02x ", u8ptr[i]);
62     }
63 }
64 
ble_store_nvram_print_value_sec(const struct ble_store_value_sec * sec)65 static void ble_store_nvram_print_value_sec(const struct ble_store_value_sec *sec)
66 {
67     BLE_HS_LOG(ERROR, "addr=");
68     ble_hs_log_flat_buf_tmp(sec->peer_addr.val, 6); // 6:len
69     BLE_HS_LOG(ERROR, " ");
70     BLE_HS_LOG(ERROR, "peer_addr_type=%d ", sec->peer_addr.type);
71 
72     if (sec->ltk_present) {
73         BLE_HS_LOG(ERROR, "ediv=%u rand=%llu authenticated=%d ltk=",
74                    sec->ediv, sec->rand_num, sec->authenticated);
75         ble_hs_log_flat_buf_tmp(sec->ltk, 16); // 16:len
76         BLE_HS_LOG(ERROR, " ");
77     }
78 
79     if (sec->irk_present) {
80         BLE_HS_LOG(ERROR, "irk=");
81         ble_hs_log_flat_buf_tmp(sec->irk, 16); // 16:len
82         BLE_HS_LOG(ERROR, " ");
83     }
84 
85     if (sec->csrk_present) {
86         BLE_HS_LOG(ERROR, "csrk=");
87         ble_hs_log_flat_buf_tmp(sec->csrk, 16); // 16:len
88         BLE_HS_LOG(ERROR, " ");
89     }
90 
91     BLE_HS_LOG(ERROR, "\n");
92 }
ble_store_nvram_print_value_cccd(const struct ble_store_value_cccd * sec)93 static void ble_store_nvram_print_value_cccd(const struct ble_store_value_cccd *sec)
94 {
95     BLE_HS_LOG(ERROR, "addr=");
96     ble_hs_log_flat_buf_tmp(sec->peer_addr.val, 6); // 6:len
97     BLE_HS_LOG(ERROR, " ");
98     BLE_HS_LOG(ERROR, "peer_addr_type=%d ", sec->peer_addr.type);
99     BLE_HS_LOG(ERROR, "chr_val_handle=%d(0x%04x) ", sec->chr_val_handle, sec->chr_val_handle);
100     BLE_HS_LOG(ERROR, "flags=%d(0x%04x) ", sec->flags, sec->flags);
101     BLE_HS_LOG(ERROR, "value_changed=%d(0x%04x) ", sec->value_changed, sec->value_changed);
102     BLE_HS_LOG(ERROR, "\n");
103 }
104 
ble_nvs_restore_sec_keys()105 static int ble_nvs_restore_sec_keys()
106 {
107     int i = 0;
108     int restore_count = 0;
109     uint8_t cccd_info[sizeof(ble_store_value_t)*MYNEWT_VAL(BLE_STORE_MAX_CCCDS)];
110     struct ble_store_value_sec peer_sec;
111     struct ble_store_value_sec our_sec;
112     struct ble_store_value_cccd cccd;
113     ble_addr_t addr;
114     uint32_t nv_tag_valid;
115     uint32_t cccd_count;
116 #define OUR_SEC_VALID_BIT_MASK    (0x01<<0)
117 #define PEER_SEC_VALID_BIT_MASK   (0x01<<1)
118 #define CCCD_VALID_BITS_MASK      (0xFFFFFFFC)
119 
120     for (i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) {
121         nv_tag_valid = btif_config_get_sec_cccd_item(i, &addr, &our_sec, sizeof(our_sec), &peer_sec,
122                        sizeof(peer_sec), &cccd_info[0], sizeof(cccd_info));
123         if (nv_tag_valid) {
124             if (nv_tag_valid & OUR_SEC_VALID_BIT_MASK) {
125                 BLE_HS_LOG(ERROR, "load our  sec; ");
126                 ble_store_nvram_print_value_sec(&our_sec);
127                 ble_store_config_our_secs[ble_store_config_num_our_secs] = our_sec;
128                 ble_store_config_num_our_secs++;
129                 restore_count++;
130             }
131 
132             if (nv_tag_valid & PEER_SEC_VALID_BIT_MASK) {
133                 BLE_HS_LOG(ERROR, "load peer sec; ");
134                 ble_store_nvram_print_value_sec(&peer_sec);
135                 ble_store_config_peer_secs[ble_store_config_num_peer_secs] = peer_sec;
136                 ble_store_config_num_peer_secs++;
137                 restore_count++;
138             }
139 
140             if (nv_tag_valid & CCCD_VALID_BITS_MASK) {
141                 int j = 0;
142                 ble_store_value_t *ptr_value = (ble_store_value_t *)&cccd_info[0];
143                 cccd_count = nv_tag_valid >> 2; // 2:byte alignment
144                 assert(cccd_count <= 6); // 6:byte alignment
145 
146                 for (j = 0; j < cccd_count; j++) {
147                     BLE_HS_LOG(ERROR, "load our cccd; ");
148                     memcpy_s(&cccd.peer_addr, sizeof(cccd.peer_addr), &addr, sizeof(ble_addr_t));
149                     cccd.chr_val_handle = ptr_value->chr_val_handle;
150                     cccd.flags = ptr_value->flags;
151                     cccd.value_changed = ptr_value->value_changed;
152                     ble_store_nvram_print_value_cccd(&cccd);
153                     ble_store_config_cccds[ble_store_config_num_cccds] = cccd;
154                     ble_store_config_num_cccds++;
155                     ptr_value++;
156                 }
157                 restore_count++;
158             }
159         }
160     }
161 
162     return restore_count;
163 }
164 
165 static cccd_nvram_t cccd_nvram_array[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
166 
ble_store_config_persist_cccds(bool flush)167 int ble_store_config_persist_cccds(bool flush)
168 {
169     int i = 0, j = 0, rc = 0;
170     int nv_idx = 0;
171     int prefer_index = 0;
172     uint8_t *ptr_byte = NULL;
173     uint8_t found = 0;
174 
175     for (i = 0; i < ble_store_config_num_cccds; i++) {
176         cccd_nvram_array[i].offset = 0;
177     }
178 
179     /* prepare the nvram information */
180     for (i = 0; i < ble_store_config_num_cccds; i++) {
181         ptr_byte = (uint8_t *)&ble_store_config_cccds[i];
182         ptr_byte += 8; // 8:value offset; dword alignment
183         found = 0;
184 
185         for (j = 0; j < prefer_index; j++) {
186             rc = ble_addr_cmp(&ble_store_config_cccds[i].peer_addr, &cccd_nvram_array[j].addr);
187             if (!rc) {
188                 memcpy_s(&cccd_nvram_array[j].value[cccd_nvram_array[j].offset],
189                     sizeof(cccd_nvram_array[j].value[cccd_nvram_array[j].offset]),
190                     ptr_byte, sizeof(ble_store_value_t));
191                 cccd_nvram_array[j].offset++;
192                 found = 1;
193                 break;
194             }
195         }
196 
197         if (found) { continue; }
198 
199         if (j == prefer_index) {
200             memcpy_s(&cccd_nvram_array[j].addr, sizeof(cccd_nvram_array[j].addr),
201                 &ble_store_config_cccds[i].peer_addr, sizeof(ble_addr_t));
202             memcpy_s(&cccd_nvram_array[j].value[cccd_nvram_array[j].offset],
203                 sizeof(cccd_nvram_array[j].value[cccd_nvram_array[j].offset]),
204                 ptr_byte, sizeof(ble_store_value_t));
205             cccd_nvram_array[j].offset++;
206             prefer_index++;
207         }
208     }
209 
210     BLE_HS_LOG(DEBUG, "prefer_index=%d sizeof(ble_store_value_t)=%d\r\n", prefer_index,
211                sizeof(ble_store_value_t));
212     i = 0;
213 
214     for (i = 0; i < prefer_index; i++) {
215         nv_idx  = btif_config_get_sec_index(&cccd_nvram_array[i].addr, &found);
216         if (nv_idx < 0) {
217             BLE_HS_LOG(DEBUG, "CCCD Full, impossible\r\n");
218             return -1;
219         }
220         if (found) nv_idx = i;
221 
222         ptr_byte = (uint8_t *)&cccd_nvram_array[i].value[0];
223         btif_config_store_cccd(nv_idx, &cccd_nvram_array[i].addr, cccd_nvram_array[i].offset, ptr_byte,
224                                sizeof(ble_store_value_t)*MYNEWT_VAL(BLE_STORE_MAX_CCCDS));
225     }
226 
227     for (; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) {
228         btif_config_delete_cccd(i);
229     }
230 
231     if (flush)ble_store_config_persist_flush();
232     return 0;
233 }
234 
ble_store_config_persist_peer_secs(bool flush)235 int ble_store_config_persist_peer_secs(bool flush)
236 {
237     int i = 0;
238     int nv_idx = 0;
239     uint8_t found = 0;
240 
241     for (i = 0; i < ble_store_config_num_peer_secs; i++) {
242         nv_idx  = btif_config_get_sec_index(&ble_store_config_peer_secs[i].peer_addr, &found);
243         if (nv_idx < 0) {
244             BLE_HS_LOG(ERROR, "PEER SEC Full, impossible[i=%d][%d]\r\n", i, ble_store_config_num_peer_secs);
245             return -1;
246         }
247         if (found) nv_idx = i;
248 
249         btif_config_store_peer_sec(nv_idx, &ble_store_config_peer_secs[i].peer_addr,
250                                    (void *)&ble_store_config_peer_secs[i], sizeof(ble_store_config_peer_secs[i]));
251     }
252 
253     for (; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) {
254         btif_config_delete_peer_sec(i);
255     }
256 
257     if (flush)ble_store_config_persist_flush();
258     return 0;
259 }
260 
ble_store_config_persist_our_secs(bool flush)261 int ble_store_config_persist_our_secs(bool flush)
262 {
263     int i = 0;
264     int nv_idx = 0;
265     uint8_t found = 0;
266 
267     for (i = 0; i < ble_store_config_num_our_secs; i++) {
268         nv_idx  = btif_config_get_sec_index((void *)&ble_store_config_our_secs[i].peer_addr, &found);
269         if (nv_idx < 0) {
270             BLE_HS_LOG(ERROR, "OUR SEC Full, impossible[i=%d][%d]\r\n", i, ble_store_config_num_our_secs);
271             return -1;
272         }
273         if (found) nv_idx = i;
274 
275         btif_config_store_our_sec(nv_idx, &ble_store_config_our_secs[i].peer_addr,
276                                   (void *)&ble_store_config_our_secs[i], sizeof(ble_store_config_our_secs[i]));
277     }
278 
279     for (; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) {
280         btif_config_delete_our_sec(i);
281     }
282 
283     if (flush)ble_store_config_persist_flush();
284     return 0;
285 }
286 
ble_store_config_persist_flush()287 void ble_store_config_persist_flush()
288 {
289     btif_config_flush(1);
290 }
291 
ble_store_config_delete_all()292 int ble_store_config_delete_all()
293 {
294     btif_config_delete_all();
295     return 0;
296 }
297 
ble_store_config_conf_init()298 void ble_store_config_conf_init()
299 {
300     memset_s(cccd_nvram_array, sizeof(cccd_nvram_array), 0, sizeof(cccd_nvram_t)*MYNEWT_VAL(BLE_STORE_MAX_BONDS));
301     ble_nvs_restore_sec_keys();
302     return;
303 }
ble_store_config_conf_deinit()304 void ble_store_config_conf_deinit()
305 {
306 }
307 
308 /***************************************************************************************/
309 #endif /* MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST) */