mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-10-02 21:27:22 +00:00
Merge pull request #48 from sjanc/scan_tmo
Support for duration and period in extended scan
This commit is contained in:
@@ -272,6 +272,7 @@ 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_scan_timeout(void);
|
||||
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);
|
||||
|
||||
@@ -132,12 +132,16 @@ struct ble_ll_scan_sm
|
||||
struct os_event scan_sched_ev;
|
||||
struct hal_timer scan_timer;
|
||||
|
||||
uint16_t duration;
|
||||
uint16_t period;
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
struct hal_timer duration_timer;
|
||||
struct hal_timer period_timer;
|
||||
uint32_t duration_ticks;
|
||||
uint32_t period_ticks;
|
||||
uint8_t ext_scanning;
|
||||
#endif
|
||||
|
||||
uint8_t cur_phy;
|
||||
uint8_t next_phy;
|
||||
uint8_t ext_scanning;
|
||||
uint8_t restart_timer_needed;
|
||||
struct ble_ll_aux_data *cur_aux_data;
|
||||
struct ble_ll_scan_params phy_data[BLE_LL_SCAN_PHY_NUMBER];
|
||||
|
||||
@@ -3028,13 +3028,11 @@ int
|
||||
ble_ll_init_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *ble_hdr)
|
||||
{
|
||||
struct ble_ll_conn_sm *connsm;
|
||||
struct ble_ll_scan_sm *scansm;
|
||||
|
||||
connsm = g_ble_ll_conn_create_sm;
|
||||
if (!connsm) {
|
||||
return 0;
|
||||
}
|
||||
scansm = connsm->scansm;
|
||||
|
||||
if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) ||
|
||||
(pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND ||
|
||||
@@ -3042,7 +3040,9 @@ ble_ll_init_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *ble_hdr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND && scansm->ext_scanning) {
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND &&
|
||||
connsm->scansm->ext_scanning) {
|
||||
if (connsm->scansm->cur_aux_data) {
|
||||
STATS_INC(ble_ll_stats, aux_received);
|
||||
}
|
||||
@@ -3050,6 +3050,7 @@ ble_ll_init_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *ble_hdr)
|
||||
ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_EXT_ADV;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -320,6 +320,28 @@ ble_ll_hci_ev_send_scan_req_recv(uint8_t adv_handle, const uint8_t *peer,
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Sends the LE Scan Timeout Event
|
||||
*
|
||||
*/
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
void
|
||||
ble_ll_hci_ev_send_scan_timeout(void)
|
||||
{
|
||||
uint8_t *evbuf;
|
||||
|
||||
if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SCAN_TIMEOUT)) {
|
||||
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_SCAN_TIMEOUT_LEN;
|
||||
evbuf[2] = BLE_HCI_LE_SUBEV_SCAN_TIMEOUT;
|
||||
ble_ll_hci_event_send(evbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Sends the LE Advertising Set Terminated event
|
||||
*
|
||||
|
||||
@@ -1154,7 +1154,9 @@ ble_ll_scan_sm_stop(int chk_disable)
|
||||
if (chk_disable) {
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
lls = ble_ll_state_get();
|
||||
if ((lls == BLE_LL_STATE_SCANNING) || (lls == BLE_LL_STATE_INITIATING)) {
|
||||
|
||||
if ((lls == BLE_LL_STATE_SCANNING) ||
|
||||
(lls == BLE_LL_STATE_INITIATING && chk_disable == 1)) {
|
||||
/* Disable phy */
|
||||
ble_phy_disable();
|
||||
|
||||
@@ -1509,10 +1511,12 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags)
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND && scansm->ext_scanning)) {
|
||||
*rxflags |= BLE_MBUF_HDR_F_EXT_ADV;
|
||||
rc = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this is the first PDU after we sent the scan response (as
|
||||
@@ -2712,6 +2716,57 @@ ble_ll_set_ext_scan_params(uint8_t *cmd)
|
||||
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
static void
|
||||
ble_ll_scan_duration_period_timers_restart(struct ble_ll_scan_sm *scansm)
|
||||
{
|
||||
uint32_t now;
|
||||
|
||||
now = os_cputime_get32();
|
||||
|
||||
os_cputime_timer_stop(&scansm->duration_timer);
|
||||
os_cputime_timer_stop(&scansm->period_timer);
|
||||
|
||||
if (scansm->duration_ticks) {
|
||||
os_cputime_timer_start(&scansm->duration_timer,
|
||||
now + scansm->duration_ticks);
|
||||
|
||||
if (scansm->period_ticks) {
|
||||
os_cputime_timer_start(&scansm->period_timer,
|
||||
now + scansm->period_ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ble_ll_scan_duration_timer_cb(void *arg)
|
||||
{
|
||||
struct ble_ll_scan_sm *scansm;
|
||||
|
||||
scansm = (struct ble_ll_scan_sm *)arg;
|
||||
|
||||
ble_ll_scan_sm_stop(2);
|
||||
|
||||
/* if period is set both timers get started from period cb */
|
||||
if (!scansm->period_ticks) {
|
||||
ble_ll_hci_ev_send_scan_timeout();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ble_ll_scan_period_timer_cb(void *arg)
|
||||
{
|
||||
struct ble_ll_scan_sm *scansm = arg;
|
||||
|
||||
ble_ll_scan_sm_start(scansm);
|
||||
|
||||
/* always start timer regardless of ble_ll_scan_sm_start result
|
||||
* if it failed will restart in next period
|
||||
*/
|
||||
ble_ll_scan_duration_period_timers_restart(scansm);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ble ll scan set enable
|
||||
*
|
||||
@@ -2732,9 +2787,13 @@ ble_ll_scan_set_enable(uint8_t *cmd, uint8_t ext)
|
||||
struct ble_ll_scan_sm *scansm;
|
||||
struct ble_ll_scan_params *scanp;
|
||||
struct ble_ll_scan_params *scanphy;
|
||||
uint16_t dur;
|
||||
uint16_t period;
|
||||
int i;
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
uint32_t period_ticks = 0;
|
||||
uint32_t dur_ticks = 0;
|
||||
uint16_t period;
|
||||
uint16_t dur;
|
||||
#endif
|
||||
|
||||
/* Check for valid parameters */
|
||||
enable = cmd[0];
|
||||
@@ -2745,70 +2804,114 @@ ble_ll_scan_set_enable(uint8_t *cmd, uint8_t ext)
|
||||
|
||||
scansm = &g_ble_ll_scan_sm;
|
||||
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
/* we can do that here since value will never change until reset */
|
||||
scansm->ext_scanning = ext;
|
||||
|
||||
if (ext) {
|
||||
/* TODO: Mark that extended scan is ongoing in order to send
|
||||
* correct advertising report
|
||||
*/
|
||||
|
||||
dur = get_le16(cmd + 2);
|
||||
period = get_le16(cmd + 4);
|
||||
|
||||
/* TODO Use period and duration */
|
||||
(void) dur;
|
||||
(void) period;
|
||||
}
|
||||
|
||||
rc = BLE_ERR_SUCCESS;
|
||||
if (enable) {
|
||||
/* If already enabled, do nothing */
|
||||
if (!scansm->scan_enabled) {
|
||||
|
||||
scansm->cur_phy = PHY_NOT_CONFIGURED;
|
||||
scansm->next_phy = PHY_NOT_CONFIGURED;
|
||||
|
||||
for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) {
|
||||
scanphy = &scansm->phy_data[i];
|
||||
scanp = &g_ble_ll_scan_params[i];
|
||||
|
||||
if (!scanp->configured) {
|
||||
continue;
|
||||
}
|
||||
|
||||
scanphy->configured = scanp->configured;
|
||||
scanphy->scan_type = scanp->scan_type;
|
||||
scanphy->scan_itvl = scanp->scan_itvl;
|
||||
scanphy->scan_window = scanp->scan_window;
|
||||
scanphy->scan_filt_policy = scanp->scan_filt_policy;
|
||||
scanphy->own_addr_type = scanp->own_addr_type;
|
||||
scansm->scan_filt_dups = filter_dups;
|
||||
|
||||
if (scansm->cur_phy == PHY_NOT_CONFIGURED) {
|
||||
scansm->cur_phy = i;
|
||||
} else {
|
||||
scansm->next_phy = i;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ble_ll_scan_sm_start(scansm);
|
||||
/* Period parameter is ignored when the Duration parameter is zero */
|
||||
if (dur) {
|
||||
period = get_le16(cmd + 4);
|
||||
} else {
|
||||
/* Controller does not allow initiating and scanning.*/
|
||||
for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) {
|
||||
scanphy = &scansm->phy_data[i];
|
||||
if (scanphy->configured &&
|
||||
scanphy->scan_type == BLE_SCAN_TYPE_INITIATE) {
|
||||
rc = BLE_ERR_CMD_DISALLOWED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
period = 0;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* period is in 1.28 sec units
|
||||
* TODO support full range, would require os_cputime milliseconds API
|
||||
*/
|
||||
if (period > 3355) {
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
period_ticks = os_cputime_usecs_to_ticks(period * 1280000);
|
||||
|
||||
/* duration is in 10ms units */
|
||||
dur_ticks = os_cputime_usecs_to_ticks(dur * 10000);
|
||||
|
||||
if (dur_ticks && period_ticks && (dur_ticks >= period_ticks)) {
|
||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* disable*/
|
||||
if (!enable) {
|
||||
if (scansm->scan_enabled) {
|
||||
ble_ll_scan_sm_stop(1);
|
||||
}
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
os_cputime_timer_stop(&scansm->duration_timer);
|
||||
os_cputime_timer_stop(&scansm->period_timer);
|
||||
#endif
|
||||
|
||||
return BLE_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/* if already enable we just need to update parameters */
|
||||
if (scansm->scan_enabled) {
|
||||
/* Controller does not allow initiating and scanning.*/
|
||||
for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) {
|
||||
scanphy = &scansm->phy_data[i];
|
||||
if (scanphy->configured &&
|
||||
scanphy->scan_type == BLE_SCAN_TYPE_INITIATE) {
|
||||
return BLE_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
}
|
||||
|
||||
/* update filter policy */
|
||||
scansm->scan_filt_dups = filter_dups;
|
||||
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
/* restart timers according to new settings */
|
||||
scansm->duration_ticks = dur_ticks;
|
||||
scansm->period_ticks = period_ticks;
|
||||
ble_ll_scan_duration_period_timers_restart(scansm);
|
||||
#endif
|
||||
|
||||
return BLE_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/* we can store those upfront regardless of start scan result since scan is
|
||||
* disabled now
|
||||
*/
|
||||
|
||||
scansm->scan_filt_dups = filter_dups;
|
||||
scansm->cur_phy = PHY_NOT_CONFIGURED;
|
||||
scansm->next_phy = PHY_NOT_CONFIGURED;
|
||||
|
||||
for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) {
|
||||
scanphy = &scansm->phy_data[i];
|
||||
scanp = &g_ble_ll_scan_params[i];
|
||||
|
||||
if (!scanp->configured) {
|
||||
continue;
|
||||
}
|
||||
|
||||
scanphy->configured = scanp->configured;
|
||||
scanphy->scan_type = scanp->scan_type;
|
||||
scanphy->scan_itvl = scanp->scan_itvl;
|
||||
scanphy->scan_window = scanp->scan_window;
|
||||
scanphy->scan_filt_policy = scanp->scan_filt_policy;
|
||||
scanphy->own_addr_type = scanp->own_addr_type;
|
||||
|
||||
if (scansm->cur_phy == PHY_NOT_CONFIGURED) {
|
||||
scansm->cur_phy = i;
|
||||
} else {
|
||||
scansm->next_phy = i;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ble_ll_scan_sm_start(scansm);
|
||||
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
if (rc == BLE_ERR_SUCCESS) {
|
||||
scansm->duration_ticks = dur_ticks;
|
||||
scansm->period_ticks = period_ticks;
|
||||
ble_ll_scan_duration_period_timers_restart(scansm);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2846,7 +2949,9 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc,
|
||||
|
||||
scansm = &g_ble_ll_scan_sm;
|
||||
scansm->own_addr_type = hcc->own_addr_type;
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
scansm->ext_scanning = 0;
|
||||
#endif
|
||||
scansm->cur_phy = PHY_UNCODED;
|
||||
scansm->next_phy = PHY_NOT_CONFIGURED;
|
||||
|
||||
@@ -3061,6 +3166,14 @@ ble_ll_scan_common_init(void)
|
||||
/* Initialize scanning timer */
|
||||
os_cputime_timer_init(&scansm->scan_timer, ble_ll_scan_timer_cb, scansm);
|
||||
|
||||
/* Initialize extended scan timers */
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
os_cputime_timer_init(&g_ble_ll_scan_sm.duration_timer,
|
||||
ble_ll_scan_duration_timer_cb, &g_ble_ll_scan_sm);
|
||||
os_cputime_timer_init(&g_ble_ll_scan_sm.period_timer,
|
||||
ble_ll_scan_period_timer_cb, &g_ble_ll_scan_sm);
|
||||
#endif
|
||||
|
||||
/* Get a scan request mbuf (packet header) and attach to state machine */
|
||||
scansm->scan_req_pdu = os_msys_get_pkthdr(BLE_SCAN_LEGACY_MAX_PKT_LEN,
|
||||
sizeof(struct ble_mbuf_hdr));
|
||||
@@ -3078,12 +3191,19 @@ ble_ll_scan_reset(void)
|
||||
{
|
||||
struct ble_ll_scan_sm *scansm;
|
||||
|
||||
/* If enabled, stop it. */
|
||||
scansm = &g_ble_ll_scan_sm;
|
||||
|
||||
/* If enabled, stop it. */
|
||||
if (scansm->scan_enabled) {
|
||||
ble_ll_scan_sm_stop(0);
|
||||
}
|
||||
|
||||
/* stop extended scan timers */
|
||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||
os_cputime_timer_stop(&scansm->duration_timer);
|
||||
os_cputime_timer_stop(&scansm->period_timer);
|
||||
#endif
|
||||
|
||||
/* Free the scan request pdu */
|
||||
os_mbuf_free_chain(scansm->scan_req_pdu);
|
||||
|
||||
|
||||
@@ -1257,6 +1257,14 @@ ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc)
|
||||
ble_gap_disc_report(desc);
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
|
||||
void
|
||||
ble_gap_rx_le_scan_timeout(void)
|
||||
{
|
||||
ble_gap_disc_complete();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV)
|
||||
void
|
||||
ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc)
|
||||
|
||||
@@ -75,6 +75,10 @@ extern STATS_SECT_DECL(ble_gap_stats) ble_gap_stats;
|
||||
#define BLE_GAP_CONN_MODE_MAX 3
|
||||
#define BLE_GAP_DISC_MODE_MAX 3
|
||||
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
|
||||
void ble_gap_rx_le_scan_timeout(void);
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV)
|
||||
void ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc);
|
||||
void ble_gap_rx_adv_set_terminated(struct hci_le_adv_set_terminated *evt);
|
||||
|
||||
@@ -50,6 +50,7 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_dir_adv_rpt;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_phy_update_complete;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_ext_adv_rpt;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_rd_rem_used_feat_complete;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_timeout;
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_adv_set_terminated;
|
||||
|
||||
/* Statistics */
|
||||
@@ -102,6 +103,8 @@ static const struct ble_hs_hci_evt_le_dispatch_entry
|
||||
{ BLE_HCI_LE_SUBEV_EXT_ADV_RPT, ble_hs_hci_evt_le_ext_adv_rpt },
|
||||
{ BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT,
|
||||
ble_hs_hci_evt_le_rd_rem_used_feat_complete },
|
||||
{ BLE_HCI_LE_SUBEV_SCAN_TIMEOUT,
|
||||
ble_hs_hci_evt_le_scan_timeout },
|
||||
{ BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED,
|
||||
ble_hs_hci_evt_le_adv_set_terminated },
|
||||
};
|
||||
@@ -604,6 +607,15 @@ ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, uint8_t *data, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, uint8_t *data, int len)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
|
||||
ble_gap_rx_le_scan_timeout();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hs_hci_evt_le_adv_set_terminated(uint8_t subevent, uint8_t *data, int len)
|
||||
{
|
||||
|
||||
@@ -775,6 +775,9 @@ extern "C" {
|
||||
/* LE PHY update complete event (sub event 0x0C) */
|
||||
#define BLE_HCI_LE_PHY_UPD_LEN (6)
|
||||
|
||||
/* LE Scan Timeout Event (sub event 0x11) */
|
||||
#define BLE_HCI_LE_SUBEV_SCAN_TIMEOUT_LEN (1)
|
||||
|
||||
/* LE Advertising Set Terminated Event (sub event 0x12) */
|
||||
#define BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN (6)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user