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 2015/12/10 19:04:27 UTC

incubator-mynewt-larva git commit: Fix a number of issues with high duty cycle advertising and direct advertising in general.

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master cabd20eb7 -> 4a12d183b


Fix a number of issues with high duty cycle advertising and direct advertising in general.


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/4a12d183
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/4a12d183
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/4a12d183

Branch: refs/heads/master
Commit: 4a12d183bb2234c8ad807eea4241cd7713eb7b08
Parents: cabd20e
Author: wes3 <wi...@micosa.io>
Authored: Thu Dec 10 10:04:07 2015 -0800
Committer: wes3 <wi...@micosa.io>
Committed: Thu Dec 10 10:04:17 2015 -0800

----------------------------------------------------------------------
 .../controller/include/controller/ble_ll_adv.h  |   3 +
 .../controller/include/controller/ble_ll_conn.h |   9 +-
 net/nimble/controller/src/ble_ll.c              |  10 +-
 net/nimble/controller/src/ble_ll_adv.c          | 153 +++++++++++++++----
 net/nimble/controller/src/ble_ll_conn.c         |   8 +-
 net/nimble/controller/src/ble_ll_ctrl.c         |  24 ++-
 project/bletest/bletest.yml                     |   1 +
 project/bletest/src/main.c                      |  85 +++++++----
 8 files changed, 202 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/4a12d183/net/nimble/controller/include/controller/ble_ll_adv.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_adv.h b/net/nimble/controller/include/controller/ble_ll_adv.h
index 1e985b0..725dfd9 100644
--- a/net/nimble/controller/include/controller/ble_ll_adv.h
+++ b/net/nimble/controller/include/controller/ble_ll_adv.h
@@ -119,6 +119,9 @@ void ble_ll_adv_tx_done_proc(void *arg);
 /* Called to initialize advertising functionality. */
 void ble_ll_adv_init(void);
 
+/* Called on rx pdu start when in advertising state */
+int ble_ll_adv_rx_pdu_start(uint8_t pdu_type, struct os_mbuf *rxpdu);
+
 /* Called on rx pdu end when in advertising state */
 int ble_ll_adv_rx_pdu_end(uint8_t pdu_type, struct os_mbuf *rxpdu);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/4a12d183/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 6b61c6d..5236dec 100644
--- a/net/nimble/controller/include/controller/ble_ll_conn.h
+++ b/net/nimble/controller/include/controller/ble_ll_conn.h
@@ -142,25 +142,24 @@ struct ble_ll_conn_sm
 };
 
 /* API */
-struct ble_ll_len_req;
+void ble_ll_conn_init(void);
 int ble_ll_conn_create(uint8_t *cmdbuf);
 int ble_ll_conn_create_cancel(void);
-int ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva);
-int ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva);
 void ble_ll_init_rx_pdu_proc(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr);
 int ble_ll_init_rx_pdu_end(struct os_mbuf *rxpdu);
 int ble_ll_conn_slave_start(uint8_t *rxbuf);
 void ble_ll_conn_spvn_timeout(void *arg);
 void ble_ll_conn_event_end(void *arg);
-void ble_ll_conn_init(void);
 void ble_ll_conn_rx_pdu_start(void);
 int ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint8_t crcok);
 void ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok);
 void ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t len);
 void ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err);
 void ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om);
+void ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status);
+
+struct ble_ll_len_req;
 void ble_ll_conn_datalen_update(struct ble_ll_conn_sm *connsm, 
                                 struct ble_ll_len_req *req);
 
-
 #endif /* H_BLE_LL_CONN_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/4a12d183/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 667150c..005d3f7 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -522,15 +522,7 @@ ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
 
     switch (g_ble_ll_data.ll_state) {
     case BLE_LL_STATE_ADV:
-        /* If we get a scan request we must tell the phy to go from rx to tx */
-        if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
-            rc = 1;
-        } else if (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_REQ) {
-            rc = 0;
-        } else {
-            /* This is a frame we dont want. Just abort it */
-            rc = -1;
-        }
+        rc = ble_ll_adv_rx_pdu_start(pdu_type, rxpdu);
         break;
     case BLE_LL_STATE_INITIATING:
         if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) ||

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/4a12d183/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 dcfe86d..5b901d2 100644
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -35,7 +35,7 @@
  * fixed for now but could be considered "configuration" parameters for either
  * the device or the stack.
  */
