nimble/controller: Enhance scansm for future support of Bluetooth 5.0

We are going to have array of struct ble_ll_scan_sm.
First array element is reserved for PHY_1M and second for PHY_CODED

X-Original-Commit: b6cb09b7f0d7816c45732b208abbe0fbeff0bcbd
This commit is contained in:
Łukasz Rymanowski
2017-06-22 13:59:29 +02:00
parent 54129ea32b
commit 1cd9839188
3 changed files with 97 additions and 41 deletions
@@ -22,6 +22,7 @@
#include "controller/ble_ll_sched.h"
#include "hal/hal_timer.h"
#include "syscfg/syscfg.h"
#ifdef __cplusplus
extern "C" {
@@ -54,22 +55,31 @@ extern "C" {
#define BLE_SCAN_RSP_DATA_MAX_LEN (31)
#define BLE_SCAN_MAX_PKT_LEN (37)
#if MYNEWT_VAL(BLE_EXT_SCAN_SUPPORT)
/* For Bluetooth 5.0 we need state machine for two PHYs*/
#define BLE_LL_SCAN_PHY_NUMBER (2)
#else
#define BLE_LL_SCAN_PHY_NUMBER (1)
#endif
#define PHY_UNCODED (0)
#define PHY_CODED (1)
struct ble_ll_scan_params
{
uint8_t scan_type;
uint8_t own_addr_type;
uint8_t scan_filt_policy;
uint8_t configured;
uint8_t scan_type;
uint8_t scan_chan;
uint16_t scan_itvl;
uint16_t scan_window;
};
/* Scanning state machine (used when initiating as well) */
struct ble_ll_scan_sm
{
uint8_t scan_enabled;
uint8_t scan_type;
uint8_t own_addr_type;
uint8_t scan_chan;
uint8_t scan_filt_policy;
uint8_t scan_filt_dups;
uint8_t scan_rsp_pending;
@@ -77,14 +87,20 @@ struct ble_ll_scan_sm
uint8_t scan_rsp_cons_ok;
int8_t scan_rpa_index;
uint8_t scan_peer_rpa[BLE_DEV_ADDR_LEN];
/* XXX: Shall we count backoff per phy? */
uint16_t upper_limit;
uint16_t backoff_count;
uint16_t scan_itvl;
uint16_t scan_window;
uint32_t scan_win_start_time;
struct os_mbuf *scan_req_pdu;
struct os_event scan_sched_ev;
struct hal_timer scan_timer;
uint16_t duration;
uint16_t period;
uint8_t cur_phy;
struct ble_ll_scan_params phy_data[BLE_LL_SCAN_PHY_NUMBER];
};
/* Scan types */
+72 -35
View File
@@ -61,7 +61,7 @@
/* The scanning parameters set by host */
struct ble_ll_scan_params g_ble_ll_scan_params;
struct ble_ll_scan_params g_ble_ll_scan_params[BLE_LL_SCAN_PHY_NUMBER];
/* The scanning state machine global object */
struct ble_ll_scan_sm g_ble_ll_scan_sm;
@@ -576,6 +576,7 @@ static void
ble_ll_scan_start(struct ble_ll_scan_sm *scansm, uint8_t chan)
{
int rc;
struct ble_ll_scan_params *scanphy = &scansm->phy_data[scansm->cur_phy];
/* Set channel */
rc = ble_phy_setchan(chan, 0, 0);
@@ -620,7 +621,7 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm, uint8_t chan)
}
/* Set link layer state to scanning */
if (scansm->scan_type == BLE_SCAN_TYPE_INITIATE) {
if (scanphy->scan_type == BLE_SCAN_TYPE_INITIATE) {
ble_ll_state_set(BLE_LL_STATE_INITIATING);
} else {
ble_ll_state_set(BLE_LL_STATE_SCANNING);
@@ -683,9 +684,10 @@ ble_ll_scan_window_chk(struct ble_ll_scan_sm *scansm, uint32_t cputime)
uint32_t itvl;
uint32_t dt;
uint32_t win_start;
struct ble_ll_scan_params *scanphy = &scansm->phy_data[scansm->cur_phy];
itvl = os_cputime_usecs_to_ticks(scansm->scan_itvl * BLE_HCI_SCAN_ITVL);
chan = scansm->scan_chan;
itvl = os_cputime_usecs_to_ticks(scanphy->scan_itvl * BLE_HCI_SCAN_ITVL);
chan = scanphy->scan_chan;
win_start = scansm->scan_win_start_time;
while ((int32_t)(cputime - win_start) >= itvl) {
win_start += itvl;
@@ -696,12 +698,12 @@ ble_ll_scan_window_chk(struct ble_ll_scan_sm *scansm, uint32_t cputime)
}
rc = 0;
if (scansm->scan_window != scansm->scan_itvl) {
itvl = os_cputime_usecs_to_ticks(scansm->scan_window * BLE_HCI_SCAN_ITVL);
if (scanphy->scan_window != scanphy->scan_itvl) {
itvl = os_cputime_usecs_to_ticks(scanphy->scan_window * BLE_HCI_SCAN_ITVL);
dt = cputime - win_start;
if (dt >= itvl) {
#ifdef BLE_XCVR_RFCLK
if (dt < (scansm->scan_itvl - g_ble_ll_data.ll_xtal_ticks)) {
if (dt < (scanphy->scan_itvl - g_ble_ll_data.ll_xtal_ticks)) {
ble_ll_scan_rfclk_chk_stop();
}
#endif
@@ -780,7 +782,7 @@ ble_ll_scan_sm_start(struct ble_ll_scan_sm *scansm)
scansm->scan_enabled = 1;
/* Set first advertising channel */
scansm->scan_chan = BLE_PHY_ADV_CHAN_START;
scansm->phy_data[scansm->cur_phy].scan_chan = BLE_PHY_ADV_CHAN_START;
/* Reset scan request backoff parameters to default */
scansm->upper_limit = 1;
@@ -825,6 +827,7 @@ ble_ll_scan_event_proc(struct os_event *ev)
uint32_t xtal_ticks;
#endif
struct ble_ll_scan_sm *scansm;
struct ble_ll_scan_params *scanphy;
/*
* Get the scanning state machine. If not enabled (this is possible), just
@@ -836,11 +839,13 @@ ble_ll_scan_event_proc(struct os_event *ev)
return;
}
scanphy = &scansm->phy_data[scansm->cur_phy];
/* Make sure the scan window start time and channel are up to date. */
now = os_cputime_get32();
scan_itvl = os_cputime_usecs_to_ticks(scansm->scan_itvl * BLE_HCI_SCAN_ITVL);
chan = scansm->scan_chan;
scan_itvl = os_cputime_usecs_to_ticks(scanphy->scan_itvl * BLE_HCI_SCAN_ITVL);
chan = scanphy->scan_chan;
win_start = scansm->scan_win_start_time;
while ((int32_t)(now - win_start) >= scan_itvl) {
win_start += scan_itvl;
@@ -851,10 +856,10 @@ ble_ll_scan_event_proc(struct os_event *ev)
}
dt = now - win_start;
scansm->scan_chan = chan;
scanphy->scan_chan = chan;
scansm->scan_win_start_time = win_start;
if (scansm->scan_window != scansm->scan_itvl) {
win = os_cputime_usecs_to_ticks(scansm->scan_window * BLE_HCI_SCAN_ITVL);
if (scanphy->scan_window != scanphy->scan_itvl) {
win = os_cputime_usecs_to_ticks(scanphy->scan_window * BLE_HCI_SCAN_ITVL);
} else {
win = 0;
}
@@ -955,7 +960,7 @@ ble_ll_scan_event_proc(struct os_event *ev)
goto rfclk_not_settled;
}
#endif
ble_ll_scan_start(scansm, scansm->scan_chan);
ble_ll_scan_start(scansm, scanphy->scan_chan);
}
#ifdef BLE_XCVR_RFCLK
@@ -984,11 +989,13 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint8_t *rxflags)
{
int rc;
struct ble_ll_scan_sm *scansm;
struct ble_ll_scan_params *scanphy;
rc = 0;
scansm = &g_ble_ll_scan_sm;
scanphy = &scansm->phy_data[scansm->cur_phy];
switch (scansm->scan_type) {
switch (scanphy->scan_type) {
case BLE_SCAN_TYPE_ACTIVE:
/* If adv ind or scan ind, we may send scan request */
if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) ||
@@ -1050,9 +1057,11 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
uint8_t *rxbuf;
struct ble_mbuf_hdr *ble_hdr;
struct ble_ll_scan_sm *scansm;
struct ble_ll_scan_params *scanphy;
/* Get scanning state machine */
scansm = &g_ble_ll_scan_sm;
scanphy = &scansm->phy_data[scansm->cur_phy];
/*
* The reason we do something different here (as opposed to failed CRC) is
@@ -1090,7 +1099,7 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
switch (pdu_type) {
case BLE_ADV_PDU_TYPE_ADV_IND:
case BLE_ADV_PDU_TYPE_ADV_SCAN_IND:
if (scansm->scan_type == BLE_SCAN_TYPE_ACTIVE) {
if (scanphy->scan_type == BLE_SCAN_TYPE_ACTIVE) {
chk_send_req = 1;
}
chk_wl = 1;
@@ -1388,12 +1397,15 @@ ble_ll_scan_set_scan_params(uint8_t *cmd)
}
/* Store scan parameters */
scanp = &g_ble_ll_scan_params;
scanp = &g_ble_ll_scan_params[PHY_UNCODED];
scanp->configured = 1;
scanp->scan_type = scan_type;
scanp->scan_itvl = scan_itvl;
scanp->scan_window = scan_window;
scanp->scan_filt_policy = filter_policy;
scanp->own_addr_type = own_addr_type;
g_ble_ll_scan_params[PHY_CODED].configured = 0;
return 0;
}
@@ -1417,6 +1429,8 @@ ble_ll_scan_set_enable(uint8_t *cmd)
uint8_t enable;
struct ble_ll_scan_sm *scansm;
struct ble_ll_scan_params *scanp;
struct ble_ll_scan_params *scanphy;
int i;
/* Check for valid parameters */
enable = cmd[0];
@@ -1430,19 +1444,36 @@ ble_ll_scan_set_enable(uint8_t *cmd)
if (enable) {
/* If already enabled, do nothing */
if (!scansm->scan_enabled) {
scanp = &g_ble_ll_scan_params;
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;
}
/* Start the scanning state machine */
scansm->scan_type = scanp->scan_type;
scansm->scan_itvl = scanp->scan_itvl;
scansm->scan_window = scanp->scan_window;
scansm->scan_filt_policy = scanp->scan_filt_policy;
scansm->own_addr_type = scanp->own_addr_type;
scansm->scan_filt_dups = filter_dups;
scansm->cur_phy = PHY_UNCODED;
rc = ble_ll_scan_sm_start(scansm);
} else {
/* Controller does not allow initiating and scanning.*/
if (scansm->scan_type == BLE_SCAN_TYPE_INITIATE) {
rc = BLE_ERR_CMD_DISALLOWED;
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;
}
}
}
} else {
@@ -1480,13 +1511,17 @@ int
ble_ll_scan_initiator_start(struct hci_create_conn *hcc)
{
struct ble_ll_scan_sm *scansm;
struct ble_ll_scan_params *scanphy;
scansm = &g_ble_ll_scan_sm;
scansm->scan_type = BLE_SCAN_TYPE_INITIATE;
scansm->scan_itvl = hcc->scan_itvl;
scansm->scan_window = hcc->scan_window;
scansm->scan_filt_policy = hcc->filter_policy;
scansm->own_addr_type = hcc->own_addr_type;
scanphy = &scansm->phy_data[scansm->cur_phy];
scanphy->scan_itvl = hcc->scan_itvl;
scanphy->scan_window = hcc->scan_window;
scanphy->scan_type = BLE_SCAN_TYPE_INITIATE;
return ble_ll_scan_sm_start(scansm);
}
@@ -1612,23 +1647,25 @@ ble_ll_scan_init(void)
{
struct ble_ll_scan_sm *scansm;
struct ble_ll_scan_params *scanp;
int i;
/* Clear state machine in case re-initialized */
scansm = &g_ble_ll_scan_sm;
memset(scansm, 0, sizeof(struct ble_ll_scan_sm));
/* Clear scan parameters in case re-initialized */
scanp = &g_ble_ll_scan_params;
memset(scanp, 0, sizeof(struct ble_ll_scan_params));
memset(g_ble_ll_scan_params, 0, sizeof(g_ble_ll_scan_params));
/* Initialize scanning window end event */
scansm->scan_sched_ev.ev_cb = ble_ll_scan_event_proc;
scansm->scan_sched_ev.ev_arg = scansm;
/* Set all non-zero default parameters */
scanp->scan_itvl = BLE_HCI_SCAN_ITVL_DEF;
scanp->scan_window = BLE_HCI_SCAN_WINDOW_DEF;
for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) {
/* Set all non-zero default parameters */
scanp = &g_ble_ll_scan_params[i];
scanp->scan_itvl = BLE_HCI_SCAN_ITVL_DEF;
scanp->scan_window = BLE_HCI_SCAN_WINDOW_DEF;
}
/* Initialize scanning timer */
os_cputime_timer_init(&scansm->scan_timer, ble_ll_scan_timer_cb, scansm);
+3
View File
@@ -51,3 +51,6 @@ syscfg.defs:
advertising instances is this number plus 1 (assuming the device
supports advertising).
value: 0
BLE_EXT_SCAN_SUPPORT:
description: "Enable extended scan support from Bluetooth 5.0"
value: 0