From edb20db9c700ccc65b73fe41ac0924693f0eb74f Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Fri, 29 Mar 2024 21:15:29 +0530 Subject: [PATCH] nimble: Simplify the connection reconnection method --- nimble/host/src/ble_gap.c | 123 ++++++++----------------------- nimble/host/src/ble_hs_hci_evt.c | 98 ++++++++---------------- 2 files changed, 62 insertions(+), 159 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index ec0e5276e..7ad0e8740 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -122,13 +122,7 @@ struct ble_gap_connect_reattempt_ctxt { struct ble_gap_conn_params conn_params; ble_gap_event_fn *cb; void *cb_arg; -}; - -static struct ble_gap_connect_reattempt_ctxt ble_conn_reattempt[MYNEWT_VAL(BLE_MAX_CONNECTIONS)]; -#if MYNEWT_VAL(BLE_ROLE_CENTRAL) -static uint16_t reattempt_idx; -#endif -static bool conn_cookie_enabled; +}ble_conn_reattempt; #endif @@ -958,27 +952,12 @@ ble_gap_master_connect_cancelled(void) static void ble_gap_update_notify(uint16_t conn_handle, int status); -static int -ble_gap_find_retry_conn_param(const struct ble_gap_conn_desc *conn_desc) -{ - int i; - - for(i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { - if (memcmp(&ble_conn_reattempt[i].peer_addr, &conn_desc->peer_ota_addr, sizeof(ble_addr_t)) == 0) { - return i; - } - } - /* No matching entry found. Return invalid index */ - return MYNEWT_VAL(BLE_MAX_CONNECTIONS); -} - int -ble_gap_master_connect_reattempt(uint16_t conn_handle) +ble_gap_master_connect_reattempt(uint16_t conn_handle, ble_addr_t *peer_addr) { struct ble_gap_snapshot snap; struct ble_gap_conn_desc conn; struct ble_gap_update_entry *entry; - int idx; int rc = BLE_HS_EUNKNOWN; snap.desc = &conn; @@ -988,14 +967,6 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle) } if (conn.role == BLE_GAP_ROLE_MASTER) { - idx = ble_gap_find_retry_conn_param(&conn); - if (idx >= MYNEWT_VAL(BLE_MAX_CONNECTIONS)) { - return BLE_HS_EINVAL; - } - - /* XXX Connection state in host needs to be removed and cleaned - * up to validate the connection when re-attempting. */ - /* If there was a connection update in progress, indicate to the * application that it did not complete. */ @@ -1019,14 +990,11 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle) return rc; } - /* Utilize cookie to get the index updated correctly for re-attempt */ - conn_cookie_enabled = true; - - rc = ble_gap_connect(ble_conn_reattempt[idx].own_addr_type, - &ble_conn_reattempt[idx].peer_addr, - ble_conn_reattempt[idx].duration_ms, - &ble_conn_reattempt[idx].conn_params, - ble_conn_reattempt[idx].cb, + rc = ble_gap_connect(ble_conn_reattempt.own_addr_type, + peer_addr, + ble_conn_reattempt.duration_ms, + &ble_conn_reattempt.conn_params, + ble_conn_reattempt.cb, &conn); if (rc != 0) { return rc; @@ -1048,6 +1016,7 @@ void ble_gap_reattempt_count(uint16_t conn_handle, uint8_t count) event.reattempt_cnt.count = count; event.reattempt_cnt.conn_handle = le16toh(conn_handle); + ble_gap_event_listener_call(&event); ble_gap_call_conn_event_cb(&event, handle); } #endif @@ -5422,51 +5391,36 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, ble_gap_master.op = BLE_GAP_OP_M_CONN; #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) - /* ble_gap_connect_reattempt save the connection parameters */ - if ((cb_arg != NULL) && conn_cookie_enabled) { - struct ble_gap_conn_desc *conn_desc = cb_arg; - struct ble_gap_conn_desc *curr_conn_desc=NULL; - /* reattempt_idx is set to that index where corresponding conn_handle entry was made */ - for (int i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { - curr_conn_desc = ble_conn_reattempt[i].cb_arg; - if (curr_conn_desc && (conn_desc->conn_handle == curr_conn_desc->conn_handle)) { - reattempt_idx = i; - break; - } - } - /* Reset cookie_enabled flag, it will be set again by reattempt call */ - conn_cookie_enabled = false; + ble_conn_reattempt.own_addr_type = own_addr_type; + + if (peer_addr != NULL) { + memcpy(&ble_conn_reattempt.peer_addr, peer_addr, sizeof(ble_addr_t)); + } else { + memset(&ble_conn_reattempt.peer_addr, 0, sizeof(ble_addr_t)); } - ble_conn_reattempt[reattempt_idx].own_addr_type = own_addr_type; - memcpy(&ble_conn_reattempt[reattempt_idx].peer_addr, peer_addr, - sizeof(ble_addr_t)); - ble_conn_reattempt[reattempt_idx].duration_ms = duration_ms; + ble_conn_reattempt.duration_ms = duration_ms; if (phy_mask & BLE_GAP_LE_PHY_1M_MASK) { - memcpy(&ble_conn_reattempt[reattempt_idx].conn_params, + memcpy(&ble_conn_reattempt.conn_params, phy_1m_conn_params, sizeof(struct ble_gap_conn_params)); } if (phy_mask & BLE_GAP_LE_PHY_2M_MASK) { - memcpy(&ble_conn_reattempt[reattempt_idx].conn_params, + memcpy(&ble_conn_reattempt.conn_params, phy_2m_conn_params, sizeof(struct ble_gap_conn_params)); } if (phy_mask & BLE_GAP_LE_PHY_CODED_MASK) { - memcpy(&ble_conn_reattempt[reattempt_idx].conn_params, + memcpy(&ble_conn_reattempt.conn_params, phy_coded_conn_params, sizeof(struct ble_gap_conn_params)); } - ble_conn_reattempt[reattempt_idx].cb = cb; - ble_conn_reattempt[reattempt_idx].cb_arg = cb_arg; - /* reattempt_idx need to be within limits. This may end up being unnecessary - * operation. However, it is better to be sure as it can get tricky with - * multiple connections and client + server roles XXX*/ - reattempt_idx = (reattempt_idx + 1) % MYNEWT_VAL(BLE_MAX_CONNECTIONS); + ble_conn_reattempt.cb = cb; + ble_conn_reattempt.cb_arg = cb_arg; #endif @@ -5616,36 +5570,21 @@ ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, #endif #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) - /* ble_gap_connect_reattempt save the connection parameters */ - if ((cb_arg != NULL) && conn_cookie_enabled) { - struct ble_gap_conn_desc *conn_desc = cb_arg; - struct ble_gap_conn_desc *curr_conn_desc=NULL; - /* reattempt_idx is set to that index where corresponding conn_handle entry was made */ - for (int i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { - curr_conn_desc = ble_conn_reattempt[i].cb_arg; - if (curr_conn_desc && (conn_desc->conn_handle == curr_conn_desc->conn_handle)) { - reattempt_idx = i; - break; - } - } - /* Reset cookie_enabled flag, it will be set again by reattempt call */ - conn_cookie_enabled = false; + ble_conn_reattempt.own_addr_type = own_addr_type; + if (peer_addr != NULL) { + memcpy(&ble_conn_reattempt.peer_addr, &bhc_peer_addr, + sizeof(ble_addr_t)); + } else { + memset(&ble_conn_reattempt.peer_addr, 0, + sizeof(ble_addr_t)); } - - ble_conn_reattempt[reattempt_idx].own_addr_type = own_addr_type; - memcpy(&ble_conn_reattempt[reattempt_idx].peer_addr, &bhc_peer_addr, - sizeof(ble_addr_t)); - ble_conn_reattempt[reattempt_idx].duration_ms = duration_ms; - memcpy(&ble_conn_reattempt[reattempt_idx].conn_params, + ble_conn_reattempt.duration_ms = duration_ms; + memcpy(&ble_conn_reattempt.conn_params, conn_params, sizeof(struct ble_gap_conn_params)); - ble_conn_reattempt[reattempt_idx].cb = cb; - ble_conn_reattempt[reattempt_idx].cb_arg = cb_arg; + ble_conn_reattempt.cb = cb; + ble_conn_reattempt.cb_arg = cb_arg; - /* reattempt_idx need to be within limits. This may end up being unnecessary - * operation. However, it is better to be sure as it can get tricky with - * multiple connections and client + server roles XXX*/ - reattempt_idx = (reattempt_idx + 1) % MYNEWT_VAL(BLE_MAX_CONNECTIONS); #endif rc = ble_gap_conn_create_tx(own_addr_type, &bhc_peer_addr, diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index f41fc03bb..432298121 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -33,10 +33,9 @@ struct ble_gap_reattempt_ctxt { ble_addr_t peer_addr; uint8_t count; -}; +}reattempt_conn; -static struct ble_gap_reattempt_ctxt reattempt_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS)]; -extern int ble_gap_master_connect_reattempt(uint16_t conn_handle); +extern int ble_gap_master_connect_reattempt(uint16_t conn_handle, ble_addr_t *peer_addr); #ifdef CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT #define MAX_REATTEMPT_ALLOWED CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT @@ -198,22 +197,6 @@ ble_hs_hci_evt_le_dispatch_find(uint8_t event_code) return ble_hs_hci_evt_le_dispatch[event_code]; } -#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) -static int -ble_gap_find_reattempt_conn_idx(const struct ble_hs_conn *conn) -{ - int i; - - for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { - if (memcmp(&reattempt_conn[i].peer_addr, &conn->bhc_peer_addr, sizeof(ble_addr_t)) == 0) { - return i; - } - } - /* No matching entry found. Return invalid index */ - return MYNEWT_VAL(BLE_MAX_CONNECTIONS); -} -#endif - #if NIMBLE_BLE_CONNECT static int ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, @@ -234,68 +217,49 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, ble_hs_unlock(); #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) - if (ev->reason == BLE_ERR_CONN_ESTABLISHMENT) { - int rc, i, idx; + if (conn && ev->reason == BLE_ERR_CONN_ESTABLISHMENT) { uint16_t handle; - - idx = ble_gap_find_reattempt_conn_idx(conn); - - if (idx == MYNEWT_VAL(BLE_MAX_CONNECTIONS)) { - /* This means, no matching addr exists in databse. So create a new one */ - for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { - if (reattempt_conn[i].count == 0) { - idx = i; - break; - } - } - } - - if (idx == MYNEWT_VAL(BLE_MAX_CONNECTIONS)) { - BLE_HS_LOG(DEBUG, "No space left in array "); - - for (i = 0; i < idx; i++) { - memset(&reattempt_conn[i], 0x0, sizeof(struct ble_gap_reattempt_ctxt)); - } - goto done; - } - - if (conn != NULL) { - BLE_HS_LOG(DEBUG, "Reattempt connection; reason = 0x%x, status = %d," + int rc; + if (reattempt_conn.count < MAX_REATTEMPT_ALLOWED ) { + /* Got for connection */ + BLE_HS_LOG(INFO, "Reattempt connection; reason = 0x%x, status = %d," "reattempt count = %d ", ev->reason, ev->status, - reattempt_conn[idx].count); + reattempt_conn.count); if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) { - if (reattempt_conn[idx].count < MAX_REATTEMPT_ALLOWED) { - reattempt_conn[idx].count += 1; + reattempt_conn.count += 1; - for (i = 0; i < BLE_DEV_ADDR_LEN; i++) { - reattempt_conn[idx].peer_addr.val[i] = conn->bhc_peer_addr.val[i]; + + switch (conn->bhc_peer_addr.type) { + case BLE_ADDR_PUBLIC: + case BLE_ADDR_RANDOM: + memcpy(&reattempt_conn.peer_addr, &conn->bhc_peer_addr, sizeof(ble_addr_t)); + reattempt_conn.peer_addr.type = conn->bhc_peer_addr.type; + break; + + case BLE_ADDR_PUBLIC_ID: + case BLE_ADDR_RANDOM_ID: + memcpy(&reattempt_conn.peer_addr, &conn->bhc_peer_rpa_addr, sizeof(ble_addr_t)); + reattempt_conn.peer_addr.type = conn->bhc_peer_rpa_addr.type; + break; } - reattempt_conn[idx].peer_addr.type = conn->bhc_peer_addr.type; - handle = le16toh(ev->conn_handle); /* Post event to interested application */ - ble_gap_reattempt_count(handle, reattempt_conn[idx].count); + ble_gap_reattempt_count(handle, reattempt_conn.count); - rc = ble_gap_master_connect_reattempt(ev->conn_handle); + rc = ble_gap_master_connect_reattempt(ev->conn_handle , &reattempt_conn.peer_addr ); if (rc != 0) { - BLE_HS_LOG(DEBUG, "Master reconnect attempt failed; rc = %d", rc); + BLE_HS_LOG(INFO, "Master reconnect attempt failed; rc = %d", rc); } - } else { - memset(&reattempt_conn[idx].peer_addr, 0x0, BLE_DEV_ADDR_LEN); - reattempt_conn[idx].count = 0; } - } } else { - /* Disconnect completed with some other reason than - * BLE_ERR_CONN_ESTABLISHMENT, reset the corresponding reattempt count - * */ - memset(&reattempt_conn[idx].peer_addr, 0x0, BLE_DEV_ADDR_LEN); - reattempt_conn[idx].count = 0; - } + /* Exhausted attempts */ + memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); + } + } else { + /* Normal disconnect. Reset the structure */ + memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); } -done: - #endif ble_gap_rx_disconn_complete(ev);