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/18 19:16:42 UTC

incubator-mynewt-larva git commit: Fix the completed packets event; it used to be a continuous counter which was incorrect. It should bea delta from the last time we sent it. Add the HCI reset command. Fix the mbuf pool that the bletest code was allocati

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master af5a7a729 -> 958a0aeda


Fix the completed packets event; it used to be a continuous counter which was incorrect. It should bea delta from the last time we sent it. Add the HCI reset command. Fix the mbuf pool that the bletest code was allocating; the size of the mbuf was incorrect.


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

Branch: refs/heads/master
Commit: 958a0aedaec426718a6c9cecc87dc7584de92804
Parents: af5a7a7
Author: wes3 <wi...@micosa.io>
Authored: Fri Dec 18 10:16:29 2015 -0800
Committer: wes3 <wi...@micosa.io>
Committed: Fri Dec 18 10:16:35 2015 -0800

----------------------------------------------------------------------
 .../controller/include/controller/ble_ll.h      |  10 +-
 .../controller/include/controller/ble_ll_adv.h  |   6 +
 .../controller/include/controller/ble_ll_conn.h |   1 -
 .../controller/include/controller/ble_ll_scan.h |   3 +
 net/nimble/controller/src/ble_ll.c              |  78 +++++++++++
 net/nimble/controller/src/ble_ll_adv.c          |  29 ++++
 net/nimble/controller/src/ble_ll_conn.c         | 133 ++++++++++++-------
 net/nimble/controller/src/ble_ll_conn_hci.c     |   5 +-
 net/nimble/controller/src/ble_ll_conn_priv.h    |   1 +
 net/nimble/controller/src/ble_ll_hci.c          |  21 ++-
 net/nimble/controller/src/ble_ll_scan.c         |  37 +++++-
 net/nimble/drivers/nrf52/src/ble_phy.c          |  41 ++++--
 net/nimble/host/include/host/host_hci.h         |   1 +
 net/nimble/host/src/host_hci_cmd.c              |   2 +-
 project/bletest/src/main.c                      |   8 +-
 15 files changed, 311 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/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 4e3ee52..985a881 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -22,6 +22,9 @@
 /* Wait for response timer */
 typedef void (*ble_ll_wfr_func)(void *arg);
 
+/* Packet queue header definition */
+STAILQ_HEAD(ble_ll_pkt_q, os_mbuf_pkthdr);
+
 /* 
  * Global Link Layer data object. There is only one Link Layer data object
  * per controller although there may be many instances of the link layer state
@@ -44,11 +47,11 @@ struct ble_ll_obj
 
     /* Packet receive queue (and event). Holds received packets from PHY */
     struct os_event ll_rx_pkt_ev;
-    STAILQ_HEAD(ll_rxpkt_qh, os_mbuf_pkthdr) ll_rx_pkt_q;
+    struct ble_ll_pkt_q ll_rx_pkt_q;
 
     /* Packet transmit queue */
     struct os_event ll_tx_pkt_ev;
-    STAILQ_HEAD(ll_txpkt_qh, os_mbuf_pkthdr) ll_tx_pkt_q;
+    struct ble_ll_pkt_q ll_tx_pkt_q;
 };
 extern struct ble_ll_obj g_ble_ll_data;
 
@@ -245,6 +248,9 @@ struct ble_dev_addr
 /* Initialize the Link Layer */
 int ble_ll_init(void);
 
+/* Reset the Link Layer */
+int ble_ll_reset(void);
+
 /* 'Boolean' function returning true if address is a valid random address */
 int ble_ll_is_valid_random_addr(uint8_t *addr);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/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 725dfd9..bf9b233 100644
--- a/net/nimble/controller/include/controller/ble_ll_adv.h
+++ b/net/nimble/controller/include/controller/ble_ll_adv.h
@@ -119,6 +119,12 @@ void ble_ll_adv_tx_done_proc(void *arg);
 /* Called to initialize advertising functionality. */
 void ble_ll_adv_init(void);
 
