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)142 static void cacheReset(BD_ADDR bda)
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         //reduced the number address counter also
181         cache_env->num_addr--;
182 
183         //update addr list to nvs flash
184         if(cache_env->num_addr > 0) {
185             //update
186             UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
187             if(!p_buf) {
188                 APPL_TRACE_ERROR("%s malloc error", __func__);
189                 return;
190             }
191             UINT16 length = cache_env->num_addr*(sizeof(BD_ADDR) + sizeof(hash_key_t));
192             for (UINT8 i = 0; i < cache_env->num_addr; i++) {
193                 //copy the address to the buffer.
194                 memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)), cache_env->cache_addr[i].addr, sizeof(BD_ADDR));
195                 //copy the hash key to the buffer.
196                 memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)) + sizeof(BD_ADDR),
197                         cache_env->cache_addr[i].hash_key, sizeof(hash_key_t));
198             }
199             if (cache_env->is_open) {
200                 if (nvs_set_blob(cache_env->addr_fp, cache_key, p_buf, length) != ESP_OK) {
201                     APPL_TRACE_WARNING("%s, nvs set blob failed", __func__);
202                 }
203             }
204             osi_free(p_buf);
205 
206         } else {
207             //erase
208             if (cache_env->is_open) {
209                 nvs_erase_all(cache_env->addr_fp);
210                 nvs_close(cache_env->addr_fp);
211                 cache_env->is_open = FALSE;
212             } else {
213                 APPL_TRACE_WARNING("cache_env status is error");
214             }
215         }
216     }
217 }
218 
219 #endif /* BT_SUPPORT_NVM */
220 /*****************************************************************************
221 **  Function Declarations
222 *****************************************************************************/
223 
224 /*******************************************************************************
225 **
226 ** Function         bta_gattc_co_cache_open
227 **
228 ** Description      This callout function is executed by GATTC when a GATT server
229 **                  cache is ready to be sent.
230 **
231 ** Parameter        server_bda: server bd address of this cache belongs to
232 **                  evt: call in event to be passed in when cache open is done.
233 **                  conn_id: connection ID of this cache operation attach to.
234 **                  to_save: open cache to save or to load.
235 **
236 ** Returns          void.
237 **
238 *******************************************************************************/
bta_gattc_co_cache_open(BD_ADDR server_bda,BOOLEAN to_save,UINT8 * index)239 tBTA_GATT_STATUS bta_gattc_co_cache_open(BD_ADDR server_bda, BOOLEAN to_save, UINT8 *index)
240 {
241     /* open NV cache and send call in */
242     tBTA_GATT_STATUS status = BTA_GATT_OK;
243     if (!cacheOpen(server_bda, to_save, index)) {
244         status = BTA_GATT_ERROR;
245     }
246 
247     APPL_TRACE_DEBUG("%s() - status=%d", __func__, status);
248     return status;
249 }
250 
251 /*******************************************************************************
252 **
253 ** Function         bta_gattc_co_cache_load
254 **
255 ** Description      This callout function is executed by GATT when server cache
256 **                  is required to load.
257 **
258 ** Parameter        server_bda: server bd address of this cache belongs to
259 **                  evt: call in event to be passed in when cache save is done.
260 **                  num_attr: number of attribute to be save.
261 **                  attr_index: starting attribute index of the save operation.
262 **                  conn_id: connection ID of this cache operation attach to.
263 ** Returns
264 **
265 *******************************************************************************/
bta_gattc_co_cache_load(tBTA_GATTC_NV_ATTR * attr,UINT8 index)266 tBTA_GATT_STATUS bta_gattc_co_cache_load(tBTA_GATTC_NV_ATTR *attr, UINT8 index)
267 {
268 #if (!CONFIG_BT_STACK_NO_LOG)
269     UINT16              num_attr = 0;
270 #endif
271     tBTA_GATT_STATUS    status = BTA_GATT_ERROR;
272     size_t length = 0;
273     // Read the size of memory space required for blob
274     nvs_get_blob(cache_env->cache_addr[index].cache_fp, cache_key, NULL, &length);
275     // Read previously saved blob if available
276     esp_err_t err_code = nvs_get_blob(cache_env->cache_addr[index].cache_fp, cache_key, attr, &length);
277 #if (!CONFIG_BT_STACK_NO_LOG)
278     num_attr = length / sizeof(tBTA_GATTC_NV_ATTR);
279 #endif
280     status = (err_code == ESP_OK && length != 0) ? BTA_GATT_OK : BTA_GATT_ERROR;
281     APPL_TRACE_DEBUG("%s() - read=%d, status=%d, err_code = %d",
282                      __func__, num_attr, status, err_code);
283 
284     return status;
285  }
286 
bta_gattc_get_cache_attr_length(UINT8 index)287 size_t bta_gattc_get_cache_attr_length(UINT8 index)
288 {
289     size_t length = 0;
290     if (index == INVALID_ADDR_NUM) {
291         return 0;
292     }
293 
294     // Read the size of memory space required for blob
295     nvs_get_blob(cache_env->cache_addr[index].cache_fp, cache_key, NULL, &length);
296     return length;
297 }
298 
299 /*******************************************************************************
300 **
301 ** Function         bta_gattc_co_cache_save
302 **
303 ** Description      This callout function is executed by GATT when a server cache
304 **                  is available to save.
305 **
306 ** Parameter        server_bda: server bd address of this cache belongs to
307 **                  evt: call in event to be passed in when cache save is done.
308 **                  num_attr: number of attribute to be save.
309 **                  p_attr: pointer to the list of attributes to save.
310 **                  attr_index: starting attribute index of the save operation.
311 **                  conn_id: connection ID of this cache operation attach to.
312 ** Returns
313 **
314 *******************************************************************************/
bta_gattc_co_cache_save(BD_ADDR server_bda,UINT16 num_attr,tBTA_GATTC_NV_ATTR * p_attr_list)315 void bta_gattc_co_cache_save (BD_ADDR server_bda, UINT16 num_attr,
316                               tBTA_GATTC_NV_ATTR *p_attr_list)
317 {
318     tBTA_GATT_STATUS    status = BTA_GATT_OK;
319     hash_key_t hash_key = {0};
320     UINT8 index = INVALID_ADDR_NUM;
321     //calculate  the hash value of the attribute table which should be added to the nvs flash.
322     hash_function_blob((unsigned char *)p_attr_list, sizeof(tBTA_GATTC_NV_ATTR)*num_attr, hash_key);
323     //save the address list to the nvs flash
324     bta_gattc_co_cache_addr_save(server_bda, hash_key);
325 
326     if (cacheOpen(server_bda, TRUE, &index)) {
327         esp_err_t err_code = nvs_set_blob(cache_env->cache_addr[index].cache_fp, cache_key,
328                                           p_attr_list, sizeof(tBTA_GATTC_NV_ATTR)*num_attr);
329         status = (err_code == ESP_OK) ? BTA_GATT_OK : BTA_GATT_ERROR;
330     } else {
331         status = BTA_GATT_ERROR;
332     }
333 
334 #if CONFIG_BT_STACK_NO_LOG
335     (void) status;
336 #endif
337     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);
338 }
339 
340 /*******************************************************************************
341 **
342 ** Function         bta_gattc_co_cache_close
343 **
344 ** Description      This callout function is executed by GATTC when a GATT server
345 **                  cache is written completely.
346 **
347 ** Parameter        server_bda: server bd address of this cache belongs to
348 **                  conn_id: connection ID of this cache operation attach to.
349 **
350 ** Returns          void.
351 **
352 *******************************************************************************/
bta_gattc_co_cache_close(BD_ADDR server_bda,UINT16 conn_id)353 void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id)
354 {
355     UNUSED(conn_id);
356 //#ifdef BT_SUPPORT_NVM
357     cacheClose(server_bda);
358 //#endif /* BT_SUPPORT_NVM */
359     /* close NV when server cache is done saving or loading,
360        does not need to do anything for now on Insight */
361 
362     BTIF_TRACE_DEBUG("%s()", __FUNCTION__);
363 }
364 
365 /*******************************************************************************
366 **
367 ** Function         bta_gattc_co_cache_reset
368 **
369 ** Description      This callout function is executed by GATTC to reset cache in
370 **                  application
371 **
372 ** Parameter        server_bda: server bd address of this cache belongs to
373 **
374 ** Returns          void.
375 **
376 *******************************************************************************/
bta_gattc_co_cache_reset(BD_ADDR server_bda)377 void bta_gattc_co_cache_reset(BD_ADDR server_bda)
378 {
379     cacheReset(server_bda);
380 }
381 
bta_gattc_co_cache_addr_init(void)382 void bta_gattc_co_cache_addr_init(void)
383 {
384     nvs_handle_t fp;
385     esp_err_t err_code;
386     UINT8 num_addr;
387     size_t length = MAX_ADDR_LIST_CACHE_BUF;
388     UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
389     if (p_buf == NULL) {
390         APPL_TRACE_ERROR("%s malloc failed!", __func__);
391         return;
392     }
393 
394     cache_env = (cache_env_t *)osi_malloc(sizeof(cache_env_t));
395     if (cache_env == NULL) {
396         APPL_TRACE_ERROR("%s malloc failed!", __func__);
397         osi_free(p_buf);
398         return;
399     }
400 
401     memset(cache_env, 0x0, sizeof(cache_env_t));
402 
403     if ((err_code = nvs_open(cache_addr, NVS_READWRITE, &fp)) == ESP_OK) {
404         cache_env->addr_fp = fp;
405         cache_env->is_open = TRUE;
406         // Read previously saved blob if available
407         if ((err_code = nvs_get_blob(fp, cache_key, p_buf, &length)) != ESP_OK) {
408             if(err_code != ESP_ERR_NVS_NOT_FOUND) {
409                 APPL_TRACE_ERROR("%s, Line = %d, nvs flash get blob data fail, err_code = 0x%x", __func__, __LINE__, err_code);
410             }
411             osi_free(p_buf);
412             return;
413         }
414         num_addr = length / (sizeof(BD_ADDR) + sizeof(hash_key_t));
415         cache_env->num_addr = num_addr;
416         //read the address from nvs flash to cache address list.
417         for (UINT8 i = 0; i < num_addr; i++) {
418             memcpy(cache_env->cache_addr[i].addr, p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)), sizeof(BD_ADDR));
419             memcpy(cache_env->cache_addr[i].hash_key,
420                     p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)) + sizeof(BD_ADDR), sizeof(hash_key_t));
421 
422             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],
423                              cache_env->cache_addr[i].addr[3], cache_env->cache_addr[i].addr[4], cache_env->cache_addr[i].addr[5]);
424             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],
425                              cache_env->cache_addr[i].hash_key[2], cache_env->cache_addr[i].hash_key[3]);
426             bta_gattc_co_cache_new_assoc_list(cache_env->cache_addr[i].addr, i);
427         }
428     } else {
429         APPL_TRACE_ERROR("%s, Line = %d, nvs flash open fail, err_code = %x", __func__, __LINE__, err_code);
430         osi_free(p_buf);
431         return;
432     }
433 
434     osi_free(p_buf);
435     return;
436 }
437 
bta_gattc_co_cache_addr_deinit(void)438 void bta_gattc_co_cache_addr_deinit(void)
439 {
440     if(!cache_env->is_open) {
441         return;
442     }
443     nvs_close(cache_env->addr_fp);
444     cache_env->is_open = false;
445 
446     for(UINT8 i = 0; i< cache_env->num_addr; i++) {
447         cache_addr_info_t *addr_info = &cache_env->cache_addr[i];
448         if(addr_info) {
449             nvs_close(addr_info->cache_fp);
450             addr_info->is_open = false;
451             if(addr_info->assoc_addr) {
452                 list_free(addr_info->assoc_addr);
453             }
454         }
455     }
456 
457     osi_free(cache_env);
458     cache_env = NULL;
459 }
460 
bta_gattc_co_addr_in_cache(BD_ADDR bda)461 BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda)
462 {
463     UINT8 addr_index = 0;
464     UINT8 num = cache_env->num_addr;
465     cache_addr_info_t *addr_info = &cache_env->cache_addr[0];
466     for (addr_index = 0; addr_index < num; addr_index++) {
467         if (!memcmp(addr_info->addr, bda, sizeof(BD_ADDR))) {
468             return TRUE;
469         }
470     }
471 
472     return FALSE;
473 }
474 
bta_gattc_co_find_addr_in_cache(BD_ADDR bda)475 UINT8 bta_gattc_co_find_addr_in_cache(BD_ADDR bda)
476 {
477     UINT8 addr_index = 0;
478     UINT8 num = cache_env->num_addr;
479     cache_addr_info_t *addr_info = &cache_env->cache_addr[0];
480 
481     for (addr_index = 0; addr_index < num; addr_index++, addr_info++) {
482         if (!memcmp(addr_info->addr, bda, sizeof(BD_ADDR))) {
483             return addr_index;
484         }
485     }
486 
487     return INVALID_ADDR_NUM;
488 }
489 
bta_gattc_co_find_hash_in_cache(hash_key_t hash_key)490 UINT8 bta_gattc_co_find_hash_in_cache(hash_key_t hash_key)
491 {
492     UINT8 index = 0;
493     UINT8 num = cache_env->num_addr;
494     cache_addr_info_t *addr_info = &cache_env->cache_addr[0];
495     for (index = 0; index < num; index++) {
496         if (!memcmp(addr_info->hash_key, hash_key, sizeof(hash_key_t))) {
497             return index;
498         }
499     }
500 
501     return INVALID_ADDR_NUM;
502 }
503 
bta_gattc_co_get_addr_num(void)504 UINT8 bta_gattc_co_get_addr_num(void)
505 {
506     return cache_env->num_addr;
507 }
508 
bta_gattc_co_get_addr_list(BD_ADDR * addr_list)509 void bta_gattc_co_get_addr_list(BD_ADDR *addr_list)
510 {
511     UINT8 num = cache_env->num_addr;
512     for (UINT8 i = 0; i < num; i++) {
513         memcpy(addr_list[i], cache_env->cache_addr[i].addr, sizeof(BD_ADDR));
514     }
515 }
516 
bta_gattc_co_cache_addr_save(BD_ADDR bd_addr,hash_key_t hash_key)517 void bta_gattc_co_cache_addr_save(BD_ADDR bd_addr, hash_key_t hash_key)
518 {
519     esp_err_t err_code;
520     UINT8 num = ++cache_env->num_addr;
521     UINT8 index = 0;
522     UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
523     // check the address list has the same hash key or not
524     if (bta_gattc_co_find_hash_in_cache(hash_key) != INVALID_ADDR_NUM) {
525         APPL_TRACE_DEBUG("%s(), the hash key already in the cache list.", __func__);
526         if ((index = bta_gattc_co_find_addr_in_cache(bd_addr)) != INVALID_ADDR_NUM) {
527             APPL_TRACE_DEBUG("%s(), the hash bd_addr already in the cache list, index = %x", __func__, index);
528             //if the bd_addr already in the address list, update the hash key in it.
529             memcpy(cache_env->cache_addr[index].addr, bd_addr, sizeof(BD_ADDR));
530             memcpy(cache_env->cache_addr[index].hash_key, hash_key, sizeof(hash_key_t));
531         } else {
532             //if the bd_addr didn't in the address list, added the bd_addr to the last of the address list.
533             memcpy(cache_env->cache_addr[num - 1].hash_key, hash_key, sizeof(hash_key_t));
534             memcpy(cache_env->cache_addr[num - 1].addr, bd_addr, sizeof(BD_ADDR));
535         }
536 
537     } else {
538         APPL_TRACE_DEBUG("%s(), num = %d", __func__, num);
539         memcpy(cache_env->cache_addr[num - 1].addr, bd_addr, sizeof(BD_ADDR));
540         memcpy(cache_env->cache_addr[num - 1].hash_key, hash_key, sizeof(hash_key_t));
541     }
542 
543     nvs_handle_t *fp = &cache_env->addr_fp;
544     UINT16 length = num*(sizeof(BD_ADDR) + sizeof(hash_key_t));
545 
546     for (UINT8 i = 0; i < num; i++) {
547         //copy the address to the buffer.
548         memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)), cache_env->cache_addr[i].addr, sizeof(BD_ADDR));
549         //copy the hash key to the buffer.
550         memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(hash_key_t)) + sizeof(BD_ADDR),
551                 cache_env->cache_addr[i].hash_key, sizeof(hash_key_t));
552     }
553 
554     if (cache_env->is_open) {
555         if ((err_code = nvs_set_blob(cache_env->addr_fp, cache_key, p_buf, length)) != ESP_OK) {
556             APPL_TRACE_WARNING("%s(), nvs set blob fail, err %d", __func__, err_code);
557         }
558     } else {
559         if ((err_code = nvs_open(cache_addr, NVS_READWRITE , fp)) == ESP_OK) {
560             cache_env->is_open = true;
561             if (( err_code = nvs_set_blob(cache_env->addr_fp, cache_key, p_buf, length)) != ESP_OK) {
562                 APPL_TRACE_WARNING("%s(), nvs set blob fail, err %d", __func__, err_code);
563             }
564         } else {
565             APPL_TRACE_ERROR("%s, Line = %d, nvs flash open fail, err_code = %x", __func__, __LINE__, err_code);
566         }
567     }
568     //free the buffer after used.
569     osi_free(p_buf);
570     return;
571 
572 }
573 
bta_gattc_co_cache_new_assoc_list(BD_ADDR src_addr,UINT8 index)574 BOOLEAN bta_gattc_co_cache_new_assoc_list(BD_ADDR src_addr, UINT8 index)
575 {
576     cache_addr_info_t *addr_info = &cache_env->cache_addr[index];
577     addr_info->assoc_addr = list_new(osi_free_func);
578     return (addr_info->assoc_addr != NULL ? TRUE : FALSE);
579 }
580 
bta_gattc_co_cache_append_assoc_addr(BD_ADDR src_addr,BD_ADDR assoc_addr)581 BOOLEAN bta_gattc_co_cache_append_assoc_addr(BD_ADDR src_addr, BD_ADDR assoc_addr)
582 {
583     UINT8 addr_index = 0;
584     cache_addr_info_t *addr_info;
585     UINT8 *p_assoc_buf = osi_malloc(sizeof(BD_ADDR));
586     memcpy(p_assoc_buf, assoc_addr, sizeof(BD_ADDR));
587     if ((addr_index = bta_gattc_co_find_addr_in_cache(src_addr)) != INVALID_ADDR_NUM) {
588         addr_info = &cache_env->cache_addr[addr_index];
589         if (addr_info->assoc_addr == NULL) {
590             addr_info->assoc_addr =list_new(NULL);
591         }
592         return list_append(addr_info->assoc_addr, p_assoc_buf);
593     }
594 
595     return FALSE;
596 }
597 
bta_gattc_co_cache_remove_assoc_addr(BD_ADDR src_addr,BD_ADDR assoc_addr)598 BOOLEAN bta_gattc_co_cache_remove_assoc_addr(BD_ADDR src_addr, BD_ADDR assoc_addr)
599 {
600     UINT8 addr_index = 0;
601     cache_addr_info_t *addr_info;
602     if ((addr_index = bta_gattc_co_find_addr_in_cache(src_addr)) != INVALID_ADDR_NUM) {
603         addr_info = &cache_env->cache_addr[addr_index];
604         if (addr_info->assoc_addr != NULL) {
605             for (list_node_t *sn = list_begin(addr_info->assoc_addr);
606              sn != list_end(addr_info->assoc_addr); sn = list_next(sn)) {
607                 void *addr = list_node(sn);
608                 if (!memcmp(addr, assoc_addr, sizeof(BD_ADDR))) {
609                     return list_remove(addr_info->assoc_addr, addr);
610                 }
611             }
612             //return list_remove(addr_info->assoc_addr, assoc_addr);
613         } else {
614             return FALSE;
615         }
616     }
617 
618     return FALSE;
619 }
620 
bta_gattc_co_cache_find_src_addr(BD_ADDR assoc_addr,UINT8 * index)621 UINT8* bta_gattc_co_cache_find_src_addr(BD_ADDR assoc_addr, UINT8 *index)
622 {
623     UINT8 num = cache_env->num_addr;
624     cache_addr_info_t *addr_info = &cache_env->cache_addr[0];
625     UINT8 *addr_data;
626     //Check the assoc_addr list is NULL or not
627     if (addr_info->assoc_addr == NULL) {
628         *index = INVALID_ADDR_NUM;
629         return NULL;
630     }
631 
632     for (int i = 0; i < num; i++) {
633        for (const list_node_t *node = list_begin(addr_info->assoc_addr); node != list_end(addr_info->assoc_addr);
634             node = list_next(node)) {
635             addr_data = (UINT8 *)list_node(node);
636            if (!memcmp(addr_data, assoc_addr, sizeof(BD_ADDR))) {
637                *index = i;
638                return (UINT8 *)addr_info->addr;
639            }
640        }
641        addr_info++;
642 
643        if (addr_info->assoc_addr == NULL) {
644            *index = INVALID_ADDR_NUM;
645            return NULL;
646        }
647     }
648 
649     *index = INVALID_ADDR_NUM;
650     return NULL;
651 }
652 
bta_gattc_co_cache_clear_assoc_addr(BD_ADDR src_addr)653 BOOLEAN bta_gattc_co_cache_clear_assoc_addr(BD_ADDR src_addr)
654 {
655     UINT8 addr_index = 0;
656     cache_addr_info_t *addr_info;
657     if ((addr_index = bta_gattc_co_find_addr_in_cache(src_addr)) != INVALID_ADDR_NUM) {
658         addr_info = &cache_env->cache_addr[addr_index];
659         if (addr_info->assoc_addr != NULL) {
660             list_clear(addr_info->assoc_addr);
661         } else {
662             return FALSE;
663         }
664         return TRUE;
665     }
666 
667     return FALSE;
668 }
669 
670 // #endif /* #if( defined GATTC_CACHE_NVS ) && (GATTC_CACHE_NVS == TRUE) */
671 #endif /* #if( defined BLE_INCLUDED ) && (BLE_INCLUDED == TRUE) */
672 #endif /* #if( defined BTA_GATT_INCLUDED ) && (BTA_GATT_INCLUDED == TRUE) */
673