-#define BLE_LL_CFG_ADV_PDU_ITVL_HD_USECS    (5000)  /* usecs */
+#define BLE_LL_CFG_ADV_PDU_ITVL_HD_USECS    (1250)  /* usecs */
 #define BLE_LL_CFG_ADV_PDU_ITVL_LD_USECS    (10000) /* usecs */
 #define BLE_LL_CFG_ADV_TXPWR                (0)     /* dBm */
 
@@ -43,8 +43,7 @@
  * 1) Need to look at advertising and scan request PDUs. Do I allocate these
  * once? Do I use a different pool for smaller ones? Do I statically declare
  * them?
- * 2) The random address and initiator address (if doing directed adv) is not
- * set yet. Determine how that is to be done.
+ * 2) Only public device addresses supported right now.
  * 3) How do features get supported? What happens if device does not support
  * advertising? (for example)
  * 4) Correct calculation of schedule start and end times for the various
@@ -53,19 +52,9 @@
  * now, we set it to max.
  * 6) Currently, when we set scheduling events, we dont take into account
  * processor overhead/delays. We will want to do that.
- * 8) For set adv enable command: if we get a connection, or we time out,
- *    we need to send a CONNECTION COMPLETE event. Do this.
- * 9) How does the advertising channel tx power get set? I dont implement
+ * 7) How does the advertising channel tx power get set? I dont implement
  * that currently.
- * 10) Deal with whitelisting at LL when pdu is handed up to LL task.
- * 11) What about High duty cycle advertising? Do we exit the advertising state
- * after 1.28 seconds automatically? Seems like we do!!! 4.4.2.4.2 Vol 6 Part B
- * => YES! we have to implement this and set back a CONN COMPLETE event with
- *    error code DIRECTED ADV TIMEOUT.
- * 12) Something to consider: if we are attempting to advertise but dont have
- * any connection state machines available, I dont think we should enable
- * advertising.
- * 13) Implement high duty cycle advertising timeout.
+ * 8) Deal with whitelisting at LL when pdu is handed up to LL task.
  */
 
 /* 
@@ -94,6 +83,7 @@ struct ble_ll_adv_sm
     uint32_t adv_itvl_usecs;
     uint32_t adv_event_start_time;
     uint32_t adv_pdu_start_time;
+    uint32_t adv_dir_hd_end_time;
     uint8_t initiator_addr[BLE_DEV_ADDR_LEN];
     uint8_t adv_data[BLE_ADV_DATA_MAX_LEN];
     uint8_t scan_rsp_data[BLE_SCAN_RSP_DATA_MAX_LEN];
@@ -224,6 +214,10 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm)
         pdu_type = BLE_ADV_PDU_TYPE_ADV_DIRECT_IND;
         adv_data_len = 0;
         pdulen = BLE_ADV_DIRECT_IND_LEN;
+
+        if (advsm->peer_addr_type == BLE_HCI_ADV_PEER_ADDR_RANDOM) {
+            pdu_type |= BLE_ADV_PDU_HDR_RXADD_RAND;
+        }
         break;
 
         /* Set these to avoid compiler warnings */
@@ -453,6 +447,12 @@ ble_ll_adv_sched_set(struct ble_ll_adv_sm *advsm)
         if (advsm->adv_type != BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
             max_usecs += BLE_LL_ADV_SCHED_MAX_USECS;
         }
+        /* 
+         * XXX: what exactly is done with the schedule end time here? It
+         * may be off when we initially start advertising since we have
+         * already passed the start time and the pdu will get transmitted
+         * well after adv_pdu_start_time 
+         */
         sch->end_time = advsm->adv_pdu_start_time +
             cputime_usecs_to_ticks(max_usecs);
 
@@ -501,15 +501,23 @@ ble_ll_adv_set_adv_params(uint8_t *cmd)
     adv_itvl_max = le16toh(cmd + 2);
     adv_type = cmd[4];
 
