You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2016/01/27 19:14:39 UTC

incubator-mynewt-larva git commit: First cut at connection parameter request procedure. Major modifications to scheduling code to fix some schedule bugs

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 0e324d9e2 -> d61dbe829


First cut at connection parameter request procedure. Major modifications to scheduling code to fix some schedule bugs


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/d61dbe82
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/d61dbe82
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/d61dbe82

Branch: refs/heads/master
Commit: d61dbe829f07da74cddb39f7be27a445969a936b
Parents: 0e324d9
Author: wes3 <wi...@micosa.io>
Authored: Wed Jan 27 10:14:23 2016 -0800
Committer: wes3 <wi...@micosa.io>
Committed: Wed Jan 27 10:14:30 2016 -0800

----------------------------------------------------------------------
 .../controller/include/controller/ble_ll_conn.h |   3 +
 net/nimble/controller/src/ble_ll.c              |   4 +-
 net/nimble/controller/src/ble_ll_conn.c         |  18 ++-
 net/nimble/controller/src/ble_ll_conn_hci.c     |  12 +-
 net/nimble/controller/src/ble_ll_conn_priv.h    |   4 +-
 net/nimble/controller/src/ble_ll_ctrl.c         | 155 +++++++++++--------
 net/nimble/controller/src/ble_ll_hci.c          |   7 +-
 net/nimble/controller/src/ble_ll_hci_ev.c       |  10 +-
 net/nimble/controller/src/ble_ll_sched.c        | 105 +++++++------
 project/bletest/src/main.c                      |  56 +++++--
 10 files changed, 224 insertions(+), 150 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 3f4d48f..0076e7d 100644
--- a/net/nimble/controller/include/controller/ble_ll_conn.h
+++ b/net/nimble/controller/include/controller/ble_ll_conn.h
@@ -183,6 +183,9 @@ struct ble_ll_conn_sm
 
     /* For connection update procedure */
     struct ble_ll_conn_upd_req conn_update_req;
+
+    /* XXX: for now, just store them all */
+    struct ble_ll_conn_params conn_cp;
 };
 
 /* 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/net/nimble/controller/src/ble_ll.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c
index 49435e8..9bab00e 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -50,7 +50,7 @@
 
 /* Configuration for supported features */
 #define BLE_LL_CFG_FEAT_DATA_LEN_EXT
-#undef BLE_LL_CFG_FEAT_CONN_PARAM_REQ
+#define BLE_LL_CFG_FEAT_CONN_PARAM_REQ
 #undef BLE_LL_CFG_FEAT_LE_ENCRYPTION
 #undef BLE_LL_CFG_FEAT_EXT_REJECT_IND
 #define BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG
@@ -702,7 +702,7 @@ ble_ll_task(void *arg)
         case OS_EVENT_T_TIMER:
             cf = (struct os_callout_func *)ev;
             assert(cf->cf_func);
-            cf->cf_func(cf->cf_arg);
+            cf->cf_func(ev->ev_arg);
             break;
         case BLE_LL_EVENT_HCI_CMD:
             /* Process HCI command */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 e219bbb..8039201 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -102,10 +102,10 @@ extern int ble_hs_rx_data(struct os_mbuf *om);
 /* Configuration parameters */
 #define BLE_LL_CFG_CONN_TX_WIN_SIZE         (1)
 #define BLE_LL_CFG_CONN_TX_WIN_OFF          (0)
-#define BLE_LL_CFG_CONN_MASTER_SCA          (BLE_MASTER_SCA_251_500_PPM << 5)
+#define BLE_LL_CFG_CONN_MASTER_SCA          (BLE_MASTER_SCA_51_75_PPM << 5)
 #define BLE_LL_CFG_CONN_MAX_CONNS           (32)
 #define BLE_LL_CFG_CONN_OUR_SCA             (60)    /* in ppm */
-#define BLE_LL_CFG_CONN_INIT_SLOTS          (2)
+#define BLE_LL_CFG_CONN_INIT_SLOTS          (4)
 
 /* We cannot have more than 254 connections given our current implementation */
 #if (BLE_LL_CFG_CONN_MAX_CONNS >= 255)
@@ -114,8 +114,8 @@ extern int ble_hs_rx_data(struct os_mbuf *om);
 
 /* LL configuration definitions */
 #define BLE_LL_CFG_SUPP_MAX_RX_BYTES        (251)
-#define BLE_LL_CFG_SUPP_MAX_TX_BYTES        (27)
-#define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES   (27)
+#define BLE_LL_CFG_SUPP_MAX_TX_BYTES        (251)
+#define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES   (251)
 
 /* Sleep clock accuracy table (in ppm) */
 static const uint16_t g_ble_sca_ppm_tbl[8] =
