From 4bb1e1d25a5f9d1cc5ad24a28327bbe26c4b91e0 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 13 Jun 2017 17:36:15 +0200 Subject: [PATCH] nimble/controller: Add support for sending Set Terminated event Currently this is done only for connection complete. X-Original-Commit: e2eb1a0fdd7948b854ad4c341d3cad0f94ede25a --- .../include/controller/ble_ll_ctrl.h | 2 + nimble/controller/src/ble_ll_adv.c | 40 ++++++++++++++++++- nimble/controller/src/ble_ll_hci_ev.c | 25 ++++++++++++ nimble/include/nimble/ble.h | 3 ++ nimble/include/nimble/hci_common.h | 3 ++ 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 8f1618996..3a9a8c7b7 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -272,6 +272,8 @@ void ble_ll_hci_ev_databuf_overflow(void); void ble_ll_hci_ev_le_csa(struct ble_ll_conn_sm *connsm); void ble_ll_hci_ev_send_scan_req_recv(uint8_t adv_handle, const uint8_t *peer, uint8_t peer_addr_type); +void ble_ll_hci_ev_send_adv_set_terminated(uint8_t status, uint8_t adv_handle, + uint16_t conn_handle, uint8_t events); int ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status); void ble_ll_calc_session_key(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 4e78ca320..ce2fed8bb 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -110,7 +110,8 @@ struct ble_ll_adv_sm uint8_t adv_random_addr[BLE_DEV_ADDR_LEN]; uint16_t duration; /* TODO */ - uint8_t events; /* TODO */ + uint8_t events_max; + uint8_t events; uint16_t did; /* TODO */ uint8_t pri_phy; /* TODO */ uint8_t sec_phy; /* TODO */ @@ -1459,7 +1460,8 @@ ble_ll_adv_set_enable(uint8_t instance, uint8_t enable, uint16_t duration, rc = BLE_ERR_SUCCESS; if (enable == 1) { advsm->duration = duration; - advsm->events = events; + advsm->events_max = events; + advsm->events = 0; /* If already enabled, do nothing */ if (!advsm->adv_enabled) { @@ -2500,6 +2502,16 @@ ble_ll_adv_secondary_done(struct ble_ll_adv_sm *advsm) /* Check if we need to resume scanning */ ble_ll_scan_chk_resume(); + if (advsm->events_max && (advsm->events >= advsm->events_max)) { + ble_ll_hci_ev_send_adv_set_terminated(BLE_RR_LIMIT_REACHED, + advsm->adv_instance, 0, + advsm->events); + /* Disable advertising */ + advsm->adv_enabled = 0; + ble_ll_scan_chk_resume(); + return; + } + /* TODO calculate this 5000 based on ext_adv sched time and channel used */ advsm->adv_secondary_start_time = advsm->adv_pdu_start_time + os_cputime_usecs_to_ticks(5000) + @@ -2566,6 +2578,10 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) final_adv_chan = ble_ll_adv_final_chan(advsm); if (advsm->adv_chan == final_adv_chan) { + if (advsm->events_max) { + advsm->events++; + } + /* Check if we need to resume scanning */ ble_ll_scan_chk_resume(); @@ -2648,6 +2664,23 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) } } + if (advsm->events_max && (advsm->events >= advsm->events_max)) { + /* Legacy PDUs need to be stop here, for ext adv it will be stopped when + * AUX is done. + */ + if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) { + ble_ll_hci_ev_send_adv_set_terminated(BLE_RR_LIMIT_REACHED, + advsm->adv_instance, 0, + advsm->events); + + /* Disable advertising */ + advsm->adv_enabled = 0; + ble_ll_scan_chk_resume(); + } + + return; + } + /* We need to regenerate our RPA's if we have passed timeout */ #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1) ble_ll_adv_chk_rpa_timeout(advsm); @@ -2746,6 +2779,9 @@ ble_ll_adv_send_conn_comp_ev(struct ble_ll_conn_sm *connsm, ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS, evbuf, advsm); + ble_ll_hci_ev_send_adv_set_terminated(0, advsm->adv_instance, + connsm->conn_handle, advsm->events); + #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) == 1) ble_ll_hci_ev_le_csa(connsm); #endif diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index 9ee374215..37e7d23b0 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -317,6 +317,31 @@ ble_ll_hci_ev_send_scan_req_recv(uint8_t adv_handle, const uint8_t *peer, } } +/** + * Sends the LE Advertising Set Terminated event + * + */ +void +ble_ll_hci_ev_send_adv_set_terminated(uint8_t status, uint8_t adv_handle, + uint16_t conn_handle, uint8_t events) +{ + uint8_t *evbuf; + + if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED)) { + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + if (evbuf) { + evbuf[0] = BLE_HCI_EVCODE_LE_META; + evbuf[1] = BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN; + evbuf[2] = BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED; + evbuf[3] = status; + evbuf[4] = adv_handle; + put_le16(evbuf + 5, conn_handle); + evbuf[7] = events; + ble_ll_hci_event_send(evbuf); + } + } +} + /** * Send a PHY update complete event * diff --git a/nimble/include/nimble/ble.h b/nimble/include/nimble/ble.h index 6db8cd901..5d674e3fd 100644 --- a/nimble/include/nimble/ble.h +++ b/nimble/include/nimble/ble.h @@ -208,6 +208,9 @@ enum ble_error_codes BLE_ERR_CONN_ESTABLISHMENT = 62, BLE_ERR_MAC_CONN_FAIL = 63, BLE_ERR_COARSE_CLK_ADJ = 64, + BLE_ERR_TYPE0_SUBMAP_NDEF = 65, + BLE_ERR_UNK_ADV_INDENT = 66, + BLE_RR_LIMIT_REACHED = 67, BLE_ERR_MAX = 255 }; diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 02be9e29d..4b8e4bfc9 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -723,6 +723,9 @@ extern "C" { /* LE PHY update complete event (sub event 0x0C) */ #define BLE_HCI_LE_PHY_UPD_LEN (6) +/* LE Advertising Set Terminated Event (sub event 0x12) */ +#define BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN (6) + /* LE Scan Request Received event (sub event 0x13) */ #define BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD_LEN (9)