-    /* Min has to be less than max */
-    if (adv_itvl_min > adv_itvl_max) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
+    /* 
+     * Get the filter policy now since we will ignore it if we are doing
+     * directed advertising
+     */
+    adv_filter_policy = cmd[14];
 
     switch (adv_type) {
-    case BLE_HCI_ADV_TYPE_ADV_IND:
     case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD:
     case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD:
+        adv_filter_policy = BLE_HCI_ADV_FILT_NONE;
+        memcpy(advsm->initiator_addr, cmd + 7, BLE_DEV_ADDR_LEN);
+        /* Ignore min/max interval */
+        min_itvl = 0;
+        adv_itvl_min = 0;
+        adv_itvl_max = 0;
+        break;
+    case BLE_HCI_ADV_TYPE_ADV_IND:
         min_itvl = BLE_LL_ADV_ITVL_MIN;
         break;
     case BLE_HCI_ADV_TYPE_ADV_NONCONN_IND:
@@ -522,7 +530,9 @@ ble_ll_adv_set_adv_params(uint8_t *cmd)
     }
 
     /* Make sure interval minimum is valid for the advertising type */
-    if ((adv_itvl_min < min_itvl) || (adv_itvl_min > BLE_HCI_ADV_ITVL_MAX)) {
+    if ((adv_itvl_min > adv_itvl_max) || (adv_itvl_min < min_itvl) || 
+        (adv_itvl_min > BLE_HCI_ADV_ITVL_MAX) || 
+        (adv_itvl_max > BLE_HCI_ADV_ITVL_MAX)) {
         return BLE_ERR_INV_HCI_CMD_PARMS;
     }
 
@@ -542,7 +552,6 @@ ble_ll_adv_set_adv_params(uint8_t *cmd)
     }
 
     /* Check for valid filter policy */
-    adv_filter_policy = cmd[14];
     if (adv_filter_policy > BLE_HCI_ADV_FILT_MAX) {
         return BLE_ERR_INV_HCI_CMD_PARMS;
     }
@@ -551,7 +560,6 @@ ble_ll_adv_set_adv_params(uint8_t *cmd)
        own address type or peer address type */
     advsm->own_addr_type = own_addr_type;
     advsm->peer_addr_type = peer_addr_type;
-
     advsm->adv_filter_policy = adv_filter_policy;
     advsm->adv_chanmask = adv_chanmask;
     advsm->adv_itvl_min = adv_itvl_min;
@@ -619,7 +627,13 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm)
     advsm->enabled = 1;
 
     /* Determine the advertising interval we will use */
-    advsm->adv_itvl_usecs = (uint32_t)advsm->adv_itvl_max * BLE_LL_ADV_ITVL;
+    if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
+        /* Set it to max. allowed for high duty cycle advertising */
+        advsm->adv_itvl_usecs = BLE_LL_ADV_PDU_ITVL_HD_MS_MAX;
+    } else {
+        advsm->adv_itvl_usecs = (uint32_t)advsm->adv_itvl_max;
+        advsm->adv_itvl_usecs *= BLE_LL_ADV_ITVL;
+    }
 
     /* Create the advertising PDU */
     ble_ll_adv_pdu_make(advsm);
@@ -649,6 +663,14 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm)
     advsm->adv_event_start_time = cputime_get32();
     advsm->adv_pdu_start_time = advsm->adv_event_start_time;
 
