fix(nimble) Start advertising if disconnect due to 0x3E in slave

This commit is contained in:
Rahul Tank
2024-05-22 13:26:16 +05:30
parent 477c77d7c0
commit 5211a7b873
2 changed files with 160 additions and 20 deletions
+126
View File
@@ -123,6 +123,30 @@ struct ble_gap_connect_reattempt_ctxt {
ble_gap_event_fn *cb;
void *cb_arg;
}ble_conn_reattempt;
struct ble_gap_adv_reattempt_ctxt {
uint8_t type;
struct ble_hs_adv_fields fields;
uint8_t own_addr_type;
ble_addr_t direct_addr;
uint8_t direct_addr_present:1 ;
int32_t duration_ms;
struct ble_gap_adv_params adv_params;
#if MYNEWT_VAL(BLE_EXT_ADV)
uint8_t instance;
struct ble_gap_ext_adv_params params;
int8_t selected_tx_power;
uint8_t selected_tx_power_present:1;
struct os_mbuf *data;
int duration;
int max_events;
#endif
ble_gap_event_fn *cb;
void *cb_arg;
}ble_adv_reattempt;
#endif
/**
@@ -978,6 +1002,58 @@ void ble_gap_reattempt_count(uint16_t conn_handle, uint8_t count)
ble_gap_event_listener_call(&event);
ble_gap_call_conn_event_cb(&event, handle);
}
int ble_gap_slave_adv_reattempt(void)
{
int rc = 0;
switch (ble_adv_reattempt.type) {
case 0:
ble_gap_adv_stop();
rc = ble_gap_adv_set_fields(&ble_adv_reattempt.fields);
if (rc != 0) {
return rc;
}
rc = ble_gap_adv_start(ble_adv_reattempt.own_addr_type,
(ble_adv_reattempt.direct_addr_present == 1 ? &ble_adv_reattempt.direct_addr: NULL),
ble_adv_reattempt.duration_ms, &ble_adv_reattempt.adv_params,
ble_adv_reattempt.cb, ble_adv_reattempt.cb_arg);
if (rc != 0) {
return rc;
}
break;
case 1:
#if MYNEWT_VAL(BLE_EXT_ADV)
ble_gap_ext_adv_stop(ble_adv_reattempt.instance);
rc = ble_gap_ext_adv_configure(ble_adv_reattempt.instance, &ble_adv_reattempt.params,
(ble_adv_reattempt.selected_tx_power_present == 1 ? &ble_adv_reattempt.selected_tx_power : NULL),
ble_adv_reattempt.cb, ble_adv_reattempt.cb_arg);
if (rc != 0) {
return rc;
}
rc = ble_gap_ext_adv_set_data(ble_adv_reattempt.instance, ble_adv_reattempt.data);
if (rc != 0)
return rc;
rc = ble_gap_ext_adv_start(ble_adv_reattempt.instance, ble_adv_reattempt.duration,
ble_adv_reattempt.max_events);
if (rc != 0)
return rc;
#endif
break;
default:
break;
}
return rc;
}
#endif
#endif
@@ -2630,6 +2706,23 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr,
return BLE_HS_EDISABLED;
}
#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT)
ble_adv_reattempt.type = 0;
ble_adv_reattempt.own_addr_type = own_addr_type;
if (direct_addr) {
memcpy(&ble_adv_reattempt.direct_addr, direct_addr, sizeof(ble_addr_t));
ble_adv_reattempt.direct_addr_present = 1;
} else {
ble_adv_reattempt.direct_addr_present = 0;
}
ble_adv_reattempt.duration_ms = duration_ms;
memcpy(&ble_adv_reattempt.adv_params , adv_params, sizeof(struct ble_gap_adv_params));
ble_adv_reattempt.cb = cb;
ble_adv_reattempt.cb_arg = cb_arg;
#endif
ble_hs_lock();
rc = ble_gap_adv_validate(own_addr_type, direct_addr, adv_params);
@@ -2770,6 +2863,9 @@ ble_gap_adv_set_fields(const struct ble_hs_adv_fields *adv_fields)
if (!ble_hs_is_enabled()) {
return BLE_HS_EDISABLED;
}
#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT)
memcpy(&ble_adv_reattempt.fields, adv_fields, sizeof( struct ble_hs_adv_fields));
#endif
rc = ble_hs_adv_set_fields(adv_fields, buf, &buf_sz, sizeof buf);
if (rc != 0) {
@@ -2985,6 +3081,23 @@ ble_gap_ext_adv_configure(uint8_t instance,
return rc;
}
#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT)
ble_adv_reattempt.instance = instance;
memcpy(&ble_adv_reattempt.params, params, sizeof(struct ble_gap_ext_adv_params));
if (selected_tx_power) {
ble_adv_reattempt.selected_tx_power = *selected_tx_power;
ble_adv_reattempt.selected_tx_power_present = 1 ;
} else {
ble_adv_reattempt.selected_tx_power_present = 0 ;
}
ble_adv_reattempt.cb = cb;
ble_adv_reattempt.cb_arg = cb_arg;
#endif
ble_hs_lock();
if (ble_gap_adv_active_instance(instance)) {
@@ -3072,6 +3185,13 @@ ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events)
return BLE_HS_EDISABLED;
}
#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT)
ble_adv_reattempt.type = 1;
ble_adv_reattempt.instance = instance;
ble_adv_reattempt.duration = duration;
ble_adv_reattempt.max_events = max_events;
#endif
ble_hs_lock();
if (!ble_gap_slave[instance].configured) {
ble_hs_unlock();
@@ -3354,6 +3474,12 @@ ble_gap_ext_adv_set_data(uint8_t instance, struct os_mbuf *data)
goto done;
}
#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT)
ble_adv_reattempt.type = 1;
ble_adv_reattempt.instance = instance;
ble_adv_reattempt.data = data;
#endif
ble_hs_lock();
rc = ble_gap_ext_adv_set_data_validate(instance, data);
if (rc != 0) {
+34 -20
View File
@@ -35,6 +35,7 @@ struct ble_gap_reattempt_ctxt {
}reattempt_conn;
extern int ble_gap_master_connect_reattempt(uint16_t conn_handle);
extern int ble_gap_slave_adv_reattempt(void);
#ifdef CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT
#define MAX_REATTEMPT_ALLOWED CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT
@@ -185,30 +186,43 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data,
if (conn && ev->reason == BLE_ERR_CONN_ESTABLISHMENT) {
uint16_t handle;
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.count);
if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) {
reattempt_conn.count += 1;
handle = le16toh(ev->conn_handle);
/* Post event to interested application */
ble_gap_reattempt_count(handle, reattempt_conn.count);
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);
rc = ble_gap_master_connect_reattempt(ev->conn_handle);
if (rc != 0) {
BLE_HS_LOG(INFO, "Master reconnect attempt 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
} 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);
/* 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));
} else {
/* 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));
}
else {
/* Normal disconnect. Reset the structure */
memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt));
}
#endif