+/* Called to initialize advertising functionality. */
+void ble_ll_adv_init(void);
+
+/* Called to reset the advertiser. */
+void ble_ll_adv_reset(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);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/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 1c4fc24..3188606 100644
--- a/net/nimble/controller/include/controller/ble_ll_conn.h
+++ b/net/nimble/controller/include/controller/ble_ll_conn.h
@@ -112,7 +112,6 @@ struct ble_ll_conn_sm
     uint16_t supervision_tmo;
     uint16_t conn_handle;
     uint16_t completed_pkts;
-    uint16_t last_completed_pkts;
     uint32_t access_addr;
     uint32_t crcinit;           /* only low 24 bits used */
     uint32_t anchor_point;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/net/nimble/controller/include/controller/ble_ll_scan.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_scan.h b/net/nimble/controller/include/controller/ble_ll_scan.h
index bb296e7..17c5cc3 100644
--- a/net/nimble/controller/include/controller/ble_ll_scan.h
+++ b/net/nimble/controller/include/controller/ble_ll_scan.h
@@ -101,6 +101,9 @@ void ble_ll_scan_win_end_proc(void *arg);
 /* Initialize the scanner */
 void ble_ll_scan_init(void);
 
+/* Reset the scanner */
+void ble_ll_scan_reset(void);
+
 /* Called when Link Layer starts to receive a PDU and is in scanning state */
 int ble_ll_scan_rx_pdu_start(uint8_t pdu_type, struct os_mbuf *rxpdu);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/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 5312a86..baced34 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -787,6 +787,84 @@ ble_ll_read_supp_features(void)
 }
 
 /**
+ * Flush a link layer packet queue.
+ * 
+ * @param pktq 
+ */
+static void
+ble_ll_flush_pkt_queue(struct ble_ll_pkt_q *pktq)
+{
+    struct os_mbuf_pkthdr *pkthdr;
+    struct os_mbuf *om;
+
+    /* FLush all packets from Link layer queues */
+    while (STAILQ_FIRST(pktq)) {
+        /* Get mbuf pointer from packet header pointer */
+        pkthdr = STAILQ_FIRST(pktq);
+        om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
+
+        /* Remove from queue and free the mbuf */
+        STAILQ_REMOVE_HEAD(pktq, omp_next);
+        os_mbuf_free(om);
+    }
+}
+
+/**
+ * Called to reset the controller. This performs a "software reset" of the link 
+ * layer; it does not perform a HW reset of the controller nor does it reset 
+ * the HCI interface. 
+ * 
+ * 
+ * @return int The ble error code to place in the command complete event that 
+ * is returned when this command is issued. 
+ */
+int
+ble_ll_reset(void)
+{
+    int rc;
+
+    /* XXX: what happens if we are transmitting and we call disable? */
+    /* XXX: what should we do to the transceiver/radio? Reset it? */
+    /* Stop the phy */
+    ble_phy_disable();
+
+    /* Stop any wait for response timer */
+    ble_ll_wfr_disable();
+
+    /* Stop any scanning */
+    ble_ll_scan_reset();
+
+    /* Stop any advertising */
+    ble_ll_adv_reset();
+
+    /* FLush all packets from Link layer queues */
+    ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_tx_pkt_q);
+    ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_rx_pkt_q);
+
+    /* Reset LL stats */
+    memset(&g_ble_ll_stats, 0, sizeof(struct ble_ll_stats));
+
+#ifdef BLE_LL_LOG
+    g_ble_ll_log_index = 0;
+    memset(&g_ble_ll_log, 0, sizeof(g_ble_ll_log));
+#endif
+
+    /* End all connections */
+    ble_ll_conn_reset();
+
+    /* All this does is re-initialize the event masks so call the hci init */
+    ble_ll_hci_init();
+
+    /* Set state to standby */
+    ble_ll_state_set(BLE_LL_STATE_STANDBY);
+
+    /* Re-initialize the PHY */
+    rc = ble_phy_init();
+
+    return rc;
+}
+
+/**
  * Initialize the Link Layer. Should be called only once 
  * 
  * @return int 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/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 0edf1f9..86478c1 100644
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -584,6 +584,9 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm)
 {
     /* XXX: Stop any timers we may have started */
 