+    /* 
+     * Set the time at which we must end directed, high-duty cycle advertising.
+     * Does not matter that we calculate this value if we are not doing high
+     * duty cycle advertising.
+     */
+    advsm->adv_dir_hd_end_time = advsm->adv_event_start_time +
+        cputime_usecs_to_ticks(BLE_LL_ADV_STATE_HD_MAX * 1000);
+
     /* Set packet in schedule */
     sch = ble_ll_adv_sched_set(advsm);
     if (!sch) {
@@ -867,6 +889,7 @@ void
 ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, uint8_t flags)
 {
     int valid;
+    uint8_t *inita;
     struct ble_ll_adv_sm *advsm;
 
     /* Check filter policy. */
@@ -880,7 +903,21 @@ ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, uint8_t flags)
     } else {
         /* If this is for us? */
         if (!ble_ll_adv_addr_cmp(rxbuf)) {
-            valid = 1;
+            /* 
+             * Only accept connect requests from the desired address if we
+             * are doing directed advertising 
+             */
+            if ((advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) ||
+                (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) {
+                /* XXX: not sure if this works if address is random */
+                /* Compare addresses */
+                inita = rxbuf + BLE_LL_PDU_HDR_LEN;
+                if (!memcmp(advsm->initiator_addr, inita, BLE_DEV_ADDR_LEN)) {
+                    valid = 1;
+                }
+            } else {
+                valid = 1;
+            }
         }
     }
 
@@ -938,6 +975,50 @@ ble_ll_adv_rx_pdu_end(uint8_t pdu_type, struct os_mbuf *rxpdu)
 }
 
 /**
+ * Called when a receive PDU has started and we are advertising. 
+ *  
+ * Context: interrupt 
+ * 
+ * @param pdu_type 
+ * @param rxpdu 
+ * 
+ * @return int 
+ *   < 0: A frame we dont want to receive.
+ *   = 0: Continue to receive frame. Dont go from rx to tx
+ *   > 0: Continue to receive frame and go from rx to tx when done
+ */
+int
+ble_ll_adv_rx_pdu_start(uint8_t pdu_type, struct os_mbuf *rxpdu)
+{
+    int rc;
+    struct ble_ll_adv_sm *advsm;
+
+    /* Assume we will abort the frame */
+    rc = -1;
+
+    /* If we get a scan request we must tell the phy to go from rx to tx */
+    advsm = &g_ble_ll_adv_sm;
+    if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
+        /* Only accept scan requests if we are indirect adv or scan adv */
+        if ((advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_SCAN_IND) || 
+            (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_IND)) {
+            rc = 1;
+        } 
+    } else {
+        /* Only accept connect requests if we are indirect ordirect advertising */
+        if (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_REQ) {
+            if ((advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) || 
+                (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD) ||
+                (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_IND)) {
+                rc = 0;
+            } 
+        }
+    }
+
+    return rc;
+}
+
+/**
  * Process advertistement tx done event. 
  *  
  * Context: Link Layer task. 
@@ -958,7 +1039,9 @@ ble_ll_adv_tx_done_proc(void *arg)
     ble_ll_state_set(BLE_LL_STATE_STANDBY);
 
     /* For debug purposes */
+#ifdef BLETEST
     bletest_inc_adv_pkt_num();
+#endif
 
     /* 
      * Check if we have ended our advertising event. If our last advertising
@@ -979,7 +1062,9 @@ ble_ll_adv_tx_done_proc(void *arg)
 
         /* Calculate start time of next advertising event */
         itvl = advsm->adv_itvl_usecs;
-        itvl += rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
+        if (advsm->adv_type != BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
+            itvl += rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
+        }
         advsm->adv_event_start_time += cputime_usecs_to_ticks(itvl);
         advsm->adv_pdu_start_time = advsm->adv_event_start_time;
 
@@ -1023,7 +1108,9 @@ ble_ll_adv_tx_done_proc(void *arg)
         /* Calculate start time of next advertising event */
         while (delta_t < 0) {
             itvl = advsm->adv_itvl_usecs;
-            itvl += rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
+            if (advsm->adv_type != BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
+                itvl += rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
+            }
             itvl = cputime_usecs_to_ticks(itvl);
             advsm->adv_event_start_time += itvl;
             advsm->adv_pdu_start_time = advsm->adv_event_start_time;
@@ -1031,6 +1118,18 @@ ble_ll_adv_tx_done_proc(void *arg)
         }
     }
 
+    /* 
+     * Stop high duty cycle directed advertising if we have been doing
+     * it for more than 1.28 seconds
+     */ 
+    if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
+        if (advsm->adv_pdu_start_time >= advsm->adv_dir_hd_end_time) {
+            ble_ll_adv_sm_stop(advsm);
+            ble_ll_conn_comp_event_send(NULL, BLE_ERR_DIR_ADV_TMO);
+            return;
+        }
+    }
+
     if (!ble_ll_adv_sched_set(advsm)) {
         /* XXX: we will need to set a timer here to wake us up */
         assert(0);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/4a12d183/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 c86b659..86c681d 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -895,7 +895,7 @@ ble_ll_conn_sm_start(struct ble_ll_conn_sm *connsm)
  * 
  * @param status The BLE error code associated with the event
  */
-static void
+void
 ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status)
 {
     uint8_t *evbuf;
@@ -1451,7 +1451,7 @@ ble_ll_conn_create_cancel(void)
 }
 
 /* Returns true if the address matches the connection peer address */
-int
+static int
 ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva)
 {
     int rc;
@@ -1477,7 +1477,7 @@ ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva)
  * @param addr_type Address type of advertiser
  * @param adva Address of advertiser
  */
