component/bt: Change the btc gattc callback function with the compile error.

1. Change all the gattc API && bta gattc layer.
2. Debug the code and change the btc_ble_gattc_get_db method.
3. Change the gatt read API interface.
4. Reconstruction the BTA_gattc_cache code.
5. Change back the bluedroid_get_status to marco.
6. Change the gattc docs format.
7. Change the docs format.
8. fix the read char value bug.
9. change the gattc_get_attr_count method.
10. Change back the bta_gattc write ccc code.
11. Change the gattc api docs format
12. Change the gattc API docs.
13. Change the prepare write descriptor method to avoid the exection.
14. modify gatt clinet demo with new API
15. Change the p_src_data->read.p_value to avoid exection.
16. Change the bugfix of gattc unreg for the notify.

    component/bt: Added the serch service res start_handle & end_handle to the result.

component/bt: Added the bta_gattc_cache_write when gatt discovery complete.

component/bt: Added the bta_gattc_cache_write declaration.

component/bt: Added the comments for esp_ble_gattc_cache_refresh API.

component/bt: Change the spelling errors & some comment error.

component/bt: fix bug of get gattc cache address list error.

1. Change the esp_bluedroid_get_status to macro;
2. added the malloc & free for the get_addr_list

component/bt: Added the addr_info->ass_addr == NULL Judgment to prevent crashes in the bta_gattc_co_cache_find_src_addr function.

component/bt: Fixed following gattc cache bugs

1. gattc can't refresh the gattc cache in the gatt discover state;
2. remove the nvs_get_blob in the cache address init function;
3. added the nvs_set_blob return value judgment in the cache address save function;
4. added the list_new when ass_address is NULL;
5. Change the ass_address list remove method to fix the ass address can't remove bug.
This commit is contained in:
Yulong 2018-03-11 23:34:20 -04:00 committed by yulong
parent fe907bde60
commit ece6bd9b82
14 changed files with 772 additions and 93 deletions

View file

@ -547,5 +547,37 @@ esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda)
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gattc_cache_associa(esp_gatt_if_t gattc_if, esp_bd_addr_t src_addr, esp_bd_addr_t ass_addr, bool is_associa)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_CACHE_ASSOCIAT;
arg.cache_associat.is_associa = is_associa;
arg.cache_associat.gattc_if = gattc_if;
memcpy(arg.cache_associat.src_addr, src_addr, sizeof(esp_bd_addr_t));
memcpy(arg.cache_associat.ass_addr, ass_addr, sizeof(esp_bd_addr_t));
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gattc_cache_get_addr_list(esp_gatt_if_t gattc_if)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ATC_CACHE_GET_ADDR_LIST;
arg.get_addr_list.gattc_if = gattc_if;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif ///GATTC_INCLUDED == TRUE

View file

@ -65,6 +65,8 @@ typedef enum {
ESP_GATTC_DISCONNECT_EVT = 41, /*!< When the ble physical connection disconnected, the event comes */
ESP_GATTC_READ_MULTIPLE_EVT = 42, /*!< When the ble characteristic or descriptor multiple complete, the event comes */
ESP_GATTC_QUEUE_FULL_EVT = 43, /*!< When the gattc command queue full, the event comes */
ESP_GATTC_SET_ASSOCIAT_EVT = 44, /*!< When the ble gattc set the associat address complete, the event comes */
ESP_GATTC_GET_ADDR_LIST_EVT = 45, /*!< When the ble get gattc address list in cache finish, the event comes */
} esp_gattc_cb_event_t;
@ -215,6 +217,20 @@ typedef union {
uint16_t conn_id; /*!< Connection id */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
} disconnect; /*!< Gatt client callback param of ESP_GATTC_DISCONNECT_EVT */
/**
* @brief ESP_GATTC_SET_ASSOCIAT_EVT
*/
struct gattc_set_ass_addr_cmp_evt_param {
esp_gatt_status_t status; /*!< Operation status */
} set_ass_cmp; /*!< Gatt client callback param of ESP_GATTC_SET_ASSOCIAT_EVT */
/**
* @brief ESP_GATTC_GET_ADDR_LIST_EVT
*/
struct gattc_get_addr_list_evt_param {
esp_gatt_status_t status; /*!< Operation status */
uint8_t num_addr; /*!< The number of address in the gattc cache address list */
esp_bd_addr_t *addr_list; /*!< The pointer to the address list which has been get from the gattc cache */
} get_addr_list; /*!< Gatt client callback param of ESP_GATTC_GET_ADDR_LIST_EVT */
/**
* @brief ESP_GATTC_QUEUE_FULL_EVT
@ -784,6 +800,34 @@ esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if,
*/
esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda);
/**
* @brief Add or delete the associated address with the source address.
*
* @param[in] gattc_if: Gatt client access interface.
* @param[in] src_addr: the source address which provide the attribute table.
* @param[in] ass_addr: the associated device address which went to share the attribute table with the source address.
* @param[in] is_associa: true add the associated device address, false remove the associated device address.
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_err_t esp_ble_gattc_cache_associa(esp_gatt_if_t gattc_if, esp_bd_addr_t src_addr,
esp_bd_addr_t ass_addr, bool is_associa);
/**
* @brief Get the address list which has store the attribute table in the gattc cache. There will
* callback ESP_GATTC_GET_ADDR_LIST_EVT event when get address list complete.
*
* @param[in] gattc_if: Gatt client access interface.
* @return
* - ESP_OK: success
* - other: failed
*
*/
esp_err_t esp_ble_gattc_cache_get_addr_list(esp_gatt_if_t gattc_if);
#ifdef __cplusplus
}
#endif

View file

@ -29,6 +29,7 @@
#include "bta_api.h"
#include "bta_dm_int.h"
#include "bta_dm_co.h"
#include "bta_gattc_co.h"
#include "btm_api.h"
#include "btm_int.h"
#include "btu.h"
@ -404,6 +405,10 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
BTM_SetDeviceClass (dev_class);
#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
#if (GATTC_INCLUDED == TRUE)
// load the gattc cache address list
bta_gattc_co_cache_addr_init();
#endif /* #if (GATTC_INCLUDED = TRUE) */
/* load BLE local information: ID keys, ER if available */
bta_dm_co_ble_load_local_keys(&key_mask, er, &id_key);

View file