+    /* XXX: what happens if we are transmitting a packet here? An advertising
+       one? Does it matter? Do we need to disable the PHY? */
+
     /* Disable whitelisting (just in case) */
     ble_ll_whitelist_disable();
 
@@ -1165,6 +1168,32 @@ ble_ll_adv_can_chg_whitelist(void)
 }
 
 /**
+ * Reset the advertising state machine.
+ * 
+ */
+void
+ble_ll_adv_reset(void)
+{
+    struct ble_ll_adv_sm *advsm;
+    advsm = &g_ble_ll_adv_sm;
+
+    /* If enabled, stop it */
+    if (advsm->enabled) {
+        ble_ll_adv_sm_stop(advsm);
+    }
+
+    /* Free advertiser pdu's */
+    os_mbuf_free(advsm->adv_pdu);
+    os_mbuf_free(advsm->scan_rsp_pdu);
+
+    /* Reset advertising state */
+    memset(&g_ble_ll_adv_stats, 0, sizeof(struct ble_ll_adv_stats));
+
+    /* re-initialize the advertiser state machine */
+    ble_ll_adv_init();
+}
+
+/**
  * Initialize the advertising functionality of a BLE device. This should 
  * be called once on initialization
  */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/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 a4e52b9..d0d7c7d 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -143,13 +143,13 @@ struct ble_ll_conn_stats
 struct ble_ll_conn_stats g_ble_ll_conn_stats;
 
 /**
- * Checks if pdu is a data pdu, meaning it is not a control pdu nor an empty 
- * pdu. 
+ * Checks if pdu is a L2CAP pdu, meaning it is not a control pdu nor an empty 
+ * pdu. This is only called for PDU's received on data channels.
  * 
  * @return int 
  */
 static int
-ble_ll_conn_is_data_pdu(struct os_mbuf *pdu)
+ble_ll_conn_is_l2cap_pdu(struct os_mbuf *pdu)
 {
     int rc;
 
@@ -161,6 +161,37 @@ ble_ll_conn_is_data_pdu(struct os_mbuf *pdu)
     return rc;
 }
 
+/**
+ * Called when the current connection state machine is no longer being used. 
+ * This function will: 
+ *  -> Disable the PHY, which will prevent any transmit/receive interrupts.
+ *  -> Disable the wait for response timer, if running.
+ *  -> Remove the connection state machine from the scheduler.
+ *  -> Sets the Link Layer state to standby.
+ *  -> Sets the current state machine to NULL.
+ *  
+ *  NOTE: the ordering of these function calls is important! We have to stop
+ *  the PHY and remove the schedule item before we can set the state to
+ *  standby and set the current state machine pointer to NULL.
+ */
+static void
+ble_ll_conn_current_sm_over(void)
+{
+    /* Disable the PHY */
+    ble_phy_disable();
+
+    /* Disable the wfr timer */
+    ble_ll_wfr_disable();
+
+    /* Remove any scheduled items for this connection */
+    ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_CONN, g_ble_ll_conn_cur_sm);
+
+    /* Link-layer is in standby state now */
+    ble_ll_state_set(BLE_LL_STATE_STANDBY);
+
+    /* Set current LL connection to NULL */
+    g_ble_ll_conn_cur_sm = NULL;
+}
 
 /**
  * Given a handle, find an active connection matching the handle
@@ -904,7 +935,6 @@ ble_ll_conn_sm_start(struct ble_ll_conn_sm *connsm)
     connsm->cons_rxd_bad_crc = 0;
     connsm->last_rxd_sn = 1;
     connsm->completed_pkts = 0;
-    connsm->last_completed_pkts = 0;
 
     /* initialize data length mgmt */
     conn_params = &g_ble_ll_conn_params;
@@ -1005,18 +1035,17 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
     struct os_mbuf *m;
     struct os_mbuf_pkthdr *pkthdr;
 
-    /* Disable the PHY */
-    ble_phy_disable();
-
-    /* Remove scheduler events just in case */
-    ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_CONN, connsm);
+    /* If this is the current state machine, we need to end it */
+    if (connsm == g_ble_ll_conn_cur_sm) {
+        ble_ll_conn_current_sm_over();
+    } else {
+        /* Remove scheduler events just in case */
+        ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_CONN, connsm);
+    }
 
     /* Stop supervision timer */
     cputime_timer_stop(&connsm->conn_spvn_timer);
 