-int
+static int
 ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva)
 {
     int rc;
@@ -2035,7 +2035,7 @@ ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t length)
  *  
  * @param rxbuf Pointer to received PDU 
  *  
- * @return 0: connection started. 
+ * @return 0: connection not started; 1 connecton started 
  */
 int
 ble_ll_conn_slave_start(uint8_t *rxbuf)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/4a12d183/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 b04a02f..73d1727 100644
--- a/net/nimble/controller/src/ble_ll_ctrl.c
+++ b/net/nimble/controller/src/ble_ll_ctrl.c
@@ -30,27 +30,23 @@
  *  2) Should we create pool of control pdu's?. Dont need more
  *  than the # of connections and can probably deal with quite a few less
  *  if we have lots of connections.
- *  4) os_callout_func_init does not really need to be done every time I
- *  dont think. Do that once per connection when initialized?
- *  5) NOTE: some procedures are allowed to run while others are
+ *  3) NOTE: some procedures are allowed to run while others are
  *      running!!! Fix this in the code
- *  8) What about procedures that have been completed but try to restart?
- *  12) NOTE: there is a supported features procedure. However, in the case
+ *  4) What about procedures that have been completed but try to restart?
+ *  5) NOTE: there is a supported features procedure. However, in the case
  *  of data length extension, if the receiving device does not understand
  *  the pdu or it does not support data length extension, the LL_UNKNOWN_RSP
  *  pdu is sent. That needs to be processed...
- *  14) Will I need to know which procedures actually completed?
- *  15) We are supposed to remember when we do the data length update proc if
+ *  6) We are supposed to remember when we do the data length update proc if
  *  the device sent us an unknown rsp. We should not send it another len req.
- *  Implement this.
- *  16) Remember: some procedures dont have timeout rules.
- *  17) remember to stop procedure when rsp received.
- *  18) Says that we should reset procedure timer whenever a LL control pdu
+ *  Implement this how? Through remote supported features?
+ *  7) Remember: some procedures dont have timeout rules.
+ *  8) remember to stop procedure when rsp received.
+ *  9) Says that we should reset procedure timer whenever a LL control pdu
  *  is queued for transmission. I dont get it... do some procedures send
  *  multiple packets? I guess so.
- *  19) How to count control pdus sent. DO we count enqueued + sent, or only
+ *  10) How to count control pdus sent. DO we count enqueued + sent, or only
  *  sent (actually attempted to tx). Do we count failures? How?
- * 
  */
 
 /* XXX: Improvements
@@ -224,7 +220,7 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc)
     uint8_t *dptr;
     struct os_mbuf *om;
 
-    /* XXX: assume for now that all procedures require an mbuf */
+    /* Get an mbuf for the control pdu */
     om = os_mbuf_get_pkthdr(&g_mbuf_pool, sizeof(struct ble_mbuf_hdr));
 
     if (om) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/4a12d183/project/bletest/bletest.yml
----------------------------------------------------------------------
diff --git a/project/bletest/bletest.yml b/project/bletest/bletest.yml
index 82b0a37..f4aafc5 100644
--- a/project/bletest/bletest.yml
+++ b/project/bletest/bletest.yml
@@ -5,3 +5,4 @@ project.eggs:
     - net/nimble/host
     - libs/console/full
     - libs/baselibc
+project.cflags: -DBLETEST

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/4a12d183/project/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c
index 6fbe3cd..e082257 100755
--- a/project/bletest/src/main.c
+++ b/project/bletest/src/main.c
@@ -65,7 +65,7 @@ os_membuf_t g_mbuf_buffer[MBUF_MEMPOOL_SIZE];
 #define BLETEST_CFG_ROLE                (BLETEST_ROLE_INITIATOR)
 #define BLETEST_CFG_FILT_DUP_ADV        (0)
 #define BLETEST_CFG_ADV_ITVL            (500000 / BLE_HCI_ADV_ITVL)
-#define BLETEST_CFG_ADV_TYPE            BLE_HCI_ADV_TYPE_ADV_IND
+#define BLETEST_CFG_ADV_TYPE            BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD
 #define BLETEST_CFG_ADV_FILT_POLICY     (BLE_HCI_ADV_FILT_NONE)
 #define BLETEST_CFG_SCAN_ITVL           (700000 / BLE_HCI_SCAN_ITVL)
 #define BLETEST_CFG_SCAN_WINDOW         (650000 / BLE_HCI_SCAN_ITVL)
