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