From d1aea09e9dfb6b8acd1f256ed95f1bdd1229ebff Mon Sep 17 00:00:00 2001 From: Sumeet Singh Date: Tue, 29 Oct 2024 17:23:11 +0530 Subject: [PATCH] fix(nimble): Fixed bugs related to robust caching --- nimble/host/src/ble_att_svr.c | 60 +++++++++++++++++++++++++++++---- nimble/host/src/ble_gatt_priv.h | 2 ++ nimble/host/src/ble_gatts.c | 12 ++++++- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index f9f688f00..b7733eda4 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -1310,20 +1310,38 @@ static void ble_att_svr_make_conn_aware(uint16_t conn_handle) { int i = 0; conn = ble_hs_conn_find_assert(conn_handle); - conn->bhc_gatt_svr.aware_state = true; + conn->bhc_gatt_svr.aware_state = false; + conn->bhc_gatt_svr.half_aware = 1; ble_hs_conn_addrs(conn, &addrs); for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { - ble_gatts_conn_aware_states[i].aware = true; + ble_gatts_conn_aware_states[i].aware = false; + ble_gatts_conn_aware_states[i].half_aware = 1; } } } static bool ble_att_svr_check_conn_aware(uint16_t conn_handle) { struct ble_hs_conn *conn; + struct ble_hs_conn_addrs addrs; + conn = ble_hs_conn_find_assert(conn_handle); + + if (conn->bhc_gatt_svr.half_aware == 1) { + conn->bhc_gatt_svr.half_aware = 0; + conn->bhc_gatt_svr.aware_state = true; + + ble_hs_conn_addrs(conn, &addrs); + for(int i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { + if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, + addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { + ble_gatts_conn_aware_states[i].half_aware = 0; + ble_gatts_conn_aware_states[i].aware = true; + } + } + } return conn->bhc_gatt_svr.aware_state; } @@ -1458,6 +1476,8 @@ ble_att_svr_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rx struct ble_att_read_type_req *req; uint16_t start_handle, end_handle; + struct ble_hs_conn *conn; + struct ble_hs_conn_addrs addrs; struct os_mbuf *txom; uint16_t err_handle; uint16_t pktlen; @@ -1504,12 +1524,40 @@ ble_att_svr_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rx #if MYNEWT_VAL(BLE_GATT_CACHING) ble_hs_lock(); - ble_att_svr_make_conn_aware(conn_handle); - ble_hs_unlock(); + if(start_handle == 0x0001 && end_handle == 0xFFFF && uuid.u.type == BLE_UUID_TYPE_16 && + (uuid.u16.value == BLE_ATT_UUID_INCLUDE || uuid.u16.value == BLE_ATT_UUID_CHARACTERISTIC) + ) { + int i = 0; - if(rc != 0) { - goto done; + conn = ble_hs_conn_find_assert(conn_handle); + conn->bhc_gatt_svr.aware_state = true; + conn->bhc_gatt_svr.half_aware = 0; + + ble_hs_conn_addrs(conn, &addrs); + for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { + if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, + addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { + ble_gatts_conn_aware_states[i].aware = true; + ble_gatts_conn_aware_states[i].half_aware = 0; + } + } + } else if (uuid.u.type == BLE_UUID_TYPE_16 && uuid.u16.value == BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16) { + if (!ble_att_svr_check_conn_aware(conn_handle)) { + ble_att_svr_make_conn_aware(conn_handle); + } + } else { + if((ble_att_svr_get_csfs(conn_handle)[0] & 1) + && ble_svc_gatt_csf_handle() != err_handle ) { + if (!ble_att_svr_check_conn_aware(conn_handle)) { + att_err = BLE_ATT_ERR_DB_OUT_OF_SYNC; + rc = BLE_HS_EREJECT; + ble_att_svr_make_conn_aware(conn_handle); + ble_hs_unlock(); + goto done; + } + } } + ble_hs_unlock(); #endif rc = ble_att_svr_build_read_type_rsp(conn_handle, cid, start_handle, end_handle, &uuid.u, rxom, &txom, &att_err, diff --git a/nimble/host/src/ble_gatt_priv.h b/nimble/host/src/ble_gatt_priv.h index a8326648d..eda5b85e6 100644 --- a/nimble/host/src/ble_gatt_priv.h +++ b/nimble/host/src/ble_gatt_priv.h @@ -109,6 +109,7 @@ struct ble_gatts_conn { int num_clt_cfgs; #if MYNEWT_VAL(BLE_GATT_CACHING) bool aware_state; + uint8_t half_aware:1; bool sent_err; #endif @@ -229,6 +230,7 @@ void ble_gatts_set_clt_cfg_perm_flags(uint8_t flags); struct ble_gatts_aware_state { uint8_t peer_id_addr[6]; bool aware; + uint8_t half_aware:1; }; extern struct ble_gatts_aware_state ble_gatts_conn_aware_states[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; #endif diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index ace4a2497..a2b93e0e1 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -1515,7 +1515,13 @@ ble_gatts_connection_broken(uint16_t conn_handle) for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { - ble_gatts_conn_aware_states[i].aware = conn->bhc_gatt_svr.aware_state; + if(conn->bhc_gatt_svr.half_aware) { + ble_gatts_conn_aware_states[i].aware = false; + ble_gatts_conn_aware_states[i].half_aware = 0; + } else { + ble_gatts_conn_aware_states[i].aware = conn->bhc_gatt_svr.aware_state; + ble_gatts_conn_aware_states[i].half_aware = conn->bhc_gatt_svr.half_aware; + } } } } @@ -2490,6 +2496,7 @@ ble_gatts_bonding_restored(uint16_t conn_handle) for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { if(memcmp(ble_gatts_conn_aware_states[i].peer_id_addr, addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val)) { + conn->bhc_gatt_svr.half_aware = ble_gatts_conn_aware_states[i].half_aware; conn->bhc_gatt_svr.aware_state = ble_gatts_conn_aware_states[i].aware; } } @@ -2774,6 +2781,7 @@ static void ble_gatts_remove_clt_cfg(struct ble_gatts_clt_cfg_list *clt_cfgs, ui static int ble_gatts_conn_unaware(struct ble_hs_conn *conn, void *arg) { conn->bhc_gatt_svr.aware_state = false; + conn->bhc_gatt_svr.half_aware = 0; return 0; } #endif @@ -2873,6 +2881,7 @@ int ble_gatts_add_dynamic_svcs(const struct ble_gatt_svc_def *svcs) { #if MYNEWT_VAL(BLE_GATT_CACHING) /* make all bonded connections unaware */ for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { + ble_gatts_conn_aware_states[i].half_aware = 0; ble_gatts_conn_aware_states[i].aware = false; } ble_hs_conn_foreach(ble_gatts_conn_unaware, NULL); @@ -2974,6 +2983,7 @@ done: /* make all bonded connections them unaware */ for(i = 0; i < MYNEWT_VAL(BLE_STORE_MAX_BONDS); i++) { ble_gatts_conn_aware_states[i].aware = false; + ble_gatts_conn_aware_states[i].half_aware = 0; } ble_hs_conn_foreach(ble_gatts_conn_unaware, NULL); #endif