@@ -95,27 +95,36 @@ bletest_inc_adv_pkt_num(void)
     uint8_t *dptr;
     uint8_t digit;
 
-    dptr = &g_host_adv_data[18];
-    while (dptr >= &g_host_adv_data[13]) {
-        digit = *dptr;
-        ++digit;
-        if (digit == 58) {
-            digit = 48;
-            *dptr = digit;
-            --dptr;
-        } else {
-            *dptr = digit;
-            break;
+    if (g_host_adv_len != 0) {
+        dptr = &g_host_adv_data[18];
+        while (dptr >= &g_host_adv_data[13]) {
+            digit = *dptr;
+            ++digit;
+            if (digit == 58) {
+                digit = 48;
+                *dptr = digit;
+                --dptr;
+            } else {
+                *dptr = digit;
+                break;
+            }
         }
-    }
 
-    rc = host_hci_cmd_le_set_adv_data(g_host_adv_data, g_host_adv_len);
-    assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
+        rc = host_hci_cmd_le_set_adv_data(g_host_adv_data, g_host_adv_len);
+        assert(rc == 0);
+        host_hci_outstanding_opcode = 0;
+    }
 }
 
+/**
+ * Sets the advertising data to be sent in advertising pdu's which contain
+ * advertising data.
+ *
+ * @param dptr
+ * @return uint8_t
+ */
 uint8_t
-bletest_create_adv_pdu(uint8_t *dptr)
+bletest_set_adv_data(uint8_t *dptr)
 {
     uint8_t len;
 
@@ -163,35 +172,47 @@ bletest_init_advertising(void)
 {
     int rc;
     uint8_t adv_len;
-    uint16_t adv_itvl;
     struct hci_adv_params adv;
 
-    /* Create the advertising PDU */
-    adv_len = bletest_create_adv_pdu(&g_host_adv_data[0]);
-
     /* Set advertising parameters */
-    adv_itvl = BLETEST_CFG_ADV_ITVL; /* Advertising interval */
     adv.adv_type = BLETEST_CFG_ADV_TYPE;
     adv.adv_channel_map = 0x07;
     adv.adv_filter_policy = BLETEST_CFG_ADV_FILT_POLICY;
     adv.own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
     adv.peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC;
-    adv.adv_itvl_min = BLE_HCI_ADV_ITVL_NONCONN_MIN;
-    adv.adv_itvl_max = adv_itvl;
+    if ((adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) ||
+        (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) {
+        adv.peer_addr[0] = 0x00;
+        adv.peer_addr[1] = 0x00;
+        adv.peer_addr[2] = 0x00;
+        adv.peer_addr[3] = 0x99;
+        adv.peer_addr[4] = 0x99;
+        adv.peer_addr[5] = 0x09;
+        adv.adv_itvl_min = 0;
+        adv.adv_itvl_max = 0;
+        adv_len = 0;
+    } else {
+        adv.adv_itvl_min = BLE_HCI_ADV_ITVL_NONCONN_MIN;
+        adv.adv_itvl_max = BLETEST_CFG_ADV_ITVL; /* Advertising interval */
+        adv_len = bletest_set_adv_data(&g_host_adv_data[0]);
+    }
+
+    /* Set the advertising parameters */
     rc = host_hci_cmd_le_set_adv_params(&adv);
     assert(rc == 0);
     host_hci_outstanding_opcode = 0;
 
-
     /* Set advertising data */
-    rc = host_hci_cmd_le_set_adv_data(&g_host_adv_data[0], adv_len);
-    assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
+    if (adv_len != 0) {
+        rc = host_hci_cmd_le_set_adv_data(&g_host_adv_data[0], adv_len);
+        assert(rc == 0);
+        host_hci_outstanding_opcode = 0;
 
-    /* Set scan response data */
-    rc = host_hci_cmd_le_set_scan_rsp_data(&g_host_adv_data[0], adv_len);
-    assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
+        /* Set scan response data */
+        rc = host_hci_cmd_le_set_scan_rsp_data(&g_host_adv_data[0], adv_len);
+        assert(rc == 0);
+        host_hci_outstanding_opcode = 0;
+    }
 }
 
 #if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)