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);

Reply via email to