mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-05 21:04:49 +00:00
fix(nimble): Handle not sending disconnect in slave role if connect was not sent
This commit is contained in:
@@ -292,6 +292,7 @@ static uint8_t pawr_adv_handle;
|
||||
static uint16_t pawr_sync_handle;
|
||||
#endif
|
||||
|
||||
int slave_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1];
|
||||
static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry);
|
||||
|
||||
#if NIMBLE_BLE_CONNECT
|
||||
@@ -1524,6 +1525,8 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason)
|
||||
struct ble_gap_update_entry *entry;
|
||||
struct ble_gap_snapshot snap;
|
||||
struct ble_gap_event event;
|
||||
struct ble_hs_conn *conn;
|
||||
bool send = 1;
|
||||
int rc;
|
||||
|
||||
memset(&event, 0, sizeof event);
|
||||
@@ -1560,6 +1563,19 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason)
|
||||
#endif
|
||||
ble_hs_flow_connection_broken(conn_handle);;
|
||||
|
||||
ble_hs_lock();
|
||||
conn = ble_hs_conn_find(conn_handle);
|
||||
ble_hs_unlock();
|
||||
|
||||
// Send disconnect event in slave role if connect was sent
|
||||
if ((conn != NULL) && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) {
|
||||
if (slave_conn[conn_handle]) {
|
||||
slave_conn[conn_handle] = 0;
|
||||
} else {
|
||||
send = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ble_hs_atomic_conn_delete(conn_handle);
|
||||
|
||||
g_max_tx_time[conn_handle] = 0;
|
||||
@@ -1570,8 +1586,10 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason)
|
||||
event.type = BLE_GAP_EVENT_DISCONNECT;
|
||||
event.disconnect.reason = reason;
|
||||
|
||||
ble_gap_event_listener_call(&event);
|
||||
ble_gap_call_event_cb(&event, snap.cb, snap.cb_arg);
|
||||
if (send) {
|
||||
ble_gap_event_listener_call(&event);
|
||||
ble_gap_call_event_cb(&event, snap.cb, snap.cb_arg);
|
||||
}
|
||||
|
||||
STATS_INC(ble_gap_stats, disconnect);
|
||||
#endif
|
||||
@@ -2740,16 +2758,16 @@ ble_gap_link_estab_call(uint16_t conn_handle, int status)
|
||||
event.link_estab.conn_handle = handle;
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES)
|
||||
event.link_estab.sync_handle = pawr_sync_handle;
|
||||
event.link_estab.adv_handle = pawr_adv_handle;
|
||||
event.link_estab.sync_handle = pawr_sync_handle;
|
||||
event.link_estab.adv_handle = pawr_adv_handle;
|
||||
#endif
|
||||
|
||||
ble_gap_event_listener_call(&event);
|
||||
ble_gap_call_conn_event_cb(&event, handle);
|
||||
ble_gap_event_listener_call(&event);
|
||||
ble_gap_call_conn_event_cb(&event, handle);
|
||||
|
||||
#if !SOC_ESP_NIMBLE_CONTROLLER
|
||||
ble_hs_hci_util_set_data_len(le16toh(conn_handle), BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MAX,
|
||||
BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX);
|
||||
ble_hs_hci_util_set_data_len(le16toh(conn_handle), BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MAX,
|
||||
BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2772,6 +2790,7 @@ ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used
|
||||
if ((conn != NULL) && (ev->status == 0)) {
|
||||
conn->supported_feat = get_le32(ev->features);
|
||||
ble_gap_link_estab_call(ev->conn_handle, ev->status);
|
||||
slave_conn[ev->conn_handle] = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,7 @@ struct ble_gap_reattempt_ctxt {
|
||||
|
||||
extern int ble_gap_master_connect_reattempt(uint16_t conn_handle);
|
||||
extern int ble_gap_slave_adv_reattempt(void);
|
||||
extern int slave_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1];
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK)
|
||||
@@ -247,58 +248,68 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data,
|
||||
ble_hs_unlock();
|
||||
|
||||
#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT)
|
||||
if (conn && ev->reason == BLE_ERR_CONN_ESTABLISHMENT) {
|
||||
if (conn) {
|
||||
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);
|
||||
/* For master role, check if failure reason is 0x3E, to restart connect attempt
|
||||
* For slave role, check whether
|
||||
* a. Failure reason is 0x3E
|
||||
* b. Connect event was not posted and 0x8 was received
|
||||
* Restart advertising in above reasons for slave.
|
||||
*/
|
||||
|
||||
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);
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
return 0; // Restart advertising, so don't post disconnect event
|
||||
|
||||
} else { // master
|
||||
if (reattempt_conn.count < MAX_REATTEMPT_ALLOWED) {
|
||||
/* Got for connection */
|
||||
if ((conn->bhc_flags & BLE_HS_CONN_F_MASTER) && \
|
||||
(ev->reason == BLE_ERR_CONN_ESTABLISHMENT)) { // master
|
||||
if (reattempt_conn.count < MAX_REATTEMPT_ALLOWED) {
|
||||
/* Go for connection */
|
||||
BLE_HS_LOG(INFO, "Reattempt connection; reason = 0x%x, status = %d,"
|
||||
"reattempt count = %d ", ev->reason, ev->status,
|
||||
reattempt_conn.count);
|
||||
"reattempt count = %d ", ev->reason, ev->status,
|
||||
reattempt_conn.count);
|
||||
reattempt_conn.count += 1;
|
||||
|
||||
handle = le16toh(ev->conn_handle);
|
||||
/* Post event to interested application */
|
||||
ble_gap_reattempt_count(handle, reattempt_conn.count);
|
||||
handle = le16toh(ev->conn_handle);
|
||||
/* Post event to interested application */
|
||||
ble_gap_reattempt_count(handle, reattempt_conn.count);
|
||||
|
||||
rc = ble_gap_master_connect_reattempt(ev->conn_handle);
|
||||
if (rc != 0) {
|
||||
BLE_HS_LOG(INFO, "Master reconnect attempt failed; rc = %d", rc);
|
||||
}
|
||||
} else {
|
||||
/* Exhausted attempts */
|
||||
memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt));
|
||||
if (rc != 0) {
|
||||
BLE_HS_LOG(INFO, "Master reconnect attempt failed; rc = %d", rc);
|
||||
}
|
||||
} else {
|
||||
/* Exhausted attempts */
|
||||
memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt));
|
||||
}
|
||||
}
|
||||
else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER) && \
|
||||
((ev->reason == BLE_ERR_CONN_ESTABLISHMENT) || \
|
||||
(!slave_conn[ev->conn_handle] && ev->reason == BLE_ERR_CONN_SPVN_TMO))) { //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);;
|
||||
#if MYNEWT_VAL(BLE_GATT_CACHING)
|
||||
ble_gattc_cache_conn_broken(ev->conn_handle);
|
||||
#endif
|
||||
rc = ble_hs_atomic_conn_delete(ev->conn_handle);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
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
|
||||
} else {
|
||||
/* Normal disconnect. Reset the structure */
|
||||
memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user