MYNEWT-397: Nimble controller assert if advertising started/stopped frequently
There was an assert in the advertising code in the nimble controller that would assert if the advertising state machine was not enabled and an advertising event finished. The code contained a race condition where it was possible that the advertising state machine was stopped but an advertising end event was processed by the Link Layer. The code will now ignore advertising packets that are processed after advertising has been stopped as these events are asynchronous to the controller. Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/1e523948 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/1e523948 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/1e523948 Branch: refs/heads/develop Commit: 1e5239485af3c056b9a053b60b778a30b2635e44 Parents: cc05bf2 Author: William San Filippo <[email protected]> Authored: Thu Sep 29 10:45:57 2016 -0700 Committer: William San Filippo <[email protected]> Committed: Fri Sep 30 15:42:33 2016 -0700 ---------------------------------------------------------------------- net/nimble/controller/src/ble_ll_adv.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1e523948/net/nimble/controller/src/ble_ll_adv.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_adv.c b/net/nimble/controller/src/ble_ll_adv.c index 3e2ce1f..24a8416 100644 --- a/net/nimble/controller/src/ble_ll_adv.c +++ b/net/nimble/controller/src/ble_ll_adv.c @@ -650,16 +650,18 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm) if (advsm->enabled) { /* Remove any scheduled advertising items */ ble_ll_sched_rmv_elem(&advsm->adv_sch); - os_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); /* Set to standby if we are no longer advertising */ OS_ENTER_CRITICAL(sr); if (ble_ll_state_get() == BLE_LL_STATE_ADV) { + ble_phy_disable(); ble_ll_wfr_disable(); ble_ll_state_set(BLE_LL_STATE_STANDBY); } OS_EXIT_CRITICAL(sr); + os_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); + /* If there is an event buf we need to free it */ if (advsm->conn_comp_ev) { ble_hci_trans_buf_free(advsm->conn_comp_ev); @@ -1161,6 +1163,15 @@ ble_ll_adv_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr) int adv_event_over; /* + * It is possible that advertising was stopped and a packet plcaed on the + * LL receive packet queue. In this case, just ignore the received packet + * as the advertising state machine is no longer "valid" + */ + if (!g_ble_ll_adv_sm.enabled) { + return; + } + + /* * If we have received a scan request and we are transmitting a response * or we have received a valid connect request, dont "end" the advertising * event. In the case of a connect request we will stop advertising. In