-    /* Disable any wait for response interrupt that might be running */
-    ble_ll_wfr_disable();
-
     /* Stop any control procedures that might be running */
     os_callout_stop(&connsm->ctrl_proc_rsp_timer.cf_c);
 
@@ -1043,21 +1072,19 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
     /* Connection state machine is now idle */
     connsm->conn_state = BLE_LL_CONN_STATE_IDLE;
 
-    /* Set current LL connection to NULL */
-    g_ble_ll_conn_cur_sm = NULL;
-
-    /* Set Link Layer state to standby */
-    ble_ll_state_set(BLE_LL_STATE_STANDBY);
-
     /* 
      * We need to send a disconnection complete event or a connection complete
      * event when the connection ends. We send a connection complete event
-     * only when we were told to cancel the connection creation.
+     * only when we were told to cancel the connection creation. If the
+     * ble error is "success" it means that the reset command was received
+     * and we should not send an event 
      */ 
-    if (ble_err == BLE_ERR_UNK_CONN_ID) {
-        ble_ll_conn_comp_event_send(connsm, ble_err);
-    } else {
-        ble_ll_disconn_comp_event_send(connsm, ble_err);
+    if (ble_err) {
+        if (ble_err == BLE_ERR_UNK_CONN_ID) {
+            ble_ll_conn_comp_event_send(connsm, ble_err);
+        } else {
+            ble_ll_disconn_comp_event_send(connsm, ble_err);
+        }
     }
 
     /* Put connection state machine back on free list */
@@ -1065,9 +1092,6 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
 
     /* Log connection end */
     ble_ll_log(BLE_LL_LOG_ID_CONN_END,connsm->conn_handle,0,connsm->event_cntr);
-
-    /* turn led off */
-    gpio_set(LED_BLINK_PIN);
 }
 
 /**
@@ -1144,6 +1168,10 @@ ble_ll_conn_event_end(void *arg)
     struct ble_ll_conn_sm *connsm;
 
     connsm = (struct ble_ll_conn_sm *)arg;
+    assert(connsm && (connsm == g_ble_ll_conn_cur_sm));
+
+    /* The current state machine is over */
+    ble_ll_conn_current_sm_over();
 
     /* If we have transmitted the terminate IND successfully, we are done */
     if ((connsm->terminate_ind_txd) || (connsm->terminate_ind_rxd)) {
@@ -1160,14 +1188,7 @@ ble_ll_conn_event_end(void *arg)
         return;
     }
 
-    /* Disable the PHY */
-    ble_phy_disable();
-
-    /* Disable the wfr timer */
-    ble_ll_wfr_disable();
-
-    /* Remove any scheduled items for this connection */
-    ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_CONN, connsm);
+    /* Remove any connection end events that might be enqueued */
     os_eventq_remove(&g_ble_ll_data.ll_evq, &connsm->conn_ev_end);
 
     /* 
@@ -1244,12 +1265,6 @@ ble_ll_conn_event_end(void *arg)
         connsm->slave_cur_window_widening = cur_ww;
     }
 
-    /* Link-layer is in standby state now */
-    ble_ll_state_set(BLE_LL_STATE_STANDBY);
-
-    /* Set current LL connection to NULL */
-    g_ble_ll_conn_cur_sm = NULL;
-
     /* Log event end */
     ble_ll_log(BLE_LL_LOG_ID_CONN_EV_END, 0, 0, connsm->event_cntr);
 
@@ -1260,12 +1275,9 @@ ble_ll_conn_event_end(void *arg)
     ble_ll_conn_sched_set(connsm);
 
     /* If we have completed packets, send an event */
-    if (connsm->completed_pkts != connsm->last_completed_pkts) {
+    if (connsm->completed_pkts) {
         ble_ll_conn_num_comp_pkts_event_send();
     }
-
-    /* turn led off */
-    gpio_set(LED_BLINK_PIN);
 }
 
 /**
@@ -1690,6 +1702,9 @@ ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t aa, uint8_t crcok)
         return -1;
     }
 
+    /* XXX: what happens in this case? When will the connection event end?
+     * Should it end as this is a data pdu received on a different access
+       address? Not sure what to do here. */
     /* Double check access address. Better match connection state machine! */
     if (aa != connsm->access_addr) {
         ++g_ble_ll_conn_stats.rx_data_pdu_bad_aa;
@@ -1767,10 +1782,10 @@ ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t aa, uint8_t crcok)
                         goto conn_event_done;
                     } else {
                         /* 
-                         * If this is a data pdu, we have to increment the
+                         * If this is a l2cap pdu, we have to increment the
                          * number of completed packets
                          */
-                        if (ble_ll_conn_is_data_pdu(txpdu)) {
+                        if (ble_ll_conn_is_l2cap_pdu(txpdu)) {
                             ++connsm->completed_pkts;
                         }
                     }
@@ -2034,6 +2049,32 @@ err_slave_start:
     return 0;
 }
 
+/**
+ * Called the reset the connection module.
+ * 
+ */
+void
+ble_ll_conn_reset(void)
+{
+    struct ble_ll_conn_sm *connsm;
+
+    /* Kill the current one first (if one is running) */
+    if (g_ble_ll_conn_cur_sm) {
+        connsm = g_ble_ll_conn_cur_sm;
+        ble_ll_conn_current_sm_over();
+        ble_ll_conn_end(connsm, BLE_ERR_SUCCESS);
+    }
+
+    /* Now go through and end all the connections */
+    while (1) {
+        connsm = SLIST_FIRST(&g_ble_ll_conn_active_list);
+        if (!connsm) {
+            break;
+        }
+        ble_ll_conn_end(connsm, BLE_ERR_SUCCESS);
+    }
+}
+
 /* Initialize the connection module */
 void
 ble_ll_conn_module_init(void)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/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 03a89e4..8ac3cce 100644
--- a/net/nimble/controller/src/ble_ll_conn_hci.c
+++ b/net/nimble/controller/src/ble_ll_conn_hci.c
@@ -166,8 +166,7 @@ ble_ll_conn_num_comp_pkts_event_send(void)
          * event and that either has packets enqueued or has completed packets.
          */ 
         if ((connsm->conn_state != BLE_LL_CONN_STATE_IDLE) &&
-            ((connsm->completed_pkts != connsm->last_completed_pkts) ||
-             !STAILQ_EMPTY(&connsm->conn_txq))) {
+            (connsm->completed_pkts || !STAILQ_EMPTY(&connsm->conn_txq))) {
             /* If no buffer, get one, If cant get one, leave. */
             if (!evbuf) {
                 evbuf = os_memblock_get(&g_hci_cmd_pool);
@@ -182,7 +181,7 @@ ble_ll_conn_num_comp_pkts_event_send(void)
             /* Add handle and complete packets */
             htole16(handle_ptr, connsm->conn_handle);
             htole16(comp_pkt_ptr, connsm->completed_pkts);
-            connsm->last_completed_pkts = connsm->completed_pkts;
+            connsm->completed_pkts = 0;
             handle_ptr += sizeof(uint16_t);
             comp_pkt_ptr += sizeof(uint16_t);
             ++handles;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/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 3c074a2..e416fee 100644
--- a/net/nimble/controller/src/ble_ll_conn_priv.h
+++ b/net/nimble/controller/src/ble_ll_conn_priv.h
@@ -65,6 +65,7 @@ int ble_ll_conn_slave_start(uint8_t *rxbuf);
 
 /* Link Layer interface */
 void ble_ll_conn_module_init(void);
+void ble_ll_conn_reset(void);
 void ble_ll_conn_event_end(void *arg);
 void ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t len);
 void ble_ll_conn_spvn_timeout(void *arg);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/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 9dc63e5..1e8f73c 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -427,6 +427,11 @@ ble_ll_hci_ctlr_bb_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
             rc = BLE_ERR_SUCCESS;
         }
         break;
+    case BLE_HCI_OCF_CB_RESET:
+        if (len == 0) {
+            rc = ble_ll_reset();
+        }
+        break;
     default:
         rc = BLE_ERR_UNKNOWN_HCI_CMD;
         break;
@@ -541,7 +546,21 @@ ble_hci_transport_host_acl_data_send(struct os_mbuf *om)
 }
 
 /**
- * Initalize the LL HCI.
+ * Reset the LL HCI interface.
+ * 
+ */
+void
+ble_ll_hci_reset(void)
+{
+    /* Only need to call the init function again */
+    ble_ll_hci_init();
+}
+
+/**
+ * Initalize the LL HCI. 
+ *  
+ * NOTE: This function is called by the HCI RESET command so if any code 
+ * is added here it must be OK to be executed when the reset command is used. 
  */
 void
 ble_ll_hci_init(void)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/net/nimble/controller/src/ble_ll_scan.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c
index 9cfdd35..159d65e 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -1143,9 +1143,44 @@ ble_ll_scan_whitelist_enabled(void)
 }
 
 /**
+ * Called when the controller receives the reset command. Resets the 
+ * scanning state machine to its initial state. 
+ * 
+ * @return int 
+ */
+void
+ble_ll_scan_reset(void)
+{
+    struct ble_ll_scan_sm *scansm;
+
+    /* If enabled, stop it. */
+    scansm = &g_ble_ll_scan_sm;
+    if (scansm->scan_enabled) {
+        ble_ll_scan_sm_stop(scansm);
+    }
+
+    /* Reset all statistics */
+    memset(&g_ble_ll_scan_stats, 0, sizeof(struct ble_ll_scan_stats));
+
+    /* Free the scan request pdu */
+    os_mbuf_free(scansm->scan_req_pdu);
+
+    /* Reset duplicate advertisers and those from which we rxd a response */
+    g_ble_ll_scan_num_rsp_advs = 0;
+    memset(&g_ble_ll_scan_rsp_advs[0], 0, sizeof(g_ble_ll_scan_rsp_advs));
+
+    g_ble_ll_scan_num_dup_advs = 0;
+    memset(&g_ble_ll_scan_dup_advs[0], 0, sizeof(g_ble_ll_scan_dup_advs));
+
+    /* Call the init function again */
+    ble_ll_scan_init();
+}
+
+/**
  * ble ll scan init 
  *  
- * Initialize a scanner. 
+ * Initialize a scanner. Must be called before scanning can be started. 
+ * Expected to be called with a un-initialized or reset scanning state machine. 
  */
 void
 ble_ll_scan_init(void)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/net/nimble/drivers/nrf52/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf52/src/ble_phy.c b/net/nimble/drivers/nrf52/src/ble_phy.c
index 2e56f6d..c78b2e9 100644
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@ -76,11 +76,33 @@ struct ble_phy_statistics
 
 struct ble_phy_statistics g_ble_phy_stats;
 
-/* XXX: TODO:
- 
- * 1) Test the following to make sure it works: suppose an event is already
- * set to 1 and the interrupt is not enabled. What happens if you enable the
- * interrupt with the event bit already set to 1  
+/* 
+ * NOTE: 
+ * Tested the following to see what would happen:
+ *  -> NVIC has radio irq enabled (interrupt # 1, mask 0x2).
+ *  -> Set up nrf52 to receive. Clear ADDRESS event register.
+ *  -> Enable ADDRESS interrupt on nrf52 by writing to INTENSET.
+ *  -> Enable RX.
+ *  -> Disable interrupts globally using OS_ENTER_CRITICAL().
+ *  -> Wait until a packet is received and the ADDRESS event occurs.
+ *  -> Call ble_phy_disable().
+ * 
+ *  At this point I wanted to see the state of the cortex NVIC. The IRQ
+ *  pending bit was TRUE for the radio interrupt (as expected) as we never
+ *  serviced the radio interrupt (interrupts were disabled).
+ * 
+ *  What was unexpected was this: without clearing the pending IRQ in the NVIC,
+ *  when radio interrupts were re-enabled (address event bit in INTENSET set to
+ *  1) and the radio ADDRESS event register read 1 (it was never cleared after
+ *  the first address event), the radio did not enter the ISR! I would have
+ *  expected that if the following were true, an interrupt would occur:
+ *      -> NVIC ISER bit set to TRUE
+ *      -> NVIC ISPR bit reads TRUE, meaning interrupt is pending.
+ *      -> Radio peripheral interrupts are enabled for some event (or events).
+ *      -> Corresponding event register(s) in radio peripheral read 1.
+ * 
+ *  Not sure what the end result of all this is. We will clear the pending
+ *  bit in the NVIC just to be sure when we disable the PHY.
  */
 
 /**
@@ -602,6 +624,8 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit)
  *  -> Disable internal shortcuts.
  *  -> Disable the radio.
  *  -> Sets phy state to idle.
+ *  -> Clears any pending irqs in the NVIC. Might not be necessary but we do
+ *  it as a precaution.
  */
 void
 ble_phy_disable(void)
@@ -611,18 +635,17 @@ ble_phy_disable(void)
     NRF_RADIO->INTENCLR = NRF52_RADIO_IRQ_MASK_ALL;
     NRF_RADIO->SHORTS = 0;
     NRF_RADIO->TASKS_DISABLE = 1;
+    NVIC_ClearPendingIRQ(RADIO_IRQn);
     g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE;
-
-    /* XXX: do I need to clear any pending state in the cortex-M possibly? */
 }
 
 /* Gets the current access address */
 uint32_t ble_phy_access_addr_get(void)
 {
+    /* XXX: Read real address from chip? */
     return g_ble_phy_data.phy_access_address;
 }
 
-
 /**
  * Return the phy state
  * 
@@ -631,6 +654,6 @@ uint32_t ble_phy_access_addr_get(void)
 int 
 ble_phy_state_get(void)
 {
+    /* XXX: should we read actual hardware */
     return g_ble_phy_data.phy_state;
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/net/nimble/host/include/host/host_hci.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/host_hci.h b/net/nimble/host/include/host/host_hci.h
index 094f3c1..518803a 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -23,6 +23,7 @@ struct os_mbuf;
 
 int host_hci_os_event_proc(struct os_event *ev);
 int host_hci_event_rx(uint8_t *data);
+int host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, void *cmddata);
 int host_hci_cmd_set_event_mask(uint64_t event_mask);
 int host_hci_cmd_disconnect(uint16_t handle, uint8_t reason);
 int host_hci_cmd_le_set_scan_rsp_data(uint8_t *data, uint8_t len);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/net/nimble/host/src/host_hci_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci_cmd.c b/net/nimble/host/src/host_hci_cmd.c
index 7843bba..5f164ff 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -38,7 +38,7 @@ host_hci_cmd_transport(uint8_t *cmdbuf)
 #endif
 }
 
-static int
+int
 host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, void *cmddata)
 {
     int rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/958a0aed/project/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c
index 6c5dad5..6b8598d 100755
--- a/project/bletest/src/main.c
+++ b/project/bletest/src/main.c
@@ -53,7 +53,7 @@ uint8_t g_host_adv_len;
 /* Create a mbuf pool of BLE mbufs */
 #define MBUF_NUM_MBUFS      (16)
 #define MBUF_BUF_SIZE       \
-    (((BLE_LL_CFG_ACL_DATA_PKT_LEN + 3) / 4) + sizeof(struct hci_data_hdr))
+    ((BLE_LL_CFG_ACL_DATA_PKT_LEN + sizeof(struct hci_data_hdr) + 3) & 0xFFFC)
 #define MBUF_MEMBLOCK_SIZE  (MBUF_BUF_SIZE + BLE_MBUF_PKT_OVERHEAD)
 
 #define MBUF_MEMPOOL_SIZE   OS_MEMPOOL_SIZE(MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE)
@@ -441,6 +441,12 @@ bletest_task_handler(void *arg)
     os_callout_func_init(&g_bletest_timer, &g_bletest_evq, bletest_timer_cb,
                          NULL);
 
+    /* Send the reset command first */
+    rc = host_hci_cmd_send(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_RESET,
+                           0, NULL);
+    assert(rc == 0);
+    host_hci_outstanding_opcode = 0;
+
 #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
     /* Initialize the advertiser */
     console_printf("Starting BLE test task as advertiser\n");