From 121739fe788a6d73891a5871322e3c08e642aec2 Mon Sep 17 00:00:00 2001 From: ShenWeilong Date: Fri, 2 Aug 2024 21:41:54 +0800 Subject: [PATCH] fix(ble): fixed the nimble connection reattempt issue when the OPTIMIZE_MULTI_CONN is enabled --- nimble/host/src/ble_gap.c | 42 +++++++++++++++++++---- nimble/host/src/ble_hs_hci_evt.c | 59 ++++++++++++++++---------------- 2 files changed, 64 insertions(+), 37 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index c5b0f8e8b..082449071 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -127,9 +127,14 @@ struct ble_gap_connect_reattempt_ctxt { ble_addr_t peer_addr; uint8_t peer_addr_present:1; int32_t duration_ms; - struct ble_gap_conn_params conn_params; + struct ble_gap_conn_params conn_params_1m; ble_gap_event_fn *cb; void *cb_arg; +#if MYNEWT_VAL(BLE_EXT_ADV) + uint8_t phy_mask; + struct ble_gap_conn_params conn_params_2m; + struct ble_gap_conn_params conn_params_coded; +#endif // MYNEWT_VAL(BLE_EXT_ADV) }ble_conn_reattempt; struct ble_gap_adv_reattempt_ctxt { @@ -1133,12 +1138,33 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle) return rc; } +#if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) + /* This reattempt will be done automatically. The `scheduling_len` maybe set in the ble_gap_multi_connect(). */ + ble_gap_multi_conn.scheduling_len_set = true; +#endif // MYNEWT_VAL(OPTIMIZE_MULTI_CONN) + +#if MYNEWT_VAL(BLE_EXT_ADV) + rc = ble_gap_ext_connect(ble_conn_reattempt.own_addr_type, + (ble_conn_reattempt.peer_addr_present == 1 ? &ble_conn_reattempt.peer_addr : NULL), + ble_conn_reattempt.duration_ms, ble_conn_reattempt.phy_mask, + ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_1M_MASK ? &ble_conn_reattempt.conn_params_1m : NULL, + ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_2M_MASK ? &ble_conn_reattempt.conn_params_2m : NULL, + ble_conn_reattempt.phy_mask & BLE_GAP_LE_PHY_CODED_MASK ? &ble_conn_reattempt.conn_params_coded : NULL, + ble_conn_reattempt.cb, + ble_conn_reattempt.cb_arg); +#else rc = ble_gap_connect(ble_conn_reattempt.own_addr_type, (ble_conn_reattempt.peer_addr_present == 1 ? &ble_conn_reattempt.peer_addr : NULL), ble_conn_reattempt.duration_ms, - &ble_conn_reattempt.conn_params, + &ble_conn_reattempt.conn_params_1m, ble_conn_reattempt.cb, ble_conn_reattempt.cb_arg); +#endif // #if MYNEWT_VAL(BLE_EXT_ADV) + +#if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) + ble_gap_multi_conn.scheduling_len_set = false; +#endif // MYNEWT_VAL(OPTIMIZE_MULTI_CONN) + if (rc != 0) { return rc; } @@ -6302,21 +6328,22 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, } ble_conn_reattempt.duration_ms = duration_ms; + ble_conn_reattempt.phy_mask = phy_mask; if (phy_mask & BLE_GAP_LE_PHY_1M_MASK) { - memcpy(&ble_conn_reattempt.conn_params, + memcpy(&ble_conn_reattempt.conn_params_1m, phy_1m_conn_params, sizeof(struct ble_gap_conn_params)); } if (phy_mask & BLE_GAP_LE_PHY_2M_MASK) { - memcpy(&ble_conn_reattempt.conn_params, + memcpy(&ble_conn_reattempt.conn_params_2m, phy_2m_conn_params, sizeof(struct ble_gap_conn_params)); } if (phy_mask & BLE_GAP_LE_PHY_CODED_MASK) { - memcpy(&ble_conn_reattempt.conn_params, + memcpy(&ble_conn_reattempt.conn_params_coded, phy_coded_conn_params, sizeof(struct ble_gap_conn_params)); } @@ -6494,7 +6521,7 @@ ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, } ble_conn_reattempt.duration_ms = duration_ms; - memcpy(&ble_conn_reattempt.conn_params, + memcpy(&ble_conn_reattempt.conn_params_1m, conn_params, sizeof(struct ble_gap_conn_params)); ble_conn_reattempt.cb = cb; @@ -6610,6 +6637,7 @@ ble_gap_multi_connect(struct ble_gap_multi_conn_params *multi_conn_params, #endif // MYNEWT_VAL(BLE_EXT_ADV) scheduling_len_us = multi_conn_params->scheduling_len_us; + /* `scheduling_len_us == 0` is allowed. It indicates that the optimization for this connection * is disabled. The connection interval must be an integer multiple of `common factor`. Note * that the unit of the connection interval is 1.25ms, while the common factor's unit is 0.625ms. @@ -6668,7 +6696,7 @@ ble_gap_multi_connect(struct ble_gap_multi_conn_params *multi_conn_params, multi_conn_params->phy_2m_conn_params, multi_conn_params->phy_coded_conn_params, cb, cb_arg); #else - rc = ble_gap_ext_connect(multi_conn_params->own_addr_type, multi_conn_params->peer_addr, + rc = ble_gap_connect(multi_conn_params->own_addr_type, multi_conn_params->peer_addr, multi_conn_params->duration_ms, multi_conn_params->phy_1m_conn_params, cb, cb_arg); #endif // MYNEWT_VAL(BLE_EXT_ADV) diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 16d76e649..40522f663 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -243,38 +243,38 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) if (conn && ev->reason == BLE_ERR_CONN_ESTABLISHMENT) { uint16_t handle; - int rc; + int rc; - if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { //slave - BLE_HS_LOG(INFO, "Reattempt advertising; reason: 0x%x, status = %x", - ev->reason, ev->status); + if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { //slave + BLE_HS_LOG(INFO, "Reattempt advertising; reason: 0x%x, status = %x", + ev->reason, ev->status); - ble_l2cap_sig_conn_broken(ev->conn_handle, BLE_ERR_CONN_ESTABLISHMENT); - ble_sm_connection_broken(ev->conn_handle); - ble_gatts_connection_broken(ev->conn_handle); - ble_gattc_connection_broken(ev->conn_handle); - ble_hs_flow_connection_broken(ev->conn_handle);; + ble_l2cap_sig_conn_broken(ev->conn_handle, BLE_ERR_CONN_ESTABLISHMENT); + ble_sm_connection_broken(ev->conn_handle); + ble_gatts_connection_broken(ev->conn_handle); + ble_gattc_connection_broken(ev->conn_handle); + ble_hs_flow_connection_broken(ev->conn_handle);; #if MYNEWT_VAL(BLE_GATT_CACHING) - ble_gattc_cache_conn_broken(ev->conn_handle); + ble_gattc_cache_conn_broken(ev->conn_handle); #endif - rc = ble_hs_atomic_conn_delete(ev->conn_handle); - if (rc != 0) { - return rc; - } + rc = ble_hs_atomic_conn_delete(ev->conn_handle); + if (rc != 0) { + return rc; + } - rc = ble_gap_slave_adv_reattempt(); - if (rc != 0) { - BLE_HS_LOG(INFO, "Adv reattempt failed; rc= %d ", rc); - } + rc = ble_gap_slave_adv_reattempt(); + if (rc != 0) { + BLE_HS_LOG(INFO, "Adv reattempt failed; rc= %d ", rc); + } - return 0; // Restart advertising, so don't post disconnect event + return 0; // Restart advertising, so don't post disconnect event - } else { // master - 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.count); + } else { // master + 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.count); reattempt_conn.count += 1; handle = le16toh(ev->conn_handle); @@ -285,13 +285,12 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, if (rc != 0) { BLE_HS_LOG(INFO, "Master reconnect attempt failed; rc = %d", rc); } - } else { + } else { /* Exhausted attempts */ memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); - } - } - } - else { + } + } + } else { /* Normal disconnect. Reset the structure */ memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); }