@@ -992,6 +992,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm)
     connsm->comp_id = 0;
     connsm->sub_vers_nr = 0;
     connsm->rxd_version_ind = 0;
+    connsm->reject_reason = BLE_ERR_SUCCESS;
 
     /* Reset current control procedure */
     connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_IDLE;
@@ -1268,7 +1269,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
 
         /* Reset the connection supervision timeout */
         cputime_timer_stop(&connsm->conn_spvn_timer);
-        tmo = connsm->supervision_tmo * BLE_HCI_CONN_SPVN_TMO_UNITS * 1000;
+        tmo = connsm->supervision_tmo;
+        tmo = tmo * BLE_HCI_CONN_SPVN_TMO_UNITS * 1000;
+        tmo = cputime_usecs_to_ticks(tmo);
         cputime_timer_start(&connsm->conn_spvn_timer, connsm->anchor_point+tmo);
 
         /* Reset update scheduled flag */
@@ -1278,8 +1281,8 @@ 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;
-        --latency;
         connsm->data_chan_index = ble_ll_conn_calc_dci(connsm);
+        --latency;
     }
 
     /* 
@@ -1727,6 +1730,7 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
             }
         }
 
+        /* XXX: note: this crashed during interop testing! conn_create_sm=NULL*/
         /* Attempt to schedule new connection. Possible that this might fail */
         if (!ble_ll_sched_master_new(g_ble_ll_conn_create_sm, 
                                    ble_hdr->end_cputime,
@@ -2131,7 +2135,7 @@ conn_rx_pdu_end:
     if (connsm->slave_set_last_anchor) {
         connsm->slave_set_last_anchor = 0;
         connsm->last_anchor_point = rxhdr->end_cputime - 
-            BLE_TX_DUR_USECS_M(rxpdu->om_data[1]);
+            cputime_usecs_to_ticks(BLE_TX_DUR_USECS_M(rxpdu->om_data[1]));
         connsm->anchor_point = connsm->last_anchor_point;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 102462e..29c6810 100644
--- a/net/nimble/controller/src/ble_ll_conn_hci.c
+++ b/net/nimble/controller/src/ble_ll_conn_hci.c
@@ -467,7 +467,7 @@ ble_ll_conn_read_rem_features(uint8_t *cmdbuf)
  * @return int 
  */
 int
-ble_ll_conn_update(uint8_t *cmdbuf)
+ble_ll_conn_hci_update(uint8_t *cmdbuf)
 {
     int rc;
     uint8_t ctrl_proc;
@@ -493,6 +493,9 @@ ble_ll_conn_update(uint8_t *cmdbuf)
 
     /* See if we support this feature */
     if ((ble_ll_read_supp_features() & BLE_LL_FEAT_CONN_PARM_REQ) == 0) {
+        if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
+            return BLE_ERR_UNSUPP_FEATURE;
+        } 
         ctrl_proc = BLE_LL_CTRL_PROC_CONN_UPDATE;
     } else {
         ctrl_proc = BLE_LL_CTRL_PROC_CONN_PARAM_REQ;
@@ -544,7 +547,7 @@ ble_ll_conn_update(uint8_t *cmdbuf)
 }
 
 int
-ble_ll_conn_param_reply(uint8_t *cmdbuf, int positive_reply)
+ble_ll_conn_hci_param_reply(uint8_t *cmdbuf, int positive_reply)
 {
     int rc;
     uint8_t ble_err;
@@ -586,7 +589,8 @@ ble_ll_conn_param_reply(uint8_t *cmdbuf, int positive_reply)
             om = os_mbuf_get_pkthdr(&g_mbuf_pool, sizeof(struct ble_mbuf_hdr));
             if (om) {
                 dptr = om->om_data;
-                rsp_opcode = ble_ll_ctrl_conn_param_reply(connsm, dptr, NULL);
+                rsp_opcode = ble_ll_ctrl_conn_param_reply(connsm, dptr, 
+                                                          &connsm->conn_cp);
                 dptr[0] = rsp_opcode;
                 len = g_ble_ll_ctrl_pkt_lengths[rsp_opcode] + 1;
                 ble_ll_conn_enqueue_pkt(connsm, om, BLE_LL_LLID_CTRL, len);
@@ -621,7 +625,7 @@ ble_ll_conn_create_cancel(void)
     int rc;
     struct ble_ll_conn_sm *connsm;
 
-    /* WWW: BUG! I send the event before the command complete. Not good. */
+    /* XXX: BUG! I send the event before the command complete. Not good. */
     /* 
      * If we receive this command and we have not got a connection
      * create command, we have to return disallowed. The spec does not say

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/net/nimble/controller/src/ble_ll_conn_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_conn_priv.h b/net/nimble/controller/src/ble_ll_conn_priv.h
index e309396..9370f0a 100644
--- a/net/nimble/controller/src/ble_ll_conn_priv.h
+++ b/net/nimble/controller/src/ble_ll_conn_priv.h
@@ -98,8 +98,8 @@ void ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm,
 int ble_ll_conn_hci_disconnect_cmd(uint8_t *cmdbuf);
 int ble_ll_conn_hci_rd_rem_ver_cmd(uint8_t *cmdbuf);
 int ble_ll_conn_create(uint8_t *cmdbuf);
-int ble_ll_conn_update(uint8_t *cmdbuf);
-int ble_ll_conn_param_reply(uint8_t *cmdbuf, int negative_reply);
+int ble_ll_conn_hci_update(uint8_t *cmdbuf);
+int ble_ll_conn_hci_param_reply(uint8_t *cmdbuf, int negative_reply);
 int ble_ll_conn_create_cancel(void);
 void ble_ll_conn_num_comp_pkts_event_send(void);
 void ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/net/nimble/controller/src/ble_ll_ctrl.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_ctrl.c b/net/nimble/controller/src/ble_ll_ctrl.c
index 2eb072e..1e8ba74 100644
--- a/net/nimble/controller/src/ble_ll_ctrl.c
+++ b/net/nimble/controller/src/ble_ll_ctrl.c
@@ -139,6 +139,16 @@ ble_ll_ctrl_len_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
     return rc;
 }
 
+/**
+ * Called when we receive either a connection parameter request or response. 
+ * 
+ * @param connsm 
+ * @param dptr 
+ * @param rspbuf 
+ * @param opcode 
+ * 
+ * @return int 
+ */
 static int
 ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
                                 uint8_t *rspbuf, uint8_t opcode)
@@ -147,30 +157,30 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
     int indicate;
     uint8_t rsp_opcode;
     uint8_t ble_err;
-    struct ble_ll_conn_params cp;
     struct ble_ll_conn_params *req;
     struct hci_conn_update *hcu;
 
     /* Extract parameters and check if valid */
-    cp.interval_min = le16toh(dptr);
-    cp.interval_max = le16toh(dptr + 2);
-    cp.latency = le16toh(dptr + 4);
-    cp.timeout = le16toh(dptr + 6);
-    cp.pref_periodicity = dptr[8];
-    cp.ref_conn_event_cnt  = le16toh(dptr + 9);
-    cp.offset0 = le16toh(dptr + 11);
-    cp.offset1 = le16toh(dptr + 13);
-    cp.offset2 = le16toh(dptr + 15);
-    cp.offset3 = le16toh(dptr + 17);
-    cp.offset4 = le16toh(dptr + 19);
-    cp.offset5 = le16toh(dptr + 21);
+    req = &connsm->conn_cp;
+    req->interval_min = le16toh(dptr);
+    req->interval_max = le16toh(dptr + 2);
+    req->latency = le16toh(dptr + 4);
+    req->timeout = le16toh(dptr + 6);
+    req->pref_periodicity = dptr[8];
+    req->ref_conn_event_cnt  = le16toh(dptr + 9);
+    req->offset0 = le16toh(dptr + 11);
+    req->offset1 = le16toh(dptr + 13);
+    req->offset2 = le16toh(dptr + 15);
+    req->offset3 = le16toh(dptr + 17);
+    req->offset4 = le16toh(dptr + 19);
+    req->offset5 = le16toh(dptr + 21);
 
     /* Check if parameters are valid */
     ble_err = BLE_ERR_SUCCESS;
-    rc = ble_ll_conn_hci_chk_conn_params(cp.interval_min, 
-                                         cp.interval_max,
-                                         cp.latency, 
-                                         cp.timeout);
+    rc = ble_ll_conn_hci_chk_conn_params(req->interval_min, 
+                                         req->interval_max,
+                                         req->latency, 
+                                         req->timeout);
     if (rc) {
         ble_err = BLE_ERR_INV_LMP_LL_PARM;
         goto conn_param_pdu_exit;
@@ -182,20 +192,15 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
      * not have to notify the host.
      *  XXX: what if we dont like the parameters? When do we check that out?
      */ 
-    req = NULL;
     indicate = 1;
-    if ((connsm->conn_itvl >= cp.interval_min) && 
-        (connsm->conn_itvl <= cp.interval_max) &&
-        (connsm->supervision_tmo == cp.timeout) &&
-        (connsm->slave_latency == cp.latency)) {
-        indicate = 0;
-        /* XXX: For now, if we are a master, we wont send a response that
-         * needs to remember the request. That might change with connection
-           update pdu. Not sure. */
-        if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
-            req = &cp;
+    if (opcode == BLE_LL_CTRL_CONN_PARM_REQ) {
+        if ((connsm->conn_itvl >= req->interval_min) &&
+            (connsm->conn_itvl <= req->interval_max) &&
+            (connsm->supervision_tmo == req->timeout) &&
+            (connsm->slave_latency == req->latency)) {
+            indicate = 0;
+            goto conn_parm_req_do_indicate;
         }
-        goto conn_parm_req_do_indicate;
     }
 
     /* 
@@ -216,12 +221,12 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
          */
         hcu = &connsm->conn_param_req;
         if (hcu->handle != 0) {
-            if (!((cp.interval_min < hcu->conn_itvl_min) ||
-                  (cp.interval_min > hcu->conn_itvl_max) ||
-                  (cp.interval_max < hcu->conn_itvl_min) ||
-                  (cp.interval_max > hcu->conn_itvl_max) ||
-                  (cp.latency != hcu->conn_latency) ||
-                  (cp.timeout != hcu->supervision_timeout))) {
+            if (!((req->interval_min < hcu->conn_itvl_min) ||
+                  (req->interval_min > hcu->conn_itvl_max) ||
+                  (req->interval_max < hcu->conn_itvl_min) ||
+                  (req->interval_max > hcu->conn_itvl_max) ||
+                  (req->latency != hcu->conn_latency) ||
+                  (req->timeout != hcu->supervision_timeout))) {
                 indicate = 0;
             }
         }
@@ -237,7 +242,8 @@ conn_parm_req_do_indicate:
          * Send event to host. At this point we leave and wait to get
          * an answer.
          */ 
-        ble_ll_hci_ev_rem_conn_parm_req(connsm, &cp);
+        /* XXX: what about masked out event? */
+        ble_ll_hci_ev_rem_conn_parm_req(connsm, req);
         connsm->host_reply_opcode = opcode;
         connsm->awaiting_host_reply = 1;
         rsp_opcode = 255;
@@ -336,10 +342,9 @@ static void
 ble_ll_ctrl_conn_param_pdu_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
                                 struct ble_ll_conn_params *req)
 {
-    uint16_t invalid_offset;
+    uint16_t offset;
     struct hci_conn_update *hcu;
 
-    invalid_offset = 0xFFFF;
     /* If we were passed in a request, we use the parameters from the request */
     if (req) {
         htole16(dptr, req->interval_min);
@@ -368,12 +373,13 @@ ble_ll_ctrl_conn_param_pdu_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
     htole16(dptr + 9, connsm->event_cntr);
 
     /* XXX: For now, dont use offsets */
-    htole16(dptr + 11, invalid_offset);
-    htole16(dptr + 13, invalid_offset);
-    htole16(dptr + 15, invalid_offset);
-    htole16(dptr + 17, invalid_offset);
-    htole16(dptr + 19, invalid_offset);
-    htole16(dptr + 21, invalid_offset);
+    offset = 0xFFFF;
+    htole16(dptr + 11, offset);
+    htole16(dptr + 13, offset);
+    htole16(dptr + 15, offset);
+    htole16(dptr + 17, offset);
+    htole16(dptr + 19, offset);
+    htole16(dptr + 21, offset);
 }
 
 static void
@@ -397,16 +403,17 @@ ble_ll_ctrl_version_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld)
  * @param rsp 
  */
 static void
-ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld)
+ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld,
+                          struct ble_ll_conn_params *cp)
 {
     uint16_t instant;
+    uint32_t dt;
+    uint32_t num_old_ce;
+    uint32_t new_itvl_usecs;
+    uint32_t old_itvl_usecs;
     struct hci_conn_update *hcu;
     struct ble_ll_conn_upd_req *req;
 
-    /* Make sure we have the parameters! */
-    assert(connsm->conn_param_req.handle != 0);
-
-
     /* 
      * Set instant. We set the instant to the current event counter plus
      * the amount of slave latency as the slave may not be listening
@@ -423,11 +430,41 @@ ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld)
     /* Copy parameters in connection update structure */
     hcu = &connsm->conn_param_req;
     req = &connsm->conn_update_req;
-    req->winsize = connsm->tx_win_size;
-    req->winoffset = 0;
-    req->interval = hcu->conn_itvl_max;
-    req->timeout = hcu->supervision_timeout;
-    req->latency = hcu->conn_latency;
+    if (cp) {
+        /* XXX: so we need to make the new anchor point some time away
+         * from txwinoffset by some amount of msecs. Not sure how to do
+           that here. We dont need to, but we should. */
+        /* Calculate offset from requested offsets (if any) */
+        if (cp->offset0 != 0xFFFF) {
+            new_itvl_usecs = cp->interval_max * BLE_LL_CONN_ITVL_USECS;
+            old_itvl_usecs = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS;
+            if ((int16_t)(cp->ref_conn_event_cnt - instant) >= 0) {
+                num_old_ce = cp->ref_conn_event_cnt - instant;
+                dt = old_itvl_usecs * num_old_ce;
+                dt += (cp->offset0 * BLE_LL_CONN_ITVL_USECS);
+                dt = dt % new_itvl_usecs;
+            } else {
+                num_old_ce = instant - cp->ref_conn_event_cnt;
+                dt = old_itvl_usecs * num_old_ce;
+                dt -= (cp->offset0 * BLE_LL_CONN_ITVL_USECS);
+                dt = dt % new_itvl_usecs;
+                dt = new_itvl_usecs - dt;
+            }
+            req->winoffset = dt / BLE_LL_CONN_TX_WIN_USECS;
+        } else {
+            req->winoffset = 0;
+        }
+        req->interval = cp->interval_max;
+        req->timeout = cp->timeout;
+        req->latency = cp->latency;
+        req->winsize = 1;
+    } else {
+        req->interval = hcu->conn_itvl_max;
+        req->timeout = hcu->supervision_timeout;
+        req->latency = hcu->conn_latency;
+        req->winoffset = 0;
+        req->winsize = connsm->tx_win_size;
+    }
     req->instant = instant;
 
     /* XXX: make sure this works for the connection parameter request proc. */
@@ -464,7 +501,7 @@ ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm *connsm, uint8_t *rsp,
         rsp_opcode = BLE_LL_CTRL_CONN_PARM_RSP;
     } else {
         /* Create a connection update pdu */
-        ble_ll_ctrl_conn_upd_make(connsm, rsp + 1);
+        ble_ll_ctrl_conn_upd_make(connsm, rsp + 1, req);
         rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_REQ;
     }
 
@@ -493,12 +530,6 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
         return BLE_ERR_MAX;
     }
 
-#if 0
-    /* Deal with receiving this when in this state. I think we are done */
-    if (IS_PENDING_CTRL_PROC_M(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) {
-    }
-#endif
-
     /* Retrieve parameters */
     reqdata = &connsm->conn_update_req;
     reqdata->winsize = dptr[0]; 
@@ -727,7 +758,7 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc)
         switch (ctrl_proc) {
         case BLE_LL_CTRL_PROC_CONN_UPDATE:
             opcode = BLE_LL_CTRL_CONN_UPDATE_REQ;
-            ble_ll_ctrl_conn_upd_make(connsm, dptr + 1);
+            ble_ll_ctrl_conn_upd_make(connsm, dptr + 1, NULL);
             break;
         case BLE_LL_CTRL_PROC_FEATURE_XCHG:
             if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/net/nimble/controller/src/ble_ll_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_hci.c b/net/nimble/controller/src/ble_ll_hci.c
index 3fb1127..fd79d6f 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -357,7 +357,7 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
         break;
     case BLE_HCI_OCF_LE_CONN_UPDATE:
         if (len == BLE_HCI_CONN_UPDATE_LEN) {
-            rc = ble_ll_conn_update(cmdbuf);
+            rc = ble_ll_conn_hci_update(cmdbuf);
         }
         /* This is a hack; command status gets sent instead of cmd complete */
         rc += (BLE_ERR_MAX + 1);
@@ -374,13 +374,13 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
 
     case BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR:
         if (len == BLE_HCI_CONN_PARAM_NEG_REPLY_LEN) {
-            rc = ble_ll_conn_param_reply(cmdbuf, 0);
+            rc = ble_ll_conn_hci_param_reply(cmdbuf, 0);
         }
         break;
 
     case BLE_HCI_OCF_LE_REM_CONN_PARAM_RR:
         if (len == BLE_HCI_CONN_PARAM_REPLY_LEN) {
-            rc = ble_ll_conn_param_reply(cmdbuf, 1);
+            rc = ble_ll_conn_hci_param_reply(cmdbuf, 1);
         }
         break;
 
@@ -518,7 +518,6 @@ ble_ll_hci_info_params_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
     return rc;
 }
 
-
 void
 ble_ll_hci_cmd_proc(struct os_event *ev)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/net/nimble/controller/src/ble_ll_hci_ev.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_hci_ev.c b/net/nimble/controller/src/ble_ll_hci_ev.c
index 7bebc5f..500525f 100644
--- a/net/nimble/controller/src/ble_ll_hci_ev.c
+++ b/net/nimble/controller/src/ble_ll_hci_ev.c
@@ -94,12 +94,10 @@ ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm *connsm, uint8_t status)
             evbuf[1] = BLE_HCI_LE_CONN_UPD_LEN;
             evbuf[2] = BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE;
             evbuf[3] = status;
-            if (status == BLE_ERR_SUCCESS) {
-                htole16(evbuf + 4, connsm->conn_handle);
-                htole16(evbuf + 6, connsm->conn_itvl);
-                htole16(evbuf + 8, connsm->slave_latency);
-                htole16(evbuf + 10, connsm->supervision_tmo);
-            }
+            htole16(evbuf + 4, connsm->conn_handle);
+            htole16(evbuf + 6, connsm->conn_itvl);
+            htole16(evbuf + 8, connsm->slave_latency);
+            htole16(evbuf + 10, connsm->supervision_tmo);
             ble_ll_hci_event_send(evbuf);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/net/nimble/controller/src/ble_ll_sched.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_sched.c b/net/nimble/controller/src/ble_ll_sched.c
index 9a639f1..6a0e8cb 100644
--- a/net/nimble/controller/src/ble_ll_sched.c
+++ b/net/nimble/controller/src/ble_ll_sched.c
@@ -50,7 +50,7 @@ TAILQ_HEAD(ll_sched_qhead, ble_ll_sched_item) g_ble_ll_sched_q;
  * @param s1 
  * @param s2 
  * 
- * @return int 
+ * @return int 0: dont overlap 1:overlap
  */
 static int
 ble_ll_sched_is_overlap(struct ble_ll_sched_item *s1, 
@@ -94,6 +94,13 @@ ble_ll_sched_chk_scan_overlap(struct ble_ll_sched_item *scan,
         ble_ll_event_send(&scansm->scan_sched_ev);
         TAILQ_REMOVE(&g_ble_ll_sched_q, scan, link);
         scan->enqueued = 0;
+    } else {
+        /* If scheduled item is before the scan item, we need to reinsert */
+        if ((int32_t)(sch->end_time - scan->start_time) <= 0) {
+            TAILQ_REMOVE(&g_ble_ll_sched_q, scan, link);
+            scan->enqueued = 0;
+            ble_ll_sched_scan(scan);
+        }
     }
 }
 
@@ -326,21 +333,13 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, uint32_t adv_rxend,
     } else {
         cputime_timer_stop(&g_ble_ll_sched_timer);
         TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
-            /* Ignore scan/initiate types */
-            if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) {
-                scan = entry;
-                continue;
-            }
-
-            /* Set these because the overlap function needs them to be set */
+            /* Set these because overlap function needs them to be set */
             sch->start_time = earliest_start;
             sch->end_time = earliest_end;
 
-            /* Check for overlapping events */
-            if (ble_ll_sched_is_overlap(sch, entry)) {
-                /* Earliest start is end of this event since we overlap */
-                earliest_start = entry->end_time;
-                earliest_end = earliest_start + dur;
+            /* Ignore scan/initiate types */
+            if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) {
+                scan = entry;
             } else {
                 /* We can insert if before entry in list */
                 if ((int32_t)(sch->end_time - entry->start_time) < 0) {
@@ -350,6 +349,13 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, uint32_t adv_rxend,
                     }
                     break;
                 }
+
+                /* Check for overlapping events */
+                if (ble_ll_sched_is_overlap(sch, entry)) {
+                    /* Earliest start is end of this event since we overlap */
+                    earliest_start = entry->end_time;
+                    earliest_end = earliest_start + dur;
+                }
             }
         }
 
