Merge pull request #48 from sjanc/scan_tmo

Support for duration and period in extended scan
This commit is contained in:
Szymon Janc
2018-04-18 13:27:27 +02:00
committed by GitHub
9 changed files with 237 additions and 62 deletions
@@ -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];
+4 -3
View File
@@ -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;
}
+22
View File
@@ -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
*
+176 -56
View File
@@ -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);
+8
View File
@@ -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)
+4
View File
@@ -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);
+12
View File
@@ -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)
{
+3
View File
@@ -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)