nimble/controller: Add support for Channel Selection Algorithm #2 When both sides indicate support for CSA #2 (by setting ChSel bit in respective PDUs) it is used for channels selection.
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/96797c92 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/96797c92 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/96797c92 Branch: refs/heads/bluetooth5 Commit: 96797c92e9bb7d27119bf48020bd1bead117b1db Parents: 9cf07fd Author: Szymon Janc <[email protected]> Authored: Wed Apr 5 14:33:33 2017 +0200 Committer: Szymon Janc <[email protected]> Committed: Fri Apr 7 13:59:51 2017 +0200 ---------------------------------------------------------------------- .../controller/include/controller/ble_ll.h | 4 +++ .../controller/include/controller/ble_ll_conn.h | 2 ++ net/nimble/controller/src/ble_ll_adv.c | 7 ++++ net/nimble/controller/src/ble_ll_conn.c | 38 ++++++++++++++------ net/nimble/controller/src/ble_ll_conn_hci.c | 4 +++ 5 files changed, 45 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/96797c92/net/nimble/controller/include/controller/ble_ll.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h index f55bc8e..0aa1f44 100644 --- a/net/nimble/controller/include/controller/ble_ll.h +++ b/net/nimble/controller/include/controller/ble_ll.h @@ -252,6 +252,7 @@ struct ble_dev_addr * -> Payload (max 37 bytes) */ #define BLE_ADV_PDU_HDR_TYPE_MASK (0x0F) +#define BLE_ADV_PDU_HDR_CHSEL_MASK (0x20) #define BLE_ADV_PDU_HDR_TXADD_MASK (0x40) #define BLE_ADV_PDU_HDR_RXADD_MASK (0x80) #define BLE_ADV_PDU_HDR_LEN_MASK (0x3F) @@ -265,6 +266,9 @@ struct ble_dev_addr #define BLE_ADV_PDU_TYPE_CONNECT_REQ (5) #define BLE_ADV_PDU_TYPE_ADV_SCAN_IND (6) +/* If Channel Selection Algorithm #2 is supported */ +#define BLE_ADV_PDU_HDR_CHSEL (0x20) + /* * TxAdd and RxAdd bit definitions. A 0 is a public address; a 1 is a * random address. http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/96797c92/net/nimble/controller/include/controller/ble_ll_conn.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_conn.h b/net/nimble/controller/include/controller/ble_ll_conn.h index 6e6f6d8..ef33b96 100644 --- a/net/nimble/controller/include/controller/ble_ll_conn.h +++ b/net/nimble/controller/include/controller/ble_ll_conn.h @@ -115,6 +115,7 @@ union ble_ll_conn_sm_flags { uint32_t encrypted:1; uint32_t encrypt_chg_sent:1; uint32_t le_ping_supp:1; + uint32_t csa2_supp:1; } cfbit; uint32_t conn_flags; } __attribute__((packed)); @@ -272,6 +273,7 @@ struct ble_ll_conn_sm #define CONN_F_ENCRYPTED(csm) ((csm)->csmflags.cfbit.encrypted) #define CONN_F_ENC_CHANGE_SENT(csm) ((csm)->csmflags.cfbit.encrypt_chg_sent) #define CONN_F_LE_PING_SUPP(csm) ((csm)->csmflags.cfbit.le_ping_supp) +#define CONN_F_CSA2_SUPP(csm) ((csm)->csmflags.cfbit.csa2_supp) /* Role */ #define CONN_IS_MASTER(csm) (csm->conn_role == BLE_LL_CONN_ROLE_MASTER) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/96797c92/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 16455fd..19a8a49 100644 --- a/net/nimble/controller/src/ble_ll_adv.c +++ b/net/nimble/controller/src/ble_ll_adv.c @@ -243,6 +243,9 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m) switch (advsm->adv_type) { case BLE_HCI_ADV_TYPE_ADV_IND: pdu_type = BLE_ADV_PDU_TYPE_ADV_IND; + + /* CSA #2 is supported */ + pdu_type |= BLE_ADV_PDU_HDR_CHSEL; break; case BLE_HCI_ADV_TYPE_ADV_NONCONN_IND: @@ -256,6 +259,10 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m) case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD: case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD: pdu_type = BLE_ADV_PDU_TYPE_ADV_DIRECT_IND; + + /* CSA #2 is supported */ + pdu_type |= BLE_ADV_PDU_HDR_CHSEL; + adv_data_len = 0; pdulen = BLE_ADV_DIRECT_IND_LEN; if (advsm->adv_rxadd) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/96797c92/net/nimble/controller/src/ble_ll_conn.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn.c b/net/nimble/controller/src/ble_ll_conn.c index afe2e86..46b8d4d 100644 --- a/net/nimble/controller/src/ble_ll_conn.c +++ b/net/nimble/controller/src/ble_ll_conn.c @@ -1574,6 +1574,19 @@ ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm, connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb; } +static void +ble_ll_conn_set_csa(struct ble_ll_conn_sm *connsm, bool use_csa2) +{ + /* calculate the next data channel */ + if (use_csa2) { + CONN_F_CSA2_SUPP(connsm) = 1; + connsm->data_chan_index = ble_ll_conn_calc_dci_csa2(connsm); + } else { + connsm->last_unmapped_chan = 0; + connsm->data_chan_index = ble_ll_conn_calc_dci(connsm); + } +} + /** * Create a new connection state machine. This is done once per * connection when the HCI command "create connection" is issued to the @@ -1612,10 +1625,6 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) */ connsm->conn_param_req.handle = 0; - /* Calculate the next data channel */ - connsm->last_unmapped_chan = 0; - connsm->data_chan_index = ble_ll_conn_calc_dci(connsm); - /* Connection end event */ connsm->conn_ev_end.ev_arg = connsm; connsm->conn_ev_end.ev_queued = 0; @@ -1936,10 +1945,14 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) } /* Calculate data channel index of next connection event */ - while (latency > 0) { - connsm->last_unmapped_chan = connsm->unmapped_chan; - connsm->data_chan_index = ble_ll_conn_calc_dci(connsm); - --latency; + if (CONN_F_CSA2_SUPP(connsm)) { + connsm->data_chan_index = ble_ll_conn_calc_dci_csa2(connsm); + } else { + while (latency > 0) { + connsm->last_unmapped_chan = connsm->unmapped_chan; + connsm->data_chan_index = ble_ll_conn_calc_dci(connsm); + --latency; + } } /* @@ -2269,9 +2282,11 @@ ble_ll_conn_req_pdu_update(struct os_mbuf *m, uint8_t *adva, uint8_t addr_type, assert(m != NULL); - /* Retain pdu type but clear txadd/rxadd bits */ + /* clear txadd/rxadd bits only */ ble_hdr = BLE_MBUF_HDR_PTR(m); - hdr = ble_hdr->txinfo.hdr_byte & BLE_ADV_PDU_HDR_TYPE_MASK; + hdr = ble_hdr->txinfo.hdr_byte & + ~(BLE_ADV_PDU_HDR_RXADD_MASK | BLE_ADV_PDU_HDR_TXADD_MASK); + if (addr_type) { /* Set random address */ hdr |= BLE_ADV_PDU_HDR_RXADD_MASK; @@ -2487,6 +2502,8 @@ ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr) /* Connection has been created. Stop scanning */ g_ble_ll_conn_create_sm = NULL; ble_ll_scan_sm_stop(0); + + ble_ll_conn_set_csa(connsm, rxbuf[0] & BLE_ADV_PDU_HDR_CHSEL_MASK); ble_ll_conn_created(connsm, NULL); } else { ble_ll_scan_chk_resume(); @@ -3436,6 +3453,7 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr) /* Start the connection state machine */ connsm->conn_role = BLE_LL_CONN_ROLE_SLAVE; ble_ll_conn_sm_new(connsm); + ble_ll_conn_set_csa(connsm, rxbuf[0] & BLE_ADV_PDU_HDR_CHSEL_MASK); /* Set initial schedule callback */ connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/96797c92/net/nimble/controller/src/ble_ll_conn_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn_hci.c b/net/nimble/controller/src/ble_ll_conn_hci.c index 4239a66..84d1b53 100644 --- a/net/nimble/controller/src/ble_ll_conn_hci.c +++ b/net/nimble/controller/src/ble_ll_conn_hci.c @@ -126,6 +126,9 @@ ble_ll_conn_req_pdu_make(struct ble_ll_conn_sm *connsm) /* Construct first PDU header byte */ pdu_type = BLE_ADV_PDU_TYPE_CONNECT_REQ; + /* CSA #2 is supported */ + pdu_type |= BLE_ADV_PDU_HDR_CHSEL; + /* Set BLE transmit header */ ble_ll_mbuf_init(m, BLE_CONNECT_REQ_LEN, pdu_type); @@ -500,6 +503,7 @@ ble_ll_conn_create(uint8_t *cmdbuf) /* Initialize state machine in master role and start state machine */ ble_ll_conn_master_init(connsm, hcc); ble_ll_conn_sm_new(connsm); + /* CSA will be selected when advertising is received */ /* Create the connection request */ ble_ll_conn_req_pdu_make(connsm);