@@ -386,6 +392,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, uint32_t adv_rxend,
          */
         if (scan) {
             ble_ll_sched_chk_scan_overlap(scan, sch);
+            sch = TAILQ_FIRST(&g_ble_ll_sched_q);
         }
     }
 
@@ -434,22 +441,23 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm)
         cputime_timer_stop(&g_ble_ll_sched_timer);
         while (1) {
             /* Skip scanning schedule items */
+            next_sch = entry->link.tqe_next;
             if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) {
                 scan = entry;
-                continue;
-            }
-
-            next_sch = entry->link.tqe_next;
-            if (ble_ll_sched_is_overlap(sch, entry)) {
-                if (ble_ll_sched_conn_overlap(entry)) {
-                    break;
-                }
             } else {
+                /* Insert if event ends before next starts */
                 if ((int32_t)(sch->end_time - entry->start_time) < 0) {
                     rc = 0;
                     TAILQ_INSERT_BEFORE(entry, sch, link);
                     break;
                 }
+
+                if (ble_ll_sched_is_overlap(sch, entry)) {
+                    /* If we overlap with a connection, we re-schedule */
+                    if (ble_ll_sched_conn_overlap(entry)) {
+                        break;
+                    }
+                }
             }
 
             /* Move to next entry */
@@ -519,14 +527,6 @@ ble_ll_sched_adv_new(struct ble_ll_sched_item *sch)
             /* Ignore scan/initiate types */
             if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) {
                 scan = entry;
-                continue;
-            }
-
-            /* Check for overlapping events */
-            if (ble_ll_sched_is_overlap(sch, entry)) {
-                /* Earliest start is end of this event since we overlap */
-                sch->start_time = entry->end_time;
-                sch->end_time = sch->start_time + duration;
             } else {
                 /* We can insert if before entry in list */
                 if ((int32_t)(sch->end_time - entry->start_time) < 0) {
@@ -534,6 +534,13 @@ ble_ll_sched_adv_new(struct ble_ll_sched_item *sch)
                     TAILQ_INSERT_BEFORE(entry, sch, link);
                     break;
                 }
+
+                /* Check for overlapping events */
+                if (ble_ll_sched_is_overlap(sch, entry)) {
+                    /* Earliest start is end of this event since we overlap */
+                    sch->start_time = entry->end_time;
+                    sch->end_time = sch->start_time + duration;
+                }
             }
         }
 
@@ -558,6 +565,12 @@ ble_ll_sched_adv_new(struct ble_ll_sched_item *sch)
 
     OS_EXIT_CRITICAL(sr);
 
+    /* XXX: some things to test. I am not sure that if we are passed the
+       output compare that we actually get the interrupt. */
+    /* XXX: I am not sure that if we receive a packet while scanning
+     * that we actually go back to scanning. I need to make sure
+       we re-enable the receive. Put an event in the log! */
+
     cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time);
 
     return rc;
@@ -572,6 +585,7 @@ ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch)
     struct ble_ll_sched_item *next_sch;
     struct ble_ll_sched_item *scan;
 
+    rc = 0;
     OS_ENTER_CRITICAL(sr);
 
     /* The schedule item must occur after current running item (if any) */
@@ -581,30 +595,27 @@ ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch)
     }
 
     entry = ble_ll_sched_insert_if_empty(sch);
-    if (!entry) {
-        /* Nothing in schedule. Schedule as soon as possible */
-        rc = 0;
-    } else {
+    if (entry) {
         scan = NULL;
         cputime_timer_stop(&g_ble_ll_sched_timer);
         while (1) {
             /* Skip scanning schedule items */
+            next_sch = entry->link.tqe_next;
             if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) {
                 scan = entry;
-                continue;
-            }
-
-            next_sch = entry->link.tqe_next;
-            if (ble_ll_sched_is_overlap(sch, entry)) {
-                if (ble_ll_sched_conn_overlap(entry)) {
-                    assert(0);
-                }
             } else {
+                /* Insert before if adv event is before this event */
                 if ((int32_t)(sch->end_time - entry->start_time) < 0) {
                     rc = 0;
                     TAILQ_INSERT_BEFORE(entry, sch, link);
                     break;
                 }
+
+                if (ble_ll_sched_is_overlap(sch, entry)) {
+                    if (ble_ll_sched_conn_overlap(entry)) {
+                        assert(0);
+                    }
+                }
             }
 
             /* Move to next entry */
@@ -642,27 +653,27 @@ ble_ll_sched_scan(struct ble_ll_sched_item *sch)
     os_sr_t sr;
     struct ble_ll_sched_item *entry;
 
+    /* Assume insert to head */
+    insert_head = 1;
+
     OS_ENTER_CRITICAL(sr);
 
     entry = ble_ll_sched_insert_if_empty(sch);
-    if (!entry) {
-        insert_head = 1;
-    } else {
+    if (entry) {
         TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
             /* No need to worry about overlap. */
             if ((int32_t)(sch->start_time - entry->start_time) < 0) {
                 TAILQ_INSERT_BEFORE(entry, sch, link);
                 break;
             }
+            insert_head = 0;
         }
 
-        insert_head = 0;
         if (!entry) {
             TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link);
         } else {
-            if (sch == TAILQ_FIRST(&g_ble_ll_sched_q)) {
+            if (insert_head) {
                 cputime_timer_stop(&g_ble_ll_sched_timer);
-                insert_head = 1;
             }
         }
         sch->enqueued = 1;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/project/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c
index 4658e06..cce96ad 100755
--- a/project/bletest/src/main.c
+++ b/project/bletest/src/main.c
@@ -66,8 +66,8 @@ os_membuf_t g_mbuf_buffer[MBUF_MEMPOOL_SIZE];
 #define BLETEST_ROLE_ADVERTISER         (0)
 #define BLETEST_ROLE_SCANNER            (1)
 #define BLETEST_ROLE_INITIATOR          (2)
-//#define BLETEST_CFG_ROLE                (BLETEST_ROLE_INITIATOR)
-#define BLETEST_CFG_ROLE                (BLETEST_ROLE_ADVERTISER)
+#define BLETEST_CFG_ROLE                (BLETEST_ROLE_INITIATOR)
+//#define BLETEST_CFG_ROLE                (BLETEST_ROLE_ADVERTISER)
 #define BLETEST_CFG_FILT_DUP_ADV        (0)
 #define BLETEST_CFG_ADV_ITVL            (60000 / BLE_HCI_ADV_ITVL)
 #define BLETEST_CFG_ADV_TYPE            BLE_HCI_ADV_TYPE_ADV_IND
@@ -96,6 +96,8 @@ struct os_callout_func g_bletest_timer;
 struct os_task bletest_task;
 sec_bss_nz_core os_stack_t bletest_stack[BLETEST_STACK_SIZE];
 uint32_t g_bletest_conn_end;
+int g_bletest_start_update;
+uint32_t g_bletest_conn_upd_time;
 uint8_t g_bletest_current_conns;
 uint8_t g_bletest_cur_peer_addr[BLE_DEV_ADDR_LEN];
 uint8_t g_last_handle_used;
@@ -130,6 +132,25 @@ bletest_inc_adv_pkt_num(void)
 }
 #endif
 
+void
+bletest_send_conn_update(uint16_t handle)
+{
+    int rc;
+    struct hci_conn_update hcu;
+
+    hcu.conn_latency = 4;
+    hcu.supervision_timeout = 2000; 
+    hcu.conn_itvl_min = 1000;
+    hcu.conn_itvl_max = 1000;
+    hcu.handle = handle;
+    hcu.min_ce_len = 4;
+    hcu.max_ce_len = 4;
+
+    rc = host_hci_cmd_le_conn_update(&hcu);
+    assert(rc == 0);
+    host_hci_outstanding_opcode = 0;
+}
+
 /**
  * Sets the advertising data to be sent in advertising pdu's which contain
  * advertising data.
@@ -329,7 +350,6 @@ bletest_execute(void)
 {
     int rc;
     uint16_t handle;
-    struct hci_conn_update hcu;
 
     /* 
      * Determine if there is an active connection for the current handle
@@ -367,21 +387,14 @@ bletest_execute(void)
             g_next_os_time += OS_TICKS_PER_SEC * 5;
         } else {
             if (g_next_os_time != 0xffffffff) {
+#if 1
                 if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
-                    hcu.conn_latency = 4;
-                    hcu.supervision_timeout = 2000; 
-                    hcu.conn_itvl_min = 1000;
-                    hcu.conn_itvl_max = 1000;
-                    hcu.handle = 1;
-                    hcu.min_ce_len = 4;
-                    hcu.max_ce_len = 4;
-
-                    rc = host_hci_cmd_le_conn_update(&hcu);
-                    assert(rc == 0);
-                    host_hci_outstanding_opcode = 0;
-
+                    bletest_send_conn_update(1);
                     g_next_os_time = 0xffffffff;
                 }
+#else
+                g_next_os_time = 0xffffffff;
+#endif
             }
         }
     }
@@ -505,6 +518,10 @@ bletest_execute(void)
             host_hci_outstanding_opcode = 0;
             assert(rc == 0);
 
+            /* set conn update time */
+            g_bletest_conn_upd_time = os_time_get() + (OS_TICKS_PER_SEC * 5);
+            g_bletest_start_update = 1;
+
             /* Add to current connections */
             ++g_bletest_current_conns;
 
@@ -520,7 +537,14 @@ bletest_execute(void)
             }
         }
     }
-
+#if 0
+    if (g_bletest_start_update) {
+        if ((int32_t)(os_time_get() - g_bletest_conn_upd_time) >= 0) {
+            bletest_send_conn_update(1);
+            g_bletest_start_update = 0;
+        }
+    }
+#endif
     /* See if it is time to hand a data packet to the connection */
     if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
         if (g_bletest_current_conns) {