1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2013 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #ifdef BT_SUPPORT_NVM
19 #include <unistd.h>
20 #endif /* BT_SUPPORT_NVM */
21 #include <string.h>
22 #include <stdio.h>
23 #include "bta/bta_gattc_co.h"
24 #include "bta/bta_gattc_ci.h"
25
26 // #include "btif_util.h"
27 #include "btm_int.h"
28 #include "nvs.h"
29 #include "nvs_flash.h"
30 #include "osi/list.h"
31 #include "esp_err.h"
32 #include "osi/allocator.h"
33
34 #if( defined BLE_INCLUDED ) && (BLE_INCLUDED == TRUE)
35 #if( defined BTA_GATT_INCLUDED ) && (GATTC_INCLUDED == TRUE)
36 // #if( defined GATTC_CACHE_NVS ) && (GATTC_CACHE_NVS == TRUE)
37
38 #define GATT_CACHE_PREFIX "gatt_"
39 #define INVALID_ADDR_NUM 0xff
40 #define MAX_DEVICE_IN_CACHE 50
41 #define MAX_ADDR_LIST_CACHE_BUF 2048
42
43 #ifdef BT_SUPPORT_NVM
44 static FILE *sCacheFD = 0;
getFilename(char * buffer,BD_ADDR bda)45 static void getFilename(char *buffer, BD_ADDR bda)
46 {
47 sprintf(buffer, "%s%02x%02x%02x%02x%02x%02x", GATT_CACHE_PREFIX
48 , bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
49 }
50
cacheClose(void)51 static void cacheClose(void)
52 {
53 if (sCacheFD != 0) {
54 fclose(sCacheFD);
55 sCacheFD = 0;
56 }
57 }
58
cacheOpen(BD_ADDR bda,bool to_save)59 static bool cacheOpen(BD_ADDR bda, bool to_save)
60 {
61 char fname[255] = {0};
62 getFilename(fname, bda);
63
64 cacheClose();
65 sCacheFD = fopen(fname, to_save ? "w" : "r");
66
67 return (sCacheFD != 0);
68 }
69
cacheReset(BD_ADDR bda)70 static void cacheReset(BD_ADDR bda)
71 {
72 char fname[255] = {0};
73 getFilename(fname, bda);
74 unlink(fname);
75 }
76
77 #else
78
79 static const char *cache_key = "gattc_cache_key";
80 static const char *cache_addr = "cache_addr_tab";
81
82 typedef struct {
83 //save the service data in the list according to the address
84 nvs_handle_t cache_fp;
85 BOOLEAN is_open;
86 BD_ADDR addr;
87 hash_key_t hash_key;
88 list_t *assoc_addr;
89 }cache_addr_info_t;
90
91 typedef struct {
92 //save the address list in the cache
93 nvs_handle_t addr_fp;
94 BOOLEAN is_open;
95 UINT8 num_addr;
96 cache_addr_info_t cache_addr[MAX_DEVICE_IN_CACHE];
97 }cache_env_t;
98
99 static cache_env_t *cache_env = NULL;
100
getFilename(char * buffer,hash_key_t hash)101 static void getFilename(char *buffer, hash_key_t hash)
102 {
103 sprintf(buffer, "%s%02x%02x%02x%02x", GATT_CACHE_PREFIX,
104 hash[0], hash[1], hash[2], hash[3]);
105 }
106
cacheClose(BD_ADDR bda)107 static void cacheClose(BD_ADDR bda)
108 {
109 UINT8 index = 0;
110 if ((index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) {
111 if (cache_env->cache_addr[index].is_open) {
112 nvs_close(cache_env->cache_addr[index].cache_fp);
113 cache_env->cache_addr[index].is_open = FALSE;
114 }
115 }
116 }
117
cacheOpen(BD_ADDR bda,bool to_save,UINT8 * index)118 static bool cacheOpen(BD_ADDR bda, bool to_save, UINT8 *index)
119 {
120 UNUSED(to_save);
121 char fname[255] = {0};
122 UINT8 *assoc_addr = NULL;
123 esp_err_t status = ESP_FAIL;
124 hash_key_t hash_key = {0};
125 if (((*index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) ||
126 ((assoc_addr = bta_gattc_co_cache_find_src_addr(bda, index)) != NULL)) {
127 if (cache_env->cache_addr[*index].is_open) {
128 return TRUE;
129 } else {
130 memcpy(hash_key, cache_env->cache_addr[*index].hash_key, sizeof(hash_key_t));
131 getFilename(fname, hash_key);
132 if ((status = nvs_open(fname, NVS_READWRITE, &cache_env->cache_addr[*index].cache_fp)) == ESP_OK) {
133 // Set the open flag to TRUE when success to open the hash file.
134 cache_env->cache_addr[*index].is_open = TRUE;
135 }
136 }
137 }
138
139 return ((status == ESP_OK) ? true : false);
140 }
141
cacheReset(BD_ADDR bda,BOOLEAN update)142 static void cacheReset(BD_ADDR bda, BOOLEAN update)
143 {
144 char fname[255] = {0};
145 getFilename(fname, bda);
146 UINT8 index = 0;
147 //cache_env->cache_addr
148 if ((index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) {
149 //clear the association address pending in the source address.
150 bta_gattc_co_cache_clear_assoc_addr(bda);
151 if (cache_env->cache_addr[index].is_open) {
152 nvs_erase_all(cache_env->cache_addr[index].cache_fp);
153 nvs_close(cache_env->cache_addr[index].cache_fp);
154 cache_env->cache_addr[index].is_open = FALSE;
155 } else {
156 cacheOpen(bda, false, &index);
157 if (index == INVALID_ADDR_NUM) {
158 APPL_TRACE_ERROR("%s INVALID ADDR NUM", __func__);
159 return;
160 }
161 if (cache_env->cache_addr[index].is_open) {
162 nvs_erase_all(cache_env->cache_addr[index].cache_fp);
163 nvs_close(cache_env->cache_addr[index].cache_fp);
164 cache_env->cache_addr[index].is_open = FALSE;
165 } else {
166 APPL_TRACE_ERROR("%s cacheOpen failed", __func__);
167 return;
168 }
169 }
170 if(cache_env->num_addr == 0) {
171 APPL_TRACE_ERROR("%s cache addr list error", __func__);
172 return;
173 }
174
175 UINT8 num = cache_env->num_addr;
176 //delete the server_bda in the addr_info list.
177 for(UINT8 i = index; i < (num - 1); i++) {
178 memcpy(&cache_env->cache_addr[i], &cache_env->cache_addr[i+1], sizeof(cache_addr_info_t));
179 }
180 //clear the last cache when delete a addr
181 memset(&cache_env->cache_addr[num-1], 0, sizeof(cache_addr_info_t));
182 //reduced the number address counter also
183 cache_env->num_addr--;
184
185 //don't need to update addr list to nvs flash
186 if (!update) {
187 return;
188 }
189
190 //update addr list to nvs flash
191 if(cache_env->num_addr > 0) {
192 //update
193 UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
194 if(!p_buf) {
195 APPL_TRACE_ERROR("%s malloc error", __func__);
196 return;
197 }
198 UINT16 length = cache_env->num_addr*(sizeof(BD_ADDR) + sizeof(hash_key_t));
199 for (UINT8 i = 0; i < cache_env->num_addr; i++) {
200 //copy the address to the buffer.
201 memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)), cache_env->cache_addr[i].addr, sizeof(BD_ADDR));
202 //copy the hash key to the buffer.
203 memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)) + sizeof(BD_ADDR),
204 cache_env->cache_addr[i].hash_key, sizeof(hash_key_t));
205 }
206 if (cache_env->is_open) {
207 if (nvs_set_blob(cache_env->addr_fp, cache_key, p_buf, length) != ESP_OK) {
208 APPL_TRACE_WARNING("%s, nvs set blob failed", __func__);
209 }
210 }
211 osi_free(p_buf);
212
213 } else {
214 //erase
215 if (cache_env->is_open) {
216 nvs_erase_all(cache_env->addr_fp);
217 nvs_close(cache_env->addr_fp);
218 cache_env->is_open = FALSE;
219 } else {
220 APPL_TRACE_WARNING("cache_env status is error");
221 }
222 }
223 }
224 }
225
226 #endif /* BT_SUPPORT_NVM */
227 /*****************************************************************************
228 ** Function Declarations
229 *****************************************************************************/
230
231 /*******************************************************************************
232 **
233 ** Function bta_gattc_co_cache_open
234 **
235 ** Description This callout function is executed by GATTC when a GATT server
236 ** cache is ready to be sent.
237 **
238 ** Parameter server_bda: server bd address of this cache belongs to
239 ** evt: call in event to be passed in when cache open is done.
240 ** conn_id: connection ID of this cache operation attach to.
241 ** to_save: open cache to save or to load.
242 **
243 ** Returns void.
244 **
245 *******************************************************************************/
bta_gattc_co_cache_open(BD_ADDR server_bda,BOOLEAN to_save,UINT8 * index)246 tBTA_GATT_STATUS bta_gattc_co_cache_open(BD_ADDR server_bda, BOOLEAN to_save, UINT8 *index)
247 {
248 /* open NV cache and send call in */
249 tBTA_GATT_STATUS status = BTA_GATT_OK;
250 if (!cacheOpen(server_bda, to_save, index)) {
251 status = BTA_GATT_ERROR;
252 }
253
254 APPL_TRACE_DEBUG("%s() - status=%d", __func__, status);
255 return status;
256 }
257
258 /*******************************************************************************
259 **
260 ** Function bta_gattc_co_cache_load
261 **
262 ** Description This callout function is executed by GATT when server cache
263 ** is required to load.
264 **
265 ** Parameter server_bda: server bd address of this cache belongs to
266 ** evt: call in event to be passed in when cache save is done.
267 ** num_attr: number of attribute to be save.
268 ** attr_index: starting attribute index of the save operation.
269 ** conn_id: connection ID of this cache operation attach to.
270 ** Returns
271 **
272 *******************************************************************************/
bta_gattc_co_cache_load(tBTA_GATTC_NV_ATTR * attr,UINT8 index)273 tBTA_GATT_STATUS bta_gattc_co_cache_load(tBTA_GATTC_NV_ATTR *attr, UINT8 index)
274 {
275 #if (!CONFIG_BT_STACK_NO_LOG)
276 UINT16 num_attr = 0;
277 #endif
278 tBTA_GATT_STATUS status = BTA_GATT_ERROR;
279 size_t length = 0;
280 // Read the size of memory space required for blob
281 nvs_get_blob(cache_env->cache_addr[index].cache_fp, cache_key, NULL, &length);
282 // Read previously saved blob if available
283 esp_err_t err_code = nvs_get_blob(cache_env->cache_addr[index].cache_fp, cache_key, attr, &length);
284 #if (!CONFIG_BT_STACK_NO_LOG)
285 num_attr = length / sizeof(tBTA_GATTC_NV_ATTR);
286 #endif
287 status = (err_code == ESP_OK && length != 0) ? BTA_GATT_OK : BTA_GATT_ERROR;
288 APPL_TRACE_DEBUG("%s() - read=%d, status=%d, err_code = %d",
289 __func__, num_attr, status, err_code);
290
291 return status;
292 }
293
bta_gattc_get_cache_attr_length(UINT8 index)294 size_t bta_gattc_get_cache_attr_length(UINT8 index)
295 {
296 size_t length = 0;
297 if (index == INVALID_ADDR_NUM) {
298 return 0;
299 }
300
301 // Read the size of memory space required for blob
302 nvs_get_blob(cache_env->cache_addr[index].cache_fp, cache_key, NULL, &length);
303 return length;
304 }
305
306 /*******************************************************************************
307 **
308 ** Function bta_gattc_co_cache_save
309 **
310 ** Description This callout function is executed by GATT when a server cache
311 ** is available to save.
312 **
313 ** Parameter server_bda: server bd address of this cache belongs to
314 ** evt: call in event to be passed in when cache save is done.
315 ** num_attr: number of attribute to be save.
316 ** p_attr: pointer to the list of attributes to save.
317 ** attr_index: starting attribute index of the save operation.
318 ** conn_id: connection ID of this cache operation attach to.
319 ** Returns
320 **
321 *******************************************************************************/
bta_gattc_co_cache_save(BD_ADDR server_bda,UINT16 num_attr,tBTA_GATTC_NV_ATTR * p_attr_list)322 void bta_gattc_co_cache_save (BD_ADDR server_bda, UINT16 num_attr,
323 tBTA_GATTC_NV_ATTR *p_attr_list)
324 {
325 tBTA_GATT_STATUS status = BTA_GATT_OK;
326 hash_key_t hash_key = {0};
327 UINT8 index = INVALID_ADDR_NUM;
328 //calculate the hash value of the attribute table which should be added to the nvs flash.
329 hash_function_blob((unsigned char *)p_attr_list, sizeof(tBTA_GATTC_NV_ATTR)*num_attr, hash_key);
330 //save the address list to the nvs flash
331 bta_gattc_co_cache_addr_save(server_bda, hash_key);
332
333 if (cacheOpen(server_bda, TRUE, &index)) {
334 esp_err_t err_code = nvs_set_blob(cache_env->cache_addr[index].cache_fp, cache_key,
335 p_attr_list, sizeof(tBTA_GATTC_NV_ATTR)*num_attr);
336 status = (err_code == ESP_OK) ? BTA_GATT_OK : BTA_GATT_ERROR;
337 } else {
338 status = BTA_GATT_ERROR;
339 }
340
341 #if CONFIG_BT_STACK_NO_LOG
342 (void) status;
343 #endif
344 APPL_TRACE_DEBUG("%s() wrote hash_key = %x%x%x%x, num_attr = %d, status = %d.", __func__, hash_key[0], hash_key[1], hash_key[2], hash_key[3], num_attr, status);
345 }
346
347 /*******************************************************************************
348 **
349 ** Function bta_gattc_co_cache_close
350 **
351 ** Description This callout function is executed by GATTC when a GATT server
352 ** cache is written completely.
353 **
354 ** Parameter server_bda: server bd address of this cache belongs to
355 ** conn_id: connection ID of this cache operation attach to.
356 **
357 ** Returns void.
358 **
359 *******************************************************************************/
bta_gattc_co_cache_close(BD_ADDR server_bda,UINT16 conn_id)360 void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id)
361 {
362 UNUSED(conn_id);
363 //#ifdef BT_SUPPORT_NVM
364 cacheClose(server_bda);
365 //#endif /* BT_SUPPORT_NVM */
366 /* close NV when server cache is done saving or loading,
367 does not need to do anything for now on Insight */
368
369 BTIF_TRACE_DEBUG("%s()", __FUNCTION__);
370 }
371
372 /*******************************************************************************
373 **
374 ** Function bta_gattc_co_cache_reset
375 **
376 ** Description This callout function is executed by GATTC to reset cache in
377 ** application
378 **
379 ** Parameter server_bda: server bd address of this cache belongs to
380 **
381 ** Returns void.
382 **
383 *******************************************************************************/
bta_gattc_co_cache_reset(BD_ADDR server_bda)384 void bta_gattc_co_cache_reset(BD_ADDR server_bda)
385 {
386 cacheReset(server_bda, TRUE);
387 }
388
bta_gattc_co_cache_addr_init(void)389 void bta_gattc_co_cache_addr_init(void)
390 {
391 nvs_handle_t fp;
392 esp_err_t err_code;
393 UINT8 num_addr;
394 size_t length = MAX_ADDR_LIST_CACHE_BUF;
395 UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
396 if (p_buf == NULL) {
397 APPL_TRACE_ERROR("%s malloc failed!", __func__);
398 return;
399 }
400
401 cache_env = (cache_env_t *)osi_malloc(sizeof(cache_env_t));
402 if (cache_env == NULL) {
403 APPL_TRACE_ERROR("%s malloc failed!", __func__);
404 osi_free(p_buf);
405 return;
406 }
407
408 memset(cache_env, 0x0, sizeof(cache_env_t));
409
410 if ((err_code = nvs_open(cache_addr, NVS_READWRITE, &fp)) == ESP_OK) {
411 cache_env->addr_fp = fp;
412 cache_env->is_open = TRUE;
413 // Read previously saved blob if available
414 if ((err_code = nvs_get_blob(fp, cache_key, p_buf, &length)) != ESP_OK) {
415 if(err_code != ESP_ERR_NVS_NOT_FOUND) {
416 APPL_TRACE_ERROR("%s, Line = %d, nvs flash get blob data fail, err_code = 0x%x", __func__, __LINE__, err_code);
417 }
418 osi_free(p_buf);
419 return;
420 }
421 num_addr = length / (sizeof(BD_ADDR) + sizeof(hash_key_t));
422 cache_env->num_addr = num_addr;
423 //read the address from nvs flash to cache address list.
424 for (UINT8 i = 0; i < num_addr; i++) {
425 memcpy(cache_env->cache_addr[i].addr, p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)), sizeof(BD_ADDR));
426 memcpy(cache_env->cache_addr[i].hash_key,
427 p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)) + sizeof(BD_ADDR), sizeof(hash_key_t));
428
429 APPL_TRACE_DEBUG("cache_addr[%x] = %x:%x:%x:%x:%x:%x", i, cache_env->cache_addr[i].addr[0], cache_env->cache_addr[i].addr[1], cache_env->cache_addr[i].addr[2],
430 cache_env->cache_addr[i].addr[3], cache_env->cache_addr[i].addr[4], cache_env->cache_addr[i].addr[5]);
431 APPL_TRACE_DEBUG("hash_key[%x] = %x%x%x%x", i, cache_env->cache_addr[i].hash_key[0], cache_env->cache_addr[i].hash_key[1],
432 cache_env->cache_addr[i].hash_key[2], cache_env->cache_addr[i].hash_key[3]);
433 bta_gattc_co_cache_new_assoc_list(cache_env->cache_addr[i].addr, i);
434 }
435 } else {
436 APPL_TRACE_ERROR("%s, Line = %d, nvs flash open fail, err_code = %x", __func__, __LINE__, err_code);
437 osi_free(p_buf);
438 return;
439 }
440
441 osi_free(p_buf);
442 return;
443 }
444
bta_gattc_co_cache_addr_deinit(void)445 void bta_gattc_co_cache_addr_deinit(void)
446 {
447 if(!cache_env->is_open) {
448 return;
449 }
450 nvs_close(cache_env->addr_fp);
451 cache_env->is_open = false;
452
453 for(UINT8 i = 0; i< cache_env->num_addr; i++) {
454 cache_addr_info_t *addr_info = &cache_env->cache_addr[i];
455 if(addr_info) {
456 nvs_close(addr_info->cache_fp);
457 addr_info->is_open = false;
458 if(addr_info->assoc_addr) {
459 list_free(addr_info->assoc_addr);
460 }
461 }
462 }
463
464 osi_free(cache_env);
465 cache_env = NULL;
466 }
467
bta_gattc_co_addr_in_cache(BD_ADDR bda)468 BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda)
469 {
470 UINT8 addr_index = 0;
471 UINT8 num = cache_env->num_addr;
472 cache_addr_info_t *addr_info = &cache_env->cache_addr[0];
473 for (addr_index = 0; addr_index < num; addr_index++) {
474 if (!memcmp(addr_info->addr, bda, sizeof(BD_ADDR))) {
475 return TRUE;
476 }
477 }
478
479 return FALSE;
480 }
481
bta_gattc_co_find_addr_in_cache(BD_ADDR bda)482 UINT8 bta_gattc_co_find_addr_in_cache(BD_ADDR bda)
483 {
484 UINT8 addr_index = 0;
485 UINT8 num = cache_env->num_addr;
486 cache_addr_info_t *addr_info = &cache_env->cache_addr[0];
487
488 for (addr_index = 0; addr_index < num; addr_index++, addr_info++) {
489 if (!memcmp(addr_info->addr, bda, sizeof(BD_ADDR))) {
490 return addr_index;
491 }
492 }
493
494 return INVALID_ADDR_NUM;
495 }
496
bta_gattc_co_find_hash_in_cache(hash_key_t hash_key)497 UINT8 bta_gattc_co_find_hash_in_cache(hash_key_t hash_key)
498 {
499 UINT8 index = 0;
500 UINT8 num = cache_env->num_addr;
501 cache_addr_info_t *addr_info = &cache_env->cache_addr[0];
502 for (index = 0; index < num; index++) {
503 if (!memcmp(addr_info->hash_key, hash_key, sizeof(hash_key_t))) {
504 return index;
505 }
506 }
507
508 return INVALID_ADDR_NUM;
509 }
510
bta_gattc_co_get_addr_num(void)511 UINT8 bta_gattc_co_get_addr_num(void)
512 {
513 if (cache_env == NULL) {
514 return 0;
515 }
516
517 return cache_env->num_addr;
518 }
519
bta_gattc_co_get_addr_list(BD_ADDR * addr_list)520 void bta_gattc_co_get_addr_list(BD_ADDR *addr_list)
521 {
522 UINT8 num = cache_env->num_addr;
523 for (UINT8 i = 0; i < num; i++) {
524 memcpy(addr_list[i], cache_env->cache_addr[i].addr, sizeof(BD_ADDR));
525 }
526 }
527
bta_gattc_co_cache_addr_save(BD_ADDR bd_addr,hash_key_t hash_key)528 void bta_gattc_co_cache_addr_save(BD_ADDR bd_addr, hash_key_t hash_key)
529 {
530 esp_err_t err_code;
531 UINT8 index = 0;
532 UINT8 new_index = cache_env->num_addr;
533 UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
534 if (p_buf == NULL) {
535 APPL_TRACE_ERROR("%s malloc failed!", __func__);
536 return;
537 }
538
539 // check the address list has the same address or not
540 // for the same address, it's hash key may be change due to service change
541 if ((index = bta_gattc_co_find_addr_in_cache(bd_addr)) != INVALID_ADDR_NUM) {
542 APPL_TRACE_DEBUG("%s the bd_addr already in the cache list, index = %x", __func__, index);
543 //if the bd_addr already in the address list, update the hash key in it.
544 memcpy(cache_env->cache_addr[index].addr, bd_addr, sizeof(BD_ADDR));
545 memcpy(cache_env->cache_addr[index].hash_key, hash_key, sizeof(hash_key_t));
546 } else {
547 if (cache_env->num_addr >= MAX_DEVICE_IN_CACHE) {
548 APPL_TRACE_WARNING("%s cache list full and remove the oldest addr info", __func__);
549 cacheReset(cache_env->cache_addr[0].addr, FALSE);
550 }
551 new_index = cache_env->num_addr;
552 assert(new_index < MAX_DEVICE_IN_CACHE);
553 memcpy(cache_env->cache_addr[new_index].addr, bd_addr, sizeof(BD_ADDR));
554 memcpy(cache_env->cache_addr[new_index].hash_key, hash_key, sizeof(hash_key_t));
555 cache_env->num_addr++;
556 APPL_TRACE_DEBUG("%s(), num = %d", __func__, cache_env->num_addr);
557 }
558
559 nvs_handle_t *fp = &cache_env->addr_fp;
560 UINT16 length = cache_env->num_addr * (sizeof(BD_ADDR) + sizeof(hash_key_t));
561
562 for (UINT8 i = 0; i < cache_env->num_addr; i++) {
563 //copy the address to the buffer.
564 memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)), cache_env->cache_addr[i].addr, sizeof(BD_ADDR));
565 //copy the hash key to the buffer.
566 memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)) + sizeof(BD_ADDR),
567 cache_env->cache_addr[i].hash_key, sizeof(hash_key_t));
568 }
569
570 if (cache_env->is_open) {
571 if ((err_code = nvs_set_blob(cache_env->addr_fp, cache_key, p_buf, length)) != ESP_OK) {
572 APPL_TRACE_WARNING("%s(), nvs set blob fail, err %d", __func__, err_code);
573 }
574 } else {
575 if ((err_code = nvs_open(cache_addr, NVS_READWRITE , fp)) == ESP_OK) {
576 cache_env->is_open = true;
577 if (( err_code = nvs_set_blob(cache_env->addr_fp, cache_key, p_buf, length)) != ESP_OK) {
578 APPL_TRACE_WARNING("%s(), nvs set blob fail, err %d", __func__, err_code);
579 }
580 } else {
581 APPL_TRACE_ERROR("%s, Line = %d, nvs flash open fail, err_code = %x", __func__, __LINE__, err_code);
582 }
583 }
584
585 //free the buffer after used.
586 osi_free(p_buf);
587 return;
588 }
589
bta_gattc_co_cache_new_assoc_list(BD_ADDR src_addr,UINT8 index)590 BOOLEAN bta_gattc_co_cache_new_assoc_list(BD_ADDR src_addr, UINT8 index)
591 {
592 cache_addr_info_t *addr_info = &cache_env->cache_addr[index];
593 addr_info->assoc_addr = list_new(osi_free_func);
594 return (addr_info->assoc_addr != NULL ? TRUE : FALSE);
595 }
596
bta_gattc_co_cache_append_assoc_addr(BD_ADDR src_addr,BD_ADDR assoc_addr)597 BOOLEAN bta_gattc_co_cache_append_assoc_addr(BD_ADDR src_addr, BD_ADDR assoc_addr)
598 {
599 UINT8 addr_index = 0;
600 cache_addr_info_t *addr_info;
601 UINT8 *p_assoc_buf = osi_malloc(sizeof(BD_ADDR));
602 if(!p_assoc_buf) {
603 return FALSE;
604 }
605 memcpy(p_assoc_buf, assoc_addr, sizeof(BD_ADDR));
606 if ((addr_index = bta_gattc_co_find_addr_in_cache(src_addr)) != INVALID_ADDR_NUM) {
607 addr_info = &cache_env->cache_addr[addr_index];
608 if (addr_info->assoc_addr == NULL) {
609 addr_info->assoc_addr =list_new(NULL);
610 }
611 return list_append(addr_info->assoc_addr, p_assoc_buf);
612 } else {
613 osi_free(p_assoc_buf);
614 }
615
616 return FALSE;
617 }
618
bta_gattc_co_cache_remove_assoc_addr(BD_ADDR src_addr,BD_ADDR assoc_addr)619 BOOLEAN bta_gattc_co_cache_remove_assoc_addr(BD_ADDR src_addr, BD_ADDR assoc_addr)
620 {
621 UINT8 addr_index = 0;
622 cache_addr_info_t *addr_info;
623 if ((addr_index = bta_gattc_co_find_addr_in_cache(src_addr)) != INVALID_ADDR_NUM) {
624 addr_info = &cache_env->cache_addr[addr_index];
625 if (addr_info->assoc_addr != NULL) {
626 for (list_node_t *sn = list_begin(addr_info->assoc_addr);
627 sn != list_end(addr_info->assoc_addr); sn = list_next(sn)) {
628 void *addr = list_node(sn);
629 if (!memcmp(addr, assoc_addr, sizeof(BD_ADDR))) {
630 return list_remove(addr_info->assoc_addr, addr);
631 }
632 }
633 //return list_remove(addr_info->assoc_addr, assoc_addr);
634 } else {
635 return FALSE;
636 }
637 }
638
639 return FALSE;
640 }
641
bta_gattc_co_cache_find_src_addr(BD_ADDR assoc_addr,UINT8 * index)642 UINT8* bta_gattc_co_cache_find_src_addr(BD_ADDR assoc_addr, UINT8 *index)
643 {
644 UINT8 num = cache_env->num_addr;
645 cache_addr_info_t *addr_info = &cache_env->cache_addr[0];
646 UINT8 *addr_data;
647 //Check the assoc_addr list is NULL or not
648 if (addr_info->assoc_addr == NULL) {
649 *index = INVALID_ADDR_NUM;
650 return NULL;
651 }
652
653 for (int i = 0; i < num; i++) {
654 for (const list_node_t *node = list_begin(addr_info->assoc_addr); node != list_end(addr_info->assoc_addr);
655 node = list_next(node)) {
656 addr_data = (UINT8 *)list_node(node);
657 if (!memcmp(addr_data, assoc_addr, sizeof(BD_ADDR))) {
658 *index = i;
659 return (UINT8 *)addr_info->addr;
660 }
661 }
662 addr_info++;
663
664 if (addr_info->assoc_addr == NULL) {
665 *index = INVALID_ADDR_NUM;
666 return NULL;
667 }
668 }
669
670 *index = INVALID_ADDR_NUM;
671 return NULL;
672 }
673
bta_gattc_co_cache_clear_assoc_addr(BD_ADDR src_addr)674 BOOLEAN bta_gattc_co_cache_clear_assoc_addr(BD_ADDR src_addr)
675 {
676 UINT8 addr_index = 0;
677 cache_addr_info_t *addr_info;
678 if ((addr_index = bta_gattc_co_find_addr_in_cache(src_addr)) != INVALID_ADDR_NUM) {
679 addr_info = &cache_env->cache_addr[addr_index];
680 if (addr_info->assoc_addr != NULL) {
681 list_clear(addr_info->assoc_addr);
682 } else {
683 return FALSE;
684 }
685 return TRUE;
686 }
687
688 return FALSE;
689 }
690
691 // #endif /* #if( defined GATTC_CACHE_NVS ) && (GATTC_CACHE_NVS == TRUE) */
692 #endif /* #if( defined BLE_INCLUDED ) && (BLE_INCLUDED == TRUE) */
693 #endif /* #if( defined BTA_GATT_INCLUDED ) && (BTA_GATT_INCLUDED == TRUE) */
694