@ -1754,6 +1754,7 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
}
if (found) {
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
return;
}
}
@ -1765,6 +1766,84 @@ void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
}
/* used to reset cache in application */
bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
}
void bta_gattc_process_api_cache_associat(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
{
tBTA_GATTC gattc_cb = {0};
gattc_cb.set_associa.client_if = p_msg->api_associa.client_if;
BOOLEAN state = FALSE;
tBTA_GATTC_CLCB *p_ass_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_associa.client_if,
p_msg->api_associa.ass_addr, BTA_TRANSPORT_LE);
tBTA_GATTC_RCB *p_clrcb = bta_gattc_cl_get_regcb(p_msg->api_associa.client_if);
if (p_ass_clcb != NULL) {
if (p_ass_clcb->state == BTA_GATTC_CONN_ST || p_ass_clcb->state == BTA_GATTC_DISCOVER_ST) {
gattc_cb.set_associa.status = BTA_GATT_BUSY;
if (p_clrcb != NULL) {
(*p_clrcb->p_cback)(BTA_GATTC_ASSOCIAT_EVT, &gattc_cb);
return;
}
}
}
if (p_msg->api_associa.is_associa) {
if ((state = bta_gattc_co_cache_append_ass_addr(p_msg->api_associa.src_addr, p_msg->api_associa.ass_addr)) == TRUE) {
gattc_cb.set_associa.status = BTA_GATT_OK;
} else {
gattc_cb.set_associa.status = BTA_GATT_ERROR;
if (p_clrcb != NULL) {
(*p_clrcb->p_cback)(BTA_GATTC_ASSOCIAT_EVT, &gattc_cb);
return;
}
}
} else {
if (( state = bta_gattc_co_cache_remove_ass_addr(p_msg->api_associa.src_addr, p_msg->api_associa.ass_addr)) == TRUE) {
gattc_cb.set_associa.status = BTA_GATT_OK;
} else {
gattc_cb.set_associa.status = BTA_GATT_ERROR;
if (p_clrcb != NULL) {
(*p_clrcb->p_cback)(BTA_GATTC_ASSOCIAT_EVT, &gattc_cb);
return;
}
}
}
if (p_clrcb != NULL) {
(*p_clrcb->p_cback)(BTA_GATTC_ASSOCIAT_EVT, &gattc_cb);
}
return;
}
void bta_gattc_process_api_cache_get_addr_list(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
{
tBTA_GATTC gattc_cb = {0};
tBTA_GATTC_RCB *p_clrcb = bta_gattc_cl_get_regcb(p_msg->api_get_addr.client_if);
UINT8 num_addr = bta_gattc_co_get_addr_num();
gattc_cb.get_addr_list.client_if = p_msg->api_get_addr.client_if;
if (num_addr != 0) {
gattc_cb.get_addr_list.num_addr = num_addr;
gattc_cb.get_addr_list.bda_list = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR)*num_addr);
if (gattc_cb.get_addr_list.bda_list != NULL) {
bta_gattc_co_get_addr_list(gattc_cb.get_addr_list.bda_list);
gattc_cb.get_addr_list.status = BTA_GATT_OK;
} else {
gattc_cb.get_addr_list.status = BTA_GATT_ERROR;
}
} else {
gattc_cb.get_addr_list.status = BTA_GATT_NOT_FOUND;
}
if (p_clrcb != NULL) {
(* p_clrcb->p_cback)(BTA_GATTC_GET_ADDR_LIST_EVT, &gattc_cb);
}
//release the address list buffer after used.
if (gattc_cb.get_addr_list.bda_list != NULL) {
osi_free((void *)gattc_cb.get_addr_list.bda_list);
}
}
/*******************************************************************************

View file

@ -929,6 +929,35 @@ void BTA_GATTC_Refresh(BD_ADDR remote_bda)
return;
}
void BTA_GATTC_CacheAssociat(tBTA_GATTC_IF client_if, BD_ADDR src_addr, BD_ADDR ass_addr, BOOLEAN is_associa)
{
tBTA_GATTC_API_CACHE_ASSO *p_buf;
if ((p_buf = (tBTA_GATTC_API_CACHE_ASSO *)osi_malloc(sizeof(tBTA_GATTC_API_CACHE_ASSO))) != NULL) {
p_buf->hdr.event = BTA_GATTC_API_CACHE_ASSOCIAT_EVT;
p_buf->is_associa = is_associa;
p_buf->client_if = client_if;
memcpy(p_buf->src_addr, src_addr, sizeof(BD_ADDR));
memcpy(p_buf->ass_addr, ass_addr, sizeof(BD_ADDR));
bta_sys_sendmsg(p_buf);
}
return;
}
void BTA_GATTC_CacheGetAddrList(tBTA_GATTC_IF client_if)
{
tBTA_GATTC_API_GET_ADDR *p_buf;
if ((p_buf = (tBTA_GATTC_API_GET_ADDR *)osi_malloc(sizeof(tBTA_GATTC_API_GET_ADDR))) != NULL) {
p_buf->hdr.event = BTA_GATTC_API_CACHE_GET_ADDR_LIST_EVT;
p_buf->client_if = client_if;
bta_sys_sendmsg(p_buf);
}
return;
}
/*******************************************************************************
**
** Function BTA_GATTC_Listen

View file

@ -49,6 +49,8 @@ static size_t bta_gattc_get_db_size_with_type(list_t *services,
bt_gatt_db_attribute_type_t type,
tBT_UUID *char_uuid,
UINT16 start_handle, UINT16 end_handle);
static void bta_gattc_cache_write(BD_ADDR server_bda, UINT16 num_attr,
tBTA_GATTC_NV_ATTR *attr);
tBTA_GATTC_SERVICE* bta_gattc_find_matching_service(const list_t *services, UINT16 handle);
tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle);
tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle);
@ -551,10 +553,7 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
/* save cache to NV */
p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE;
if (btm_sec_is_a_bonded_dev(p_srvc_cb->server_bda)) {
bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id);
}
bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id);
bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
}
/*******************************************************************************
@ -1217,6 +1216,7 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
if (!p_srcb->p_srvc_cache || list_is_empty(p_srcb->p_srvc_cache)) {
APPL_TRACE_DEBUG("the service cache is empty.");
*count = 0;
*char_db = NULL;
return;
@ -1225,6 +1225,7 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
size_t db_size = ((end_handle - start_handle) < p_srcb->total_attr) ? (end_handle - start_handle) : p_srcb->total_attr;
if (!db_size) {
APPL_TRACE_DEBUG("the db size is 0.");
*count = 0;
*char_db = NULL;
return;
@ -1233,6 +1234,7 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
void *buffer = osi_malloc(db_size*sizeof(btgatt_db_element_t));
if (!buffer) {
APPL_TRACE_DEBUG("the buffer is NULL.");
*count = 0;
*char_db = NULL;
return;
@ -1303,6 +1305,7 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
}
if ((op == GATT_OP_GET_ALL_CHAR || op == GATT_OP_GET_CHAR_BY_UUID) &&
(char_uuid == NULL || bta_gattc_uuid_compare(&p_char->uuid, char_uuid, TRUE))) {
APPL_TRACE_DEBUG("%s(), uuid match.", __func__);
bta_gattc_fill_gatt_db_el(curr_db_attr,
BTGATT_DB_CHARACTERISTIC,
p_char->handle,
@ -1813,7 +1816,7 @@ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr,
tBTA_GATTC_NV_ATTR *p_attr)
{
/* first attribute loading, initialize buffer */
APPL_TRACE_ERROR("%s: bta_gattc_rebuild_cache", __func__);
APPL_TRACE_DEBUG("%s: bta_gattc_rebuild_cache, num_attr = %d", __func__, num_attr);
list_free(p_srvc_cb->p_srvc_cache);
p_srvc_cb->p_srvc_cache = NULL;
@ -1892,6 +1895,11 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
int i = 0;
size_t db_size = bta_gattc_get_db_size(p_srvc_cb->p_srvc_cache, 0x0000, 0xFFFF);
tBTA_GATTC_NV_ATTR *nv_attr = osi_malloc(db_size * sizeof(tBTA_GATTC_NV_ATTR));
// This step is very importent, if not clear the memory, the hasy key base on the attribute case will be not corret.
if (nv_attr != NULL) {
memset(nv_attr, 0, db_size * sizeof(tBTA_GATTC_NV_ATTR));
}
if (!nv_attr) {
APPL_TRACE_WARNING("%s(), no resource.", __func__);
return;
@ -1967,6 +1975,7 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
}
/* TODO: Gattc cache write/read need to be added in IDF 3.1*/
bta_gattc_cache_write(p_srvc_cb->server_bda, db_size, nv_attr);
osi_free(nv_attr);
}
@ -1983,56 +1992,56 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
*******************************************************************************/
bool bta_gattc_cache_load(tBTA_GATTC_CLCB *p_clcb)
{
#if 0
char fname[255] = {0};
bta_gattc_generate_cache_file_name(fname, p_clcb->p_srcb->server_bda);
/* open NV cache and send call in */
tBTA_GATT_STATUS status = BTA_GATT_OK;
UINT8 index = 0;
tBTA_GATTC_NV_ATTR *attr = NULL;
FILE *fd = fopen(fname, "rb");
if (!fd) {
APPL_TRACE_ERROR("%s: can't open GATT cache file %s for reading, error: %s",
__func__, fname, strerror(errno));
if ((status = bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, true, &index)) != BTA_GATT_OK) {
APPL_TRACE_DEBUG("%s(), gattc cache open fail, index = %x", __func__, index);
return false;
}
UINT16 cache_ver = 0;
tBTA_GATTC_NV_ATTR *attr = NULL;
bool success = false;
size_t num_attr = bta_gattc_get_cache_attr_length(index) / sizeof(tBTA_GATTC_NV_ATTR);
if (fread(&cache_ver, sizeof(UINT16), 1, fd) != 1) {
APPL_TRACE_ERROR("%s: can't read GATT cache version from: %s", __func__, fname);
goto done;
if (!num_attr) {
return false;
}
if (cache_ver != GATT_CACHE_VERSION) {
APPL_TRACE_ERROR("%s: wrong GATT cache version: %s", __func__, fname);
goto done;
//don't forget to set the total attribute number.
p_clcb->p_srcb->total_attr = num_attr;
APPL_TRACE_DEBUG("%s(), index = %x, num_attr = %d", __func__, index, num_attr);
if ((attr = osi_malloc(sizeof(tBTA_GATTC_NV_ATTR) * num_attr)) == NULL) {
APPL_TRACE_ERROR("%s, No Memory.", __func__);
return false;
}
UINT16 num_attr = 0;
if (fread(&num_attr, sizeof(UINT16), 1, fd) != 1) {
APPL_TRACE_ERROR("%s: can't read number of GATT attributes: %s", __func__, fname);
goto done;
}
attr = osi_malloc(sizeof(tBTA_GATTC_NV_ATTR) * num_attr);
if (fread(attr, sizeof(tBTA_GATTC_NV_ATTR), 0xFF, fd) != num_attr) {
APPL_TRACE_ERROR("%s: can't read GATT attributes: %s", __func__, fname);
goto done;
if ((status = bta_gattc_co_cache_load(attr, index)) != BTA_GATT_OK) {
APPL_TRACE_DEBUG("%s(), gattc cache load fail, status = %x", __func__, status);
return false;
}
bta_gattc_rebuild_cache(p_clcb->p_srcb, num_attr, attr);
success = true;
done:
//free the attr buffer after used.
osi_free(attr);
fclose(fd);
return success;
#endif
bool success = false;
return success;
return true;
}
/*******************************************************************************
**
** Function bta_gattc_cache_write
**
** Description This callout function is executed by GATT when a server cache
** is available to save.
**
** Parameter server_bda: server bd address of this cache belongs to
** num_attr: number of attribute to be save.
** attr: pointer to the list of attributes to save.
** Returns
**
*******************************************************************************/
static void bta_gattc_cache_write(BD_ADDR server_bda, UINT16 num_attr,
tBTA_GATTC_NV_ATTR *attr)
{
bta_gattc_co_cache_save(server_bda, num_attr, attr);
}
/*******************************************************************************
@ -2052,6 +2061,7 @@ void bta_gattc_cache_reset(BD_ADDR server_bda)
BTIF_TRACE_DEBUG("%s", __func__);
char fname[255] = {0};
bta_gattc_generate_cache_file_name(fname, server_bda);
bta_gattc_co_cache_reset(server_bda);
//unlink(fname);
}
#endif /* BTA_GATT_INCLUDED */

View file

@ -356,7 +356,12 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
case BTA_GATTC_API_REFRESH_EVT:
bta_gattc_process_api_refresh(p_cb, (tBTA_GATTC_DATA *) p_msg);
break;
case BTA_GATTC_API_CACHE_ASSOCIAT_EVT:
bta_gattc_process_api_cache_associat(p_cb, (tBTA_GATTC_DATA *)p_msg);
break;
case BTA_GATTC_API_CACHE_GET_ADDR_LIST_EVT:
bta_gattc_process_api_cache_get_addr_list(p_cb, (tBTA_GATTC_DATA *)p_msg);
break;
#if BLE_INCLUDED == TRUE
case BTA_GATTC_API_LISTEN_EVT:
bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg);

View file

@ -183,6 +183,8 @@ typedef UINT8 tBTA_GATT_STATUS;
#define BTA_GATTC_DISCONNECT_EVT 36 /* GATTC DISCONNECT event */
#define BTA_GATTC_READ_MULTIPLE_EVT 37 /* GATTC Read mutiple event */
#define BTA_GATTC_QUEUE_FULL_EVT 38 /* GATTC queue full event */
#define BTA_GATTC_ASSOCIAT_EVT 39 /* GATTC association address event */
#define BTA_GATTC_GET_ADDR_LIST_EVT 40 /* GATTC get address list in the cache event */
typedef UINT8 tBTA_GATTC_EVT;
@ -364,12 +366,24 @@ typedef struct {
BOOLEAN is_full;
} tBTA_GATTC_QUEUE_FULL;
typedef struct {
tBTA_GATT_STATUS status;
tBTA_GATTC_IF client_if;
} tBTA_GATTC_SET_ASSOCIAT;
typedef struct {
tBTA_GATT_STATUS status;
tBTA_GATTC_IF client_if;
UINT8 num_addr;
BD_ADDR *bda_list;
} tBTA_GATTC_GET_ADDR_LIST;
typedef struct {
tBTA_GATT_STATUS status;
tBTA_GATTC_IF client_if;
UINT16 conn_id;
BD_ADDR remote_bda;
}tBTA_GATTC_OPEN_CLOSE;
} tBTA_GATTC_OPEN_CLOSE;
typedef struct {
tBTA_GATTC_IF client_if;
@ -413,6 +427,8 @@ typedef union {
tBTA_GATTC_CONGEST congest;
tBTA_GATTC_QUEUE_FULL queue_full;
tBTA_GATTC_SERVICE_CHANGE srvc_chg; /* service change event */
tBTA_GATTC_SET_ASSOCIAT set_associa;
tBTA_GATTC_GET_ADDR_LIST get_addr_list;
} tBTA_GATTC;
/* GATTC enable callback function */
@ -1085,6 +1101,10 @@ extern void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_mult
*******************************************************************************/
extern void BTA_GATTC_Refresh(BD_ADDR remote_bda);
extern void BTA_GATTC_CacheAssociat(tBTA_GATTC_IF client_if, BD_ADDR src_addr, BD_ADDR ass_addr, BOOLEAN is_associa);
extern void BTA_GATTC_CacheGetAddrList(tBTA_GATTC_IF client_if);
/*******************************************************************************
**

View file

@ -36,7 +36,7 @@ typedef struct {
tBTA_GATT_STATUS status;
} tBTA_GATTC_CI_EVT;
#define BTA_GATTC_NV_LOAD_MAX 10
#define BTA_GATTC_NV_LOAD_MAX 100
/* Read Ready Event */
typedef struct {

View file

@ -25,6 +25,7 @@
#define BTA_GATTC_CO_H
#include "bta_gatt_api.h"
#include "hashkey.h"
/*******************************************************************************
**
@ -41,8 +42,7 @@
** Returns void.
**
*******************************************************************************/
extern void bta_gattc_co_cache_open(BD_ADDR server_bda, UINT16 evt,
UINT16 conn_id, BOOLEAN to_save);
extern tBTA_GATT_STATUS bta_gattc_co_cache_open(BD_ADDR server_bda, BOOLEAN to_save, UINT8 *index);
/*******************************************************************************
**
@ -75,9 +75,8 @@ extern void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id);
** Returns
**
*******************************************************************************/
extern void bta_gattc_co_cache_save(BD_ADDR server_bda, UINT16 evt,
UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr,
UINT16 attr_index, UINT16 conn_id);
extern void bta_gattc_co_cache_save (BD_ADDR server_bda, UINT16 num_attr,
tBTA_GATTC_NV_ATTR *p_attr_list);
/*******************************************************************************
**
@ -94,8 +93,7 @@ extern void bta_gattc_co_cache_save(BD_ADDR server_bda, UINT16 evt,
** Returns
**
*******************************************************************************/
extern void bta_gattc_co_cache_load(BD_ADDR server_bda, UINT16 evt,
UINT16 start_index, UINT16 conn_id);
extern tBTA_GATT_STATUS bta_gattc_co_cache_load(tBTA_GATTC_NV_ATTR *attr, UINT8 index);
/*******************************************************************************
**
@ -111,4 +109,30 @@ extern void bta_gattc_co_cache_load(BD_ADDR server_bda, UINT16 evt,
*******************************************************************************/
extern void bta_gattc_co_cache_reset(BD_ADDR server_bda);
extern size_t bta_gattc_get_cache_attr_length(UINT8 index);
extern void bta_gattc_co_cache_addr_init(void);
extern BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda);
extern uint8_t bta_gattc_co_find_addr_in_cache(BD_ADDR bda);
extern uint8_t bta_gattc_co_find_hash_in_cache(coap_key_t hash_key);
extern UINT8 bta_gattc_co_get_addr_num(void);
extern void bta_gattc_co_get_addr_list(BD_ADDR *addr_list);
extern void bta_gattc_co_cache_addr_save(BD_ADDR bd_addr, coap_key_t hash_key);
extern BOOLEAN bta_gattc_co_cache_new_ass_list(BD_ADDR src_addr, uint8_t index);
extern BOOLEAN bta_gattc_co_cache_append_ass_addr(BD_ADDR src_addr, BD_ADDR ass_addr);
extern BOOLEAN bta_gattc_co_cache_remove_ass_addr(BD_ADDR src_addr, BD_ADDR ass_addr);
uint8_t* bta_gattc_co_cache_find_src_addr(BD_ADDR ass_addr, uint8_t *index);
extern BOOLEAN bta_gattc_co_cache_clear_ass_addr(BD_ADDR src_addr);
#endif /* BTA_GATT_CO_H */

View file

@ -65,7 +65,9 @@ enum {
BTA_GATTC_API_LISTEN_EVT,
BTA_GATTC_API_BROADCAST_EVT,
BTA_GATTC_API_DISABLE_EVT,
BTA_GATTC_ENC_CMPL_EVT
BTA_GATTC_ENC_CMPL_EVT,
BTA_GATTC_API_CACHE_ASSOCIAT_EVT,
BTA_GATTC_API_CACHE_GET_ADDR_LIST_EVT,
};
typedef UINT16 tBTA_GATTC_INT_EVT;
@ -186,6 +188,19 @@ typedef struct {
BT_HDR hdr;
} tBTA_GATTC_API_CFG_MTU;
typedef struct {
BT_HDR hdr;
tBTA_GATTC_IF client_if;
BD_ADDR src_addr;
BD_ADDR ass_addr;
BOOLEAN is_associa;
} tBTA_GATTC_API_CACHE_ASSO;
typedef struct {
BT_HDR hdr;
tBTA_GATTC_IF client_if;
} tBTA_GATTC_API_GET_ADDR;
typedef struct {
BT_HDR hdr;
BD_ADDR remote_bda;
@ -215,6 +230,8 @@ typedef union {
tBTA_GATTC_API_EXEC api_exec;
tBTA_GATTC_API_READ_MULTI api_read_multi;
tBTA_GATTC_API_CFG_MTU api_mtu;
tBTA_GATTC_API_CACHE_ASSO api_associa;
tBTA_GATTC_API_GET_ADDR api_get_addr;
tBTA_GATTC_OP_CMPL op_cmpl;
tBTA_GATTC_INT_CONN int_conn;
tBTA_GATTC_ENC_CMPL enc_cmpl;
@ -447,6 +464,8 @@ extern void bta_gattc_send_connect_cback( tBTA_GATTC_RCB *p_clreg, BD_ADDR remot
extern void bta_gattc_send_disconnect_cback( tBTA_GATTC_RCB *p_clreg, tGATT_DISCONN_REASON reason,
BD_ADDR remote_bda, UINT16 conn_id);
extern void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
extern void bta_gattc_process_api_cache_associat(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
extern void bta_gattc_process_api_cache_get_addr_list(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
#if BLE_INCLUDED == TRUE
extern void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);

View file

@ -142,6 +142,18 @@ static void btc_gattc_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
}
break;
}
case BTA_GATTC_GET_ADDR_LIST_EVT: {
if (p_src_data->get_addr_list.bda_list != NULL) {
uint8_t num_addr = p_src_data->get_addr_list.num_addr;
p_dest_data->get_addr_list.bda_list = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR) * num_addr);
if (p_dest_data->get_addr_list.bda_list) {
memcpy(p_dest_data->get_addr_list.bda_list, p_src_data->get_addr_list.bda_list, sizeof(BD_ADDR) * num_addr);
} else {
LOG_ERROR("%s %d no mem\n", __func__, msg->act);
}
}
break;
}
default:
break;
}
@ -159,6 +171,12 @@ static void btc_gattc_free_req_data(btc_msg_t *msg)
}
break;
}
case BTA_GATTC_GET_ADDR_LIST_EVT: {
if (arg->get_addr_list.bda_list) {
osi_free(arg->get_addr_list.bda_list);
}
break;
}
default:
break;
}
@ -721,6 +739,15 @@ void btc_gattc_call_handler(btc_msg_t *msg)
case BTC_GATTC_ACT_CACHE_REFRESH:
BTA_GATTC_Refresh(arg->cache_refresh.remote_bda);
break;
case BTC_GATTC_ACT_CACHE_ASSOCIAT:
BTA_GATTC_CacheAssociat(arg->cache_associat.gattc_if,
arg->cache_associat.src_addr,
arg->cache_associat.ass_addr,
arg->cache_associat.is_associa);
break;
case BTC_GATTC_ATC_CACHE_GET_ADDR_LIST:
BTA_GATTC_CacheGetAddrList(arg->get_addr_list.gattc_if);
break;
default:
LOG_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
break;
@ -928,6 +955,20 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
btc_gattc_cb_to_app(ESP_GATTC_QUEUE_FULL_EVT, gattc_if, &param);
break;
}
case BTA_GATTC_ASSOCIAT_EVT: {
gattc_if = arg->set_associa.client_if;
param.set_ass_cmp.status = arg->set_associa.status;
btc_gattc_cb_to_app(ESP_GATTC_SET_ASSOCIAT_EVT, gattc_if, &param);
break;
}
case BTA_GATTC_GET_ADDR_LIST_EVT: {
gattc_if = arg->get_addr_list.client_if;
param.get_addr_list.status = arg->get_addr_list.status;
param.get_addr_list.num_addr = arg->get_addr_list.num_addr;
param.get_addr_list.addr_list = arg->get_addr_list.bda_list;
btc_gattc_cb_to_app(ESP_GATTC_GET_ADDR_LIST_EVT, gattc_if, &param);
break;
}
default:
LOG_DEBUG("%s: Unhandled event (%d)!", __FUNCTION__, msg->act);
break;

View file

@ -38,6 +38,8 @@ typedef enum {
BTC_GATTC_ACT_REG_FOR_NOTIFY,
BTC_GATTC_ACT_UNREG_FOR_NOTIFY,
BTC_GATTC_ACT_CACHE_REFRESH,
BTC_GATTC_ACT_CACHE_ASSOCIAT,
BTC_GATTC_ATC_CACHE_GET_ADDR_LIST,
} btc_gattc_act_t;
/* btc_ble_gattc_args_t */
@ -167,6 +169,17 @@ typedef union {
struct cache_refresh_arg {
esp_bd_addr_t remote_bda;
} cache_refresh;
//BTC_GATTC_ACT_CACHE_ASSOCIAT
struct cache_associat_arg {
esp_gatt_if_t gattc_if;
esp_bd_addr_t src_addr;
esp_bd_addr_t ass_addr;
bool is_associa;
} cache_associat;
//BTC_GATTC_ATC_CACHE_GET_ADDR_LIST
struct cache_get_addr_list_arg {
esp_gatt_if_t gattc_if;
}get_addr_list;
} btc_ble_gattc_args_t;
void btc_gattc_call_handler(btc_msg_t *msg);

View file

@ -24,15 +24,22 @@
#include "bta_gattc_ci.h"
// #include "btif_util.h"
#include "btm_int.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "list.h"
#include "esp_err.h"
#include "allocator.h"
#if( defined BLE_INCLUDED ) && (BLE_INCLUDED == TRUE)
#if( defined BTA_GATT_INCLUDED ) && (GATTC_INCLUDED == TRUE)
#define GATT_CACHE_PREFIX "/data/misc/bluedroid/gatt_cache_"
#define GATT_CACHE_PREFIX "gatt_"
#define INVALID_ADDR_NUM 0xff
#define MAX_DEVICE_IN_CACHE 50
#define MAX_ADDR_LIST_CACHE_BUF 2048
#ifdef BT_SUPPORT_NVM
static FILE *sCacheFD = 0;
static void getFilename(char *buffer, BD_ADDR bda)
{
sprintf(buffer, "%s%02x%02x%02x%02x%02x%02x", GATT_CACHE_PREFIX
@ -65,6 +72,96 @@ static void cacheReset(BD_ADDR bda)
unlink(fname);
}
#else
static const char *cache_key = "gattc_cahe_key";
static const char *cache_addr = "cache_addr_tab";
nvs_handle nvs_fp;
typedef struct {
//save the service data in the list according to the address
nvs_handle cache_fp;
BOOLEAN is_open;
BD_ADDR addr;
coap_key_t hash_key;
list_t *ass_addr;
}cache_addr_info_t;
typedef struct {
//save the address list in the cache
nvs_handle addr_fp;
BOOLEAN is_open;
UINT8 num_addr;
cache_addr_info_t cache_addr[MAX_DEVICE_IN_CACHE];
}cache_env_t;
cache_env_t cache_env;
static void getFilename(char *buffer, coap_key_t hash)
{
sprintf(buffer, "%s%02x%02x%02x%02x", GATT_CACHE_PREFIX,
hash[0], hash[1], hash[2], hash[3]);
}
static void cacheClose(BD_ADDR bda)
{
UINT8 index = 0;
if ((index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) {
if (cache_env.cache_addr[index].is_open) {
nvs_close(cache_env.cache_addr[index].cache_fp);
cache_env.cache_addr[index].is_open = FALSE;
}
}
}
static bool cacheOpen(BD_ADDR bda, bool to_save, UINT8 *index)
{
UNUSED(to_save);
char fname[255] = {0};
UINT8 *ass_addr = NULL;
esp_err_t status = ESP_FAIL;
coap_key_t hash_key = {0};
if (((*index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) ||
((ass_addr = bta_gattc_co_cache_find_src_addr(bda, index)) != NULL)) {
if (cache_env.cache_addr[*index].is_open) {
return TRUE;
} else {
memcpy(hash_key, cache_env.cache_addr[*index].hash_key, sizeof(coap_key_t));
getFilename(fname, hash_key);
if ((status = nvs_open(fname, NVS_READWRITE, &cache_env.cache_addr[*index].cache_fp)) == ESP_OK) {
// Set the open flag to TRUE when success to open the hash file.
cache_env.cache_addr[*index].is_open = TRUE;
}
}
}
return ((status == ESP_OK) ? true : false);
}
static void cacheReset(BD_ADDR bda)
{
char fname[255] = {0};
getFilename(fname, bda);
UINT8 index = 0;
//cache_env.cache_addr
if ((index = bta_gattc_co_find_addr_in_cache(bda)) != INVALID_ADDR_NUM) {
//clear the association address pending in the source address.
bta_gattc_co_cache_clear_ass_addr(bda);
if (cache_env.cache_addr[index].is_open) {
nvs_erase_all(cache_env.cache_addr[index].cache_fp);
nvs_close(cache_env.cache_addr[index].cache_fp);
cache_env.cache_addr[index].is_open = FALSE;
}
UINT8 num = cache_env.num_addr;
//delete the server_bda in the addr_info list.
for(UINT8 i = index; i < (num - 1); i++) {
memcpy(&cache_env.cache_addr[i], &cache_env.cache_addr[i+1], sizeof(cache_addr_info_t));
}
//reduced the number address counter also
cache_env.num_addr--;
}
}
#endif /* BT_SUPPORT_NVM */
/*****************************************************************************
** Function Declarations
@ -85,20 +182,16 @@ static void cacheReset(BD_ADDR bda)
** Returns void.
**
*******************************************************************************/
void bta_gattc_co_cache_open(BD_ADDR server_bda, UINT16 evt, UINT16 conn_id, BOOLEAN to_save)
tBTA_GATT_STATUS bta_gattc_co_cache_open(BD_ADDR server_bda, BOOLEAN to_save, UINT8 *index)
{
#ifdef BT_SUPPORT_NVM
/* open NV cache and send call in */
tBTA_GATT_STATUS status = BTA_GATT_OK;
if (!btm_sec_is_a_bonded_dev(server_bda) || !cacheOpen(server_bda, to_save)) {
tBTA_GATT_STATUS status = BTA_GATT_OK;
if (!cacheOpen(server_bda, to_save, index)) {
status = BTA_GATT_ERROR;
}
BTIF_TRACE_DEBUG("%s() - status=%d", __FUNCTION__, status);
bta_gattc_ci_cache_open(server_bda, evt, status, conn_id);
#else
bta_gattc_ci_cache_open(server_bda, evt, BTA_GATT_ERROR, conn_id);
#endif /* BT_SUPPORT_NVM */
APPL_TRACE_DEBUG("%s() - status=%d", __func__, status);
return status;
}
/*******************************************************************************
@ -116,21 +209,33 @@ void bta_gattc_co_cache_open(BD_ADDR server_bda, UINT16 evt, UINT16 conn_id, BOO
** Returns
**
*******************************************************************************/
void bta_gattc_co_cache_load(BD_ADDR server_bda, UINT16 evt, UINT16 start_index, UINT16 conn_id)
tBTA_GATT_STATUS bta_gattc_co_cache_load(tBTA_GATTC_NV_ATTR *attr, UINT8 index)
{
UINT16 num_attr = 0;
tBTA_GATTC_NV_ATTR attr[BTA_GATTC_NV_LOAD_MAX];
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
#ifdef BT_SUPPORT_NVM
if (sCacheFD && (0 == fseek(sCacheFD, start_index * sizeof(tBTA_GATTC_NV_ATTR), SEEK_SET))) {
num_attr = fread(attr, sizeof(tBTA_GATTC_NV_ATTR), BTA_GATTC_NV_LOAD_MAX, sCacheFD);
status = (num_attr < BTA_GATTC_NV_LOAD_MAX ? BTA_GATT_OK : BTA_GATT_MORE);
}
BTIF_TRACE_DEBUG("%s() - sCacheFD=%p, start_index=%d, read=%d, status=%d",
__FUNCTION__, sCacheFD, start_index, num_attr, status);
#endif /* BT_SUPPORT_NVM */
size_t length = 0;
// Read the size of memory space required for blob
nvs_get_blob(cache_env.cache_addr[index].cache_fp, cache_key, NULL, &length);
// Read previously saved blob if available
esp_err_t err_code = nvs_get_blob(cache_env.cache_addr[index].cache_fp, cache_key, attr, &length);
num_attr = length / sizeof(tBTA_GATTC_NV_ATTR);
status = (err_code == ESP_OK && length != 0) ? BTA_GATT_OK : BTA_GATT_ERROR;
APPL_TRACE_DEBUG("%s() - read=%d, status=%d, err_code = %d",
__func__, num_attr, status, err_code);
bta_gattc_ci_cache_load(server_bda, evt, num_attr, attr, status, conn_id);
return status;
}
size_t bta_gattc_get_cache_attr_length(UINT8 index)
{
size_t length = 0;
if (index == INVALID_ADDR_NUM) {
return 0;
}
// Read the size of memory space required for blob
nvs_get_blob(cache_env.cache_addr[index].cache_fp, cache_key, NULL, &length);
return length;
}
/*******************************************************************************
@ -149,18 +254,26 @@ void bta_gattc_co_cache_load(BD_ADDR server_bda, UINT16 evt, UINT16 start_index,
** Returns
**
*******************************************************************************/
void bta_gattc_co_cache_save (BD_ADDR server_bda, UINT16 evt, UINT16 num_attr,
tBTA_GATTC_NV_ATTR *p_attr_list, UINT16 attr_index, UINT16 conn_id)
void bta_gattc_co_cache_save (BD_ADDR server_bda, UINT16 num_attr,
tBTA_GATTC_NV_ATTR *p_attr_list)
{
tBTA_GATT_STATUS status = BTA_GATT_OK;
UNUSED(attr_index);
#ifdef BT_SUPPORT_NVM
if (sCacheFD != 0) {
int num = fwrite(p_attr_list, sizeof(tBTA_GATTC_NV_ATTR), num_attr, sCacheFD);
BTIF_TRACE_DEBUG("%s() wrote %d", __FUNCTION__, num);
coap_key_t hash_key = {0};
UINT8 index = INVALID_ADDR_NUM;
//calculate the hash value of the attribute table which should be added to the nvs flash.
coap_hash_impl((unsigned char *)p_attr_list, sizeof(tBTA_GATTC_NV_ATTR)*num_attr, hash_key);
//save the address list to the nvs flash
bta_gattc_co_cache_addr_save(server_bda, hash_key);
if (cacheOpen(server_bda, TRUE, &index)) {
esp_err_t err_code = nvs_set_blob(cache_env.cache_addr[index].cache_fp, cache_key,
p_attr_list, sizeof(tBTA_GATTC_NV_ATTR)*num_attr);
status = (err_code == ESP_OK) ? BTA_GATT_OK : BTA_GATT_ERROR;
} else {
status = BTA_GATT_ERROR;
}
#endif /* BT_SUPPORT_NVM */
bta_gattc_ci_cache_save(server_bda, evt, status, conn_id);
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);
}
/*******************************************************************************
@ -178,11 +291,10 @@ void bta_gattc_co_cache_save (BD_ADDR server_bda, UINT16 evt, UINT16 num_attr,
*******************************************************************************/
void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id)
{
UNUSED(server_bda);
UNUSED(conn_id);
#ifdef BT_SUPPORT_NVM
cacheClose();
#endif /* BT_SUPPORT_NVM */
//#ifdef BT_SUPPORT_NVM
cacheClose(server_bda);
//#endif /* BT_SUPPORT_NVM */
/* close NV when server cache is done saving or loading,
does not need to do anything for now on Insight */
@ -203,10 +315,256 @@ void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id)
*******************************************************************************/
void bta_gattc_co_cache_reset(BD_ADDR server_bda)
{
BTIF_TRACE_DEBUG("%s()", __FUNCTION__);
#ifdef BT_SUPPORT_NVM
cacheReset(server_bda);
#endif /* BT_SUPPORT_NVM */
}
void bta_gattc_co_cache_addr_init(void)
{
nvs_handle fp;
esp_err_t err_code;
UINT8 num_addr;
UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
size_t length = 0;
if ((err_code = nvs_open(cache_addr, NVS_READWRITE, &fp)) == ESP_OK) {
cache_env.addr_fp = fp;
// Read previously saved blob if available
if ((err_code = nvs_get_blob(fp, cache_key, p_buf, &length)) != ESP_OK) {
APPL_TRACE_ERROR("%s, Line = %d, nvs flash get blob data fail, err_code = %x", __func__, __LINE__, err_code);
osi_free(p_buf);
return;
}
num_addr = length / (sizeof(BD_ADDR) + sizeof(coap_key_t));
cache_env.num_addr = num_addr;
//read the address from nvs flash to cache address list.
for (UINT8 i = 0; i < num_addr; i++) {
memcpy(cache_env.cache_addr[i].addr, p_buf + i*(sizeof(BD_ADDR) + sizeof(coap_key_t)), sizeof(BD_ADDR));
memcpy(cache_env.cache_addr[i].hash_key,
p_buf + i*(sizeof(BD_ADDR) + sizeof(coap_key_t)) + sizeof(BD_ADDR), sizeof(coap_key_t));
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],
cache_env.cache_addr[i].addr[3], cache_env.cache_addr[i].addr[4], cache_env.cache_addr[i].addr[5]);
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],
cache_env.cache_addr[i].hash_key[2], cache_env.cache_addr[i].hash_key[3]);
bta_gattc_co_cache_new_ass_list(cache_env.cache_addr[i].addr, i);
}
} else {
APPL_TRACE_ERROR("%s, Line = %d, nvs flash open fail, err_code = %x", __func__, __LINE__, err_code);
osi_free(p_buf);
return;
}
osi_free(p_buf);
return;
}
BOOLEAN bta_gattc_co_addr_in_cache(BD_ADDR bda)
{
UINT8 addr_index = 0;
UINT8 num = cache_env.num_addr;
cache_addr_info_t *addr_info = &cache_env.cache_addr[0];
for (addr_index = 0; addr_index < num; addr_index++) {
if (!memcmp(addr_info->addr, bda, sizeof(BD_ADDR))) {
return TRUE;
}
}
return FALSE;
}
UINT8 bta_gattc_co_find_addr_in_cache(BD_ADDR bda)
{
UINT8 addr_index = 0;
UINT8 num = cache_env.num_addr;
cache_addr_info_t *addr_info = &cache_env.cache_addr[0];
for (addr_index = 0; addr_index < num; addr_index++, addr_info++) {
if (!memcmp(addr_info->addr, bda, sizeof(BD_ADDR))) {
return addr_index;
}
}
return INVALID_ADDR_NUM;
}
UINT8 bta_gattc_co_find_hash_in_cache(coap_key_t hash_key)
{
UINT8 index = 0;
UINT8 num = cache_env.num_addr;
cache_addr_info_t *addr_info = &cache_env.cache_addr[0];
for (index = 0; index < num; index++) {
if (!memcmp(addr_info->hash_key, hash_key, sizeof(coap_key_t))) {
return index;
}
}
return INVALID_ADDR_NUM;
}
UINT8 bta_gattc_co_get_addr_num(void)
{
return cache_env.num_addr;
}
void bta_gattc_co_get_addr_list(BD_ADDR *addr_list)
{
UINT8 num = cache_env.num_addr;
for (UINT8 i = 0; i < num; i++) {
memcpy(addr_list[i], cache_env.cache_addr[i].addr, sizeof(BD_ADDR));
}
}
void bta_gattc_co_cache_addr_save(BD_ADDR bd_addr, coap_key_t hash_key)
{
esp_err_t err_code;
UINT8 num = ++cache_env.num_addr;
UINT8 index = 0;
UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF);
// check the address list has the same hash key or not
if (bta_gattc_co_find_hash_in_cache(hash_key) != INVALID_ADDR_NUM) {
APPL_TRACE_DEBUG("%s(), the hash key already in the cache list.", __func__);
if ((index = bta_gattc_co_find_addr_in_cache(bd_addr)) != INVALID_ADDR_NUM) {
APPL_TRACE_DEBUG("%s(), the hash bd_addr already in the cache list, index = %x", __func__, index);
//if the bd_addr already in the address list, update the hash key in it.
memcpy(cache_env.cache_addr[index].addr, bd_addr, sizeof(BD_ADDR));
memcpy(cache_env.cache_addr[index].hash_key, hash_key, sizeof(coap_key_t));
} else {
//if the bd_addr didn't in the address list, added the bd_addr to the last of the address list.
memcpy(cache_env.cache_addr[num - 1].hash_key, hash_key, sizeof(coap_key_t));
memcpy(cache_env.cache_addr[num - 1].addr, bd_addr, sizeof(BD_ADDR));
}
} else {
APPL_TRACE_DEBUG("%s(), num = %d", __func__, num);
memcpy(cache_env.cache_addr[num - 1].addr, bd_addr, sizeof(BD_ADDR));
memcpy(cache_env.cache_addr[num - 1].hash_key, hash_key, sizeof(coap_key_t));
}
nvs_handle *fp = &cache_env.addr_fp;
UINT16 length = num*(sizeof(BD_ADDR) + sizeof(coap_key_t));
for (UINT8 i = 0; i < num; i++) {
//copy the address to the buffer.
memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(coap_key_t)), cache_env.cache_addr[i].addr, sizeof(BD_ADDR));
//copy the hash key to the buffer.
memcpy(p_buf + i*(sizeof(BD_ADDR) + sizeof(coap_key_t)) + sizeof(BD_ADDR),
cache_env.cache_addr[i].hash_key, sizeof(coap_key_t));
}
if (cache_env.is_open) {
if ((err_code = nvs_set_blob(cache_env.addr_fp, cache_key, p_buf, length)) != ESP_OK) {
APPL_TRACE_WARNING("%s(), nvs set blob fail, err %d", __func__, err_code);
}
} else {
if ((err_code = nvs_open(cache_addr, NVS_READWRITE , fp)) == ESP_OK) {
cache_env.is_open = true;
if (( err_code = nvs_set_blob(cache_env.addr_fp, cache_key, p_buf, length)) != ESP_OK) {
APPL_TRACE_WARNING("%s(), nvs set blob fail, err %d", __func__, err_code);
}
} else {
APPL_TRACE_ERROR("%s, Line = %d, nvs flash open fail, err_code = %x", __func__, __LINE__, err_code);
}
}
//free the buffer after used.
osi_free(p_buf);
return;
}
BOOLEAN bta_gattc_co_cache_new_ass_list(BD_ADDR src_addr, UINT8 index)
{
cache_addr_info_t *addr_info = &cache_env.cache_addr[index];
addr_info->ass_addr = list_new(osi_free_func);
return (addr_info->ass_addr != NULL ? TRUE : FALSE);
}
BOOLEAN bta_gattc_co_cache_append_ass_addr(BD_ADDR src_addr, BD_ADDR ass_addr)
{
UINT8 addr_index = 0;
cache_addr_info_t *addr_info;
UINT8 *p_ass_buf = osi_malloc(sizeof(BD_ADDR));
memcpy(p_ass_buf, ass_addr, sizeof(BD_ADDR));
if ((addr_index = bta_gattc_co_find_addr_in_cache(src_addr)) != INVALID_ADDR_NUM) {
addr_info = &cache_env.cache_addr[addr_index];
if (addr_info->ass_addr == NULL) {
addr_info->ass_addr =list_new(NULL);
}
return list_append(addr_info->ass_addr, p_ass_buf);
}
return FALSE;
}
BOOLEAN bta_gattc_co_cache_remove_ass_addr(BD_ADDR src_addr, BD_ADDR ass_addr)
{
UINT8 addr_index = 0;
cache_addr_info_t *addr_info;
if ((addr_index = bta_gattc_co_find_addr_in_cache(src_addr)) != INVALID_ADDR_NUM) {
addr_info = &cache_env.cache_addr[addr_index];
if (addr_info->ass_addr != NULL) {
for (list_node_t *sn = list_begin(addr_info->ass_addr);
sn != list_end(addr_info->ass_addr); sn = list_next(sn)) {
void *addr = list_node(sn);
if (!memcmp(addr, ass_addr, sizeof(BD_ADDR))) {
return list_remove(addr_info->ass_addr, addr);
}
}
//return list_remove(addr_info->ass_addr, ass_addr);
} else {
return FALSE;
}
}
return FALSE;
}
UINT8* bta_gattc_co_cache_find_src_addr(BD_ADDR ass_addr, UINT8 *index)
{
UINT8 num = cache_env.num_addr;
cache_addr_info_t *addr_info = &cache_env.cache_addr[0];
UINT8 *addr_data;
//Check the ass_addr list is NULL or not
if (addr_info->ass_addr == NULL) {
*index = INVALID_ADDR_NUM;
return NULL;
}
for (int i = 0; i < num; i++) {
for (const list_node_t *node = list_begin(addr_info->ass_addr); node != list_end(addr_info->ass_addr);
node = list_next(node)) {
addr_data = (UINT8 *)list_node(node);
if (!memcmp(addr_data, ass_addr, sizeof(BD_ADDR))) {
*index = i;
return (UINT8 *)addr_info->addr;
}
}
addr_info++;
if (addr_info->ass_addr == NULL) {
*index = INVALID_ADDR_NUM;
return NULL;
}
}
*index = INVALID_ADDR_NUM;
return NULL;
}
BOOLEAN bta_gattc_co_cache_clear_ass_addr(BD_ADDR src_addr)
{
UINT8 addr_index = 0;
cache_addr_info_t *addr_info;
if ((addr_index = bta_gattc_co_find_addr_in_cache(src_addr)) != INVALID_ADDR_NUM) {
addr_info = &cache_env.cache_addr[addr_index];
if (addr_info->ass_addr != NULL) {
list_clear(addr_info->ass_addr);
} else {
return FALSE;
}
return TRUE;
}
return FALSE;
}
#endif /* #if( defined BLE_INCLUDED ) && (BLE_INCLUDED == TRUE) */