You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by st...@apache.org on 2016/08/09 23:07:40 UTC

[06/42] incubator-mynewt-core git commit: BLE Host - Use HCI transport API

BLE Host - Use HCI transport API

Prior to this change, the host assumed it was running with a combined
host-controller setup.  Now it uses the available HCI transport instead.


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

Branch: refs/heads/sterly_refactor
Commit: 0fd02e1e719c9f296e151e89d57ac34c80a870f1
Parents: 2a8f6e4
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Aug 3 19:44:39 2016 -0700
Committer: Sterling Hughes <st...@apache.org>
Committed: Tue Aug 9 16:05:21 2016 -0700

----------------------------------------------------------------------
 .../controller/include/controller/ble_ll.h      |   1 +
 net/nimble/controller/pkg.yml                   |   6 +-
 net/nimble/controller/src/ble_ll.c              |  17 +
 net/nimble/controller/src/ble_ll_conn.c         |   6 +-
 net/nimble/controller/src/ble_ll_conn_hci.c     |   9 +-
 net/nimble/controller/src/ble_ll_conn_priv.h    |   7 +
 net/nimble/controller/src/ble_ll_hci.c          |  14 +-
 net/nimble/controller/src/ble_ll_hci_ev.c       |  15 +-
 net/nimble/controller/src/ble_ll_scan.c         |   3 +-
 net/nimble/host/include/host/ble_hs.h           |  28 +-
 net/nimble/host/include/host/ble_hs_test.h      |   3 -
 net/nimble/host/include/host/host_hci.h         |   8 +-
 net/nimble/host/pkg.yml                         |  15 +-
 net/nimble/host/src/ble_gap.c                   |   2 +-
 net/nimble/host/src/ble_gap_priv.h              |   2 +-
 net/nimble/host/src/ble_hci_cmd.c               |  58 +-
 net/nimble/host/src/ble_hs.c                    | 224 ++++--
 net/nimble/host/src/ble_hs_atomic.c             |  20 +
 net/nimble/host/src/ble_hs_atomic_priv.h        |   1 +
 net/nimble/host/src/ble_hs_priv.h               |  16 +
 net/nimble/host/src/ble_hs_pvcy.c               |  27 +-
 net/nimble/host/src/ble_hs_pvcy_priv.h          |   2 +-
 net/nimble/host/src/ble_hs_startup.c            |   4 -
 net/nimble/host/src/host_dbg.c                  |   2 +-
 net/nimble/host/src/host_hci.c                  |  49 +-
 net/nimble/host/src/host_hci_cmd.c              |  52 +-
 net/nimble/host/src/test/ble_gap_test.c         |  11 +-
 net/nimble/host/src/test/ble_host_hci_test.c    |   8 +-
 net/nimble/host/src/test/ble_hs_test.c          |  16 -
 net/nimble/host/src/test/ble_hs_test_util.c     |  96 ++-
 net/nimble/host/src/test/ble_hs_test_util.h     |   2 +
 net/nimble/host/src/test/ble_os_test.c          |   2 +-
 net/nimble/host/src/test/ble_sm_test_util.c     |  20 +-
 net/nimble/include/nimble/ble.h                 |   4 -
 net/nimble/include/nimble/ble_hci_trans.h       | 152 ++++
 net/nimble/include/nimble/hci_transport.h       |  32 -
 .../ram/include/transport/ram/ble_hci_ram.h     |  15 +
 net/nimble/transport/ram/pkg.yml                |  33 +
 net/nimble/transport/ram/src/ble_hci_ram.c      | 190 +++++
 .../uart/include/transport/uart/ble_hci_uart.h  |  19 +
 net/nimble/transport/uart/pkg.yml               |  34 +
 net/nimble/transport/uart/src/ble_hci_uart.c    | 775 +++++++++++++++++++
 42 files changed, 1731 insertions(+), 269 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 81cba53..2be8425 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -22,6 +22,7 @@
 
 #include "stats/stats.h"
 #include "hal/hal_cputime.h"
+#include "os/os_eventq.h"
 #include "nimble/nimble_opt.h"
 
 /* Controller revision. */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/controller/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/controller/pkg.yml b/net/nimble/controller/pkg.yml
index 07a9d56..8e52aba 100644
--- a/net/nimble/controller/pkg.yml
+++ b/net/nimble/controller/pkg.yml
@@ -25,10 +25,14 @@ pkg.keywords:
     - ble
     - bluetooth
 
-pkg.req_apis: ble_driver
+pkg.req_apis:
+    - ble_driver
+    - ble_transport
+
 pkg.deps:
     - libs/os
     - sys/stats
     - net/nimble
+
 pkg.features:
     - BLE_DEVICE

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 3a09e3e..1a4f558 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -26,6 +26,7 @@
 #include "nimble/ble.h"
 #include "nimble/nimble_opt.h"
 #include "nimble/hci_common.h"
+#include "nimble/ble_hci_trans.h"
 #include "controller/ble_hw.h"
 #include "controller/ble_phy.h"
 #include "controller/ble_ll.h"
@@ -182,6 +183,9 @@ STATS_NAME_END(ble_ll_stats)
 struct os_task g_ble_ll_task;
 os_stack_t g_ble_ll_stack[BLE_LL_STACK_SIZE];
 
+struct os_mempool g_ble_ll_hci_ev_pool;
+static void *ble_ll_hci_os_event_buf;
+
 /* XXX: temporary logging until we transition to real logging */
 #ifdef BLE_LL_LOG
 struct ble_ll_log
@@ -1129,6 +1133,16 @@ ble_ll_init(uint8_t ll_task_prio, uint8_t num_acl_pkts, uint16_t acl_pkt_size)
     cputime_timer_init(&g_ble_ll_data.ll_wfr_timer, ble_ll_wfr_timer_exp,
                        NULL);
 
+    ble_ll_hci_os_event_buf = malloc(
+        OS_MEMPOOL_BYTES(16, sizeof (struct os_event)));
+    assert(ble_ll_hci_os_event_buf != NULL);
+
+    /* Create memory pool of OS events */
+    rc = os_mempool_init(&g_ble_ll_hci_ev_pool, 16,
+                         sizeof (struct os_event), ble_ll_hci_os_event_buf,
+                         "g_ble_ll_hci_ev_pool");
+    assert(rc == 0);
+
     /* Initialize LL HCI */
     ble_ll_hci_init();
 
@@ -1182,6 +1196,9 @@ ble_ll_init(uint8_t ll_task_prio, uint8_t num_acl_pkts, uint16_t acl_pkt_size)
                             STATS_SIZE_INIT_PARMS(ble_ll_stats, STATS_SIZE_32),
                             STATS_NAME_INIT_PARMS(ble_ll_stats),
                             "ble_ll");
+
+    ble_hci_trans_cfg_ll(ble_ll_hci_cmd_rx, NULL,
+                                    ble_ll_hci_acl_rx, NULL);
     return rc;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 f711dfb..cb0f89b 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -25,6 +25,7 @@
 #include "nimble/ble.h"
 #include "nimble/nimble_opt.h"
 #include "nimble/hci_common.h"
+#include "nimble/ble_hci_trans.h"
 #include "ble/xcvr.h"
 #include "controller/ble_ll.h"
 #include "controller/ble_ll_hci.h"
@@ -103,9 +104,6 @@ extern void bletest_completed_pkt(uint16_t handle);
  *  are hosed. Well, anchor point can get really messed up!
  */
 
-/* XXX: this does not belong here! Move to transport? */
-extern int ble_hs_rx_data(struct os_mbuf *om);
-
 /*
  * The amount of time that we will wait to hear the start of a receive
  * packet after we have transmitted a packet. This time is at least
@@ -2569,7 +2567,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
                     acl_hdr = (acl_hdr << 12) | connsm->conn_handle;
                     htole16(rxbuf, acl_hdr);
                     htole16(rxbuf + 2, acl_len);
-                    ble_hs_rx_data(rxpdu);
+                    ble_hci_trans_ll_acl_tx(rxpdu);
                 }
 
                 /* NOTE: we dont free the mbuf since we handed it off! */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 1d6102e..f653ca6 100644
--- a/net/nimble/controller/src/ble_ll_conn_hci.c
+++ b/net/nimble/controller/src/ble_ll_conn_hci.c
@@ -25,6 +25,7 @@
 #include "nimble/ble.h"
 #include "nimble/nimble_opt.h"
 #include "nimble/hci_common.h"
+#include "nimble/ble_hci_trans.h"
 #include "controller/ble_ll.h"
 #include "controller/ble_ll_hci.h"
 #include "controller/ble_ll_conn.h"
@@ -140,7 +141,7 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status)
     enh_enabled = ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE);
 
     if (enabled || enh_enabled) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             /* Put common elements in event */
             evbuf[0] = BLE_HCI_EVCODE_LE_META;
@@ -246,7 +247,7 @@ ble_ll_conn_num_comp_pkts_event_send(void)
             (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_evt_pool);
+                evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
                 if (!evbuf) {
                     break;
                 }
@@ -313,7 +314,7 @@ ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm)
     uint8_t *evbuf;
 
     if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_AUTH_PYLD_TMO)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             evbuf[0] = BLE_HCI_EVCODE_AUTH_PYLD_TMO;
             evbuf[1] = sizeof(uint16_t);
@@ -338,7 +339,7 @@ ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t reason)
     uint8_t *evbuf;
 
     if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_DISCONN_CMP)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             evbuf[0] = BLE_HCI_EVCODE_DISCONN_CMP;
             evbuf[1] = BLE_HCI_EVENT_DISCONN_COMPLETE_LEN;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 218ecbc..b855b22 100644
--- a/net/nimble/controller/src/ble_ll_conn_priv.h
+++ b/net/nimble/controller/src/ble_ll_conn_priv.h
@@ -81,6 +81,9 @@ extern struct ble_ll_conn_free_list g_ble_ll_conn_free_list;
 /* Pointer to connection state machine we are trying to create */
 extern struct ble_ll_conn_sm *g_ble_ll_conn_create_sm;
 
+extern struct os_mempool g_ble_ll_hci_ev_pool;
+
+
 /* Generic interface */
 struct ble_ll_len_req;
 struct hci_create_conn;
@@ -150,4 +153,8 @@ void ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm);
 #else
 #define ble_ll_conn_auth_pyld_timer_start(x)
 #endif
+
+int ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg);
+int ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg);
+
 #endif /* H_BLE_LL_CONN_PRIV_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 2889367..352dda2 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -23,7 +23,7 @@
 #include "nimble/ble.h"
 #include "nimble/nimble_opt.h"
 #include "nimble/hci_common.h"
-#include "nimble/hci_transport.h"
+#include "nimble/ble_hci_trans.h"
 #include "controller/ble_hw.h"
 #include "controller/ble_ll_adv.h"
 #include "controller/ble_ll_scan.h"
@@ -68,7 +68,7 @@ ble_ll_hci_event_send(uint8_t *evbuf)
     STATS_INC(ble_ll_stats, hci_events_sent);
 
     /* Send the event to the host */
-    rc = ble_hci_transport_ctlr_event_send(evbuf);
+    rc = ble_hci_trans_ll_evt_tx(evbuf);
 
     return rc;
 }
@@ -86,7 +86,7 @@ ble_ll_hci_send_noop(void)
     uint8_t *evbuf;
     uint16_t opcode;
 
-    evbuf = os_memblock_get(&g_hci_evt_pool);
+    evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
     if (evbuf) {
         /* Create a command complete event with a NO-OP opcode */
         opcode = 0;
@@ -919,7 +919,7 @@ ble_ll_hci_cmd_proc(struct os_event *ev)
     assert(cmdbuf != NULL);
 
     /* Free the event */
-    err = os_memblock_put(&g_hci_os_event_pool, ev);
+    err = os_memblock_put(&g_ble_ll_hci_ev_pool, ev);
     assert(err == OS_OK);
 
     /* Get the opcode from the command buffer */
@@ -994,12 +994,12 @@ ble_ll_hci_cmd_proc(struct os_event *ev)
  *                              BLE_ERR_MEM_CAPACITY on HCI buffer exhaustion.
  */
 int
-ble_hci_transport_host_cmd_send(uint8_t *cmd)
+ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg)
 {
     struct os_event *ev;
 
     /* Get an event structure off the queue */
-    ev = (struct os_event *)os_memblock_get(&g_hci_os_event_pool);
+    ev = (struct os_event *)os_memblock_get(&g_ble_ll_hci_ev_pool);
     if (!ev) {
         return BLE_ERR_MEM_CAPACITY;
     }
@@ -1015,7 +1015,7 @@ ble_hci_transport_host_cmd_send(uint8_t *cmd)
 
 /* Send ACL data from host to contoller */
 int
-ble_hci_transport_host_acl_data_send(struct os_mbuf *om)
+ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg)
 {
     ble_ll_acl_data_in(om);
     return 0;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 5624c65..2548bdc 100644
--- a/net/nimble/controller/src/ble_ll_hci_ev.c
+++ b/net/nimble/controller/src/ble_ll_hci_ev.c
@@ -21,6 +21,7 @@
 #include <string.h>
 #include "nimble/ble.h"
 #include "nimble/hci_common.h"
+#include "nimble/ble_hci_trans.h"
 #include "controller/ble_ll.h"
 #include "controller/ble_ll_hci.h"
 #include "controller/ble_ll_ctrl.h"
@@ -41,7 +42,7 @@ ble_ll_hci_ev_datalen_chg(struct ble_ll_conn_sm *connsm)
     uint8_t *evbuf;
 
     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_DATA_LEN_CHG)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             evbuf[0] = BLE_HCI_EVCODE_LE_META;
             evbuf[1] = BLE_HCI_LE_DATA_LEN_CHG_LEN;
@@ -68,7 +69,7 @@ ble_ll_hci_ev_rem_conn_parm_req(struct ble_ll_conn_sm *connsm,
     uint8_t *evbuf;
 
     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             evbuf[0] = BLE_HCI_EVCODE_LE_META;
             evbuf[1] = BLE_HCI_LE_REM_CONN_PARM_REQ_LEN;
@@ -95,7 +96,7 @@ ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm *connsm, uint8_t status)
     uint8_t *evbuf;
 
     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             evbuf[0] = BLE_HCI_EVCODE_LE_META;
             evbuf[1] = BLE_HCI_LE_CONN_UPD_LEN;
@@ -127,7 +128,7 @@ ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status)
     }
 
     if (ble_ll_hci_is_event_enabled(evcode)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             evbuf[0] = evcode;
             evbuf[1] = evlen;
@@ -158,7 +159,7 @@ ble_ll_hci_ev_ltk_req(struct ble_ll_conn_sm *connsm)
     uint8_t *evbuf;
 
     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_LT_KEY_REQ)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             evbuf[0] = BLE_HCI_EVCODE_LE_META;
             evbuf[1] = BLE_HCI_LE_LT_KEY_REQ_LEN;
@@ -188,7 +189,7 @@ ble_ll_hci_ev_rd_rem_used_feat(struct ble_ll_conn_sm *connsm, uint8_t status)
     uint8_t *evbuf;
 
     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             evbuf[0] = BLE_HCI_EVCODE_LE_META;
             evbuf[1] = BLE_HCI_LE_RD_REM_USED_FEAT_LEN;
@@ -208,7 +209,7 @@ ble_ll_hci_ev_rd_rem_ver(struct ble_ll_conn_sm *connsm, uint8_t status)
     uint8_t *evbuf;
 
     if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
         if (evbuf) {
             evbuf[0] = BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP;
             evbuf[1] = BLE_HCI_EVENT_RD_RM_VER_LEN;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 c926846..64c3990 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -25,6 +25,7 @@
 #include "nimble/ble.h"
 #include "nimble/nimble_opt.h"
 #include "nimble/hci_common.h"
+#include "nimble/ble_hci_trans.h"
 #include "controller/ble_phy.h"
 #include "controller/ble_hw.h"
 #include "controller/ble_ll.h"
@@ -424,7 +425,7 @@ ble_ll_hci_send_adv_report(uint8_t pdu_type, uint8_t txadd, uint8_t *rxbuf,
     }
 
     if (ble_ll_hci_is_le_event_enabled(subev)) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO);
         if (evbuf) {
             evbuf[0] = BLE_HCI_EVCODE_LE_META;
             evbuf[1] = event_len;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/include/host/ble_hs.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs.h b/net/nimble/host/include/host/ble_hs.h
index 5cdf863..faeaf14 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -21,6 +21,7 @@
 #define H_BLE_HS_
 
 #include <inttypes.h>
+#include "nimble/hci_common.h"
 #include "host/ble_att.h"
 #include "host/ble_gap.h"
 #include "host/ble_gatt.h"
@@ -62,6 +63,7 @@ struct os_event;
 #define BLE_HS_ETIMEOUT_HCI         19
 #define BLE_HS_ENOMEM_EVT           20
 #define BLE_HS_ENOADDR              21
+#define BLE_HS_ENOTSYNCED           22
 
 #define BLE_HS_ERR_ATT_BASE         0x100   /* 256 */
 #define BLE_HS_ATT_ERR(x)           ((x) ? BLE_HS_ERR_ATT_BASE + (x) : 0)
@@ -85,8 +87,10 @@ struct os_event;
 #define BLE_HS_IO_NO_INPUT_OUTPUT           0x03
 #define BLE_HS_IO_KEYBOARD_DISPLAY          0x04
 
+typedef void ble_hs_reset_fn(int reason);
+typedef void ble_hs_sync_fn(void);
+
 struct ble_hs_cfg {
-    /*** HCI settings. */
     /**
      * An HCI buffer is a "flat" 260-byte buffer.  HCI buffers are used by the
      * controller to send unsolicited events to the host.
@@ -105,6 +109,10 @@ struct ble_hs_cfg {
      * needs to be processsed.  The pool of OS events is allocated with the
      * same number of elements as the HCI buffer pool.
      */
+    /* XXX: This should either be renamed to indicate it is only used for OS
+     * events, or it should go away entirely (copy the number from the
+     * transport's config).
+     */
     uint8_t max_hci_bufs;
 
     /*** Connection settings. */
@@ -211,6 +219,19 @@ struct ble_hs_cfg {
     uint8_t sm_our_key_dist;
     uint8_t sm_their_key_dist;
 
+    /*** HCI settings */
+    /**
+     * This callback is executed when the host resets itself and the controller
+     * due to fatal error.
+     */
+    ble_hs_reset_fn *reset_cb;
+
+    /**
+     * This callback is executed when the host and controller become synced.
+     * This happens at startup and after a reset.
+     */
+    ble_hs_sync_fn *sync_cb;
+
     /*** Store settings. */
     /**
      * These function callbacks handle persistence of sercurity material
@@ -220,7 +241,7 @@ struct ble_hs_cfg {
     ble_store_write_fn *store_write_cb;
     ble_store_delete_fn *store_delete_cb;
 
-    /*** privacy settings */
+    /*** Privacy settings. */
     /**
      * The frequency at which new resovlable private addresses are generated.
      * Units are seconds.
@@ -230,9 +251,8 @@ struct ble_hs_cfg {
 
 extern const struct ble_hs_cfg ble_hs_cfg_dflt;
 
-int ble_hs_rx_data(struct os_mbuf *om);
+int ble_hs_synced(void);
 int ble_hs_start(void);
-void ble_hs_event_enqueue(struct os_event *ev);
 int ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/include/host/ble_hs_test.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs_test.h b/net/nimble/host/include/host/ble_hs_test.h
index a883018..5d28291 100644
--- a/net/nimble/host/include/host/ble_hs_test.h
+++ b/net/nimble/host/include/host/ble_hs_test.h
@@ -23,9 +23,6 @@
 #include <inttypes.h>
 struct os_mbuf;
 
-void ble_hs_test_pkt_txed(struct os_mbuf *om);
-void ble_hs_test_hci_txed(uint8_t *cmdbuf);
-
 int ble_att_clt_test_all(void);
 int ble_att_svr_test_all(void);
 int ble_gap_test_all(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 dbe626a..79a0034 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -24,13 +24,7 @@
 struct ble_hs_conn;
 struct os_mbuf;
 
-#define HCI_CMD_BUF_SIZE        260
-#define HCI_EVT_BUF_SIZE        260
-
-extern uint8_t host_hci_cmd_buf[HCI_CMD_BUF_SIZE];
-
-int host_hci_os_event_proc(struct os_event *ev);
-int host_hci_event_rx(uint8_t *data);
+int host_hci_evt_process(uint8_t *data);
 uint16_t host_hci_opcode_join(uint8_t ogf, uint16_t ocf);
 void host_hci_write_hdr(uint8_t ogf, uint8_t ocf, uint8_t len, void *buf);
 int host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/pkg.yml b/net/nimble/host/pkg.yml
index 0edea58..a45ba1e 100644
--- a/net/nimble/host/pkg.yml
+++ b/net/nimble/host/pkg.yml
@@ -36,20 +36,23 @@ pkg.deps:
     # Tinycrypt is only required when secure connections (NIMBPLE_OPT_SM_SC)
     # is enabled.  It always gets built as a dependency, but not is not
     # included by the linker unless SC is enabled.  XXX: We should not build
-    # this library if it is not requiresd.
+    # this library if it is not required.
     - libs/tinycrypt
 
 pkg.req_apis:
+    - ble_transport
     - console
 
 pkg.features:
     - BLE_HOST
 
 # Satisfy capability dependencies for the self-contained test executable.
-pkg.deps.SELFTEST: libs/console/stub
+pkg.deps.SELFTEST:
+    - libs/console/stub
+    - net/nimble/transport/ram
+
 pkg.cflags.SELFTEST:
-    - -DPHONY_TRANSPORT=1
-    - -DPHONY_HCI_ACKS=1
-    - -DNIMBLE_OPT_SM=1
-    - -DNIMBLE_OPT_SM_SC=1
+    - "-DPHONY_HCI_ACKS=1"
+    - "-DNIMBLE_OPT_SM=1"
+    - "-DNIMBLE_OPT_SM_SC=1"
 pkg.cflags.TEST: -DBLE_HS_DEBUG

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_gap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c
index a001ae3..1a41956 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -708,7 +708,7 @@ ble_gap_update_failed(uint16_t conn_handle, int status)
     ble_gap_update_notify(conn_handle, status);
 }
 
-static void
+void
 ble_gap_conn_broken(uint16_t conn_handle, int reason)
 {
     struct ble_gap_snapshot snap;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_gap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_priv.h b/net/nimble/host/src/ble_gap_priv.h
index 449a4b0..3168d48 100644
--- a/net/nimble/host/src/ble_gap_priv.h
+++ b/net/nimble/host/src/ble_gap_priv.h
@@ -70,7 +70,6 @@ extern STATS_SECT_DECL(ble_gap_stats) ble_gap_stats;
 #define BLE_GAP_CONN_MODE_MAX               3
 #define BLE_GAP_DISC_MODE_MAX               3
 
-int ble_gap_locked_by_cur_task(void);
 void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc);
 int ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt);
 void ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt);
@@ -92,6 +91,7 @@ void ble_gap_subscribe_event(uint16_t conn_handle, uint16_t attr_handle,
                              uint8_t prev_indicate, uint8_t cur_indicate);
 int ble_gap_master_in_progress(void);
 
+void ble_gap_conn_broken(uint16_t conn_handle, int reason);
 int32_t ble_gap_heartbeat(void);
 
 int ble_gap_init(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_hci_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_cmd.c b/net/nimble/host/src/ble_hci_cmd.c
index 23eaba3..53fe726 100644
--- a/net/nimble/host/src/ble_hci_cmd.c
+++ b/net/nimble/host/src/ble_hci_cmd.c
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include "os/os.h"
+#include "nimble/ble_hci_trans.h"
 #include "ble_hs_priv.h"
 #include "host_dbg_priv.h"
 
@@ -29,6 +30,8 @@
 static struct os_mutex ble_hci_cmd_mutex;
 static struct os_sem ble_hci_cmd_sem;
 
+static uint8_t *ble_hci_cmd_ack;
+
 #if PHONY_HCI_ACKS
 static ble_hci_cmd_phony_ack_fn *ble_hci_cmd_phony_ack_cb;
 #endif
@@ -69,7 +72,6 @@ ble_hci_cmd_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len,
     uint8_t num_pkts;
 
     if (len < BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN) {
-        /* XXX: Increment stat. */
         return BLE_HS_ECONTROLLER;
     }
 
@@ -112,7 +114,6 @@ ble_hci_cmd_rx_cmd_status(uint8_t event_code, uint8_t *data, int len,
     uint8_t status;
 
     if (len < BLE_HCI_EVENT_CMD_STATUS_LEN) {
-        /* XXX: Increment stat. */
         return BLE_HS_ECONTROLLER;
     }
 
@@ -132,7 +133,8 @@ ble_hci_cmd_rx_cmd_status(uint8_t event_code, uint8_t *data, int len,
 }
 
 static int
-ble_hci_cmd_process_ack(uint8_t *params_buf, uint8_t params_buf_len,
+ble_hci_cmd_process_ack(uint16_t expected_opcode,
+                        uint8_t *params_buf, uint8_t params_buf_len,
                         struct ble_hci_ack *out_ack)
 {
     uint8_t event_code;
@@ -140,20 +142,16 @@ ble_hci_cmd_process_ack(uint8_t *params_buf, uint8_t params_buf_len,
     uint8_t event_len;
     int rc;
 
-    /***
-     * The controller always reuses the command buffer for its acknowledgement
-     * events.  This function processes the acknowledgement event contained in
-     * the command buffer.
-     */
+    BLE_HS_DBG_ASSERT(ble_hci_cmd_ack != NULL);
 
     /* Count events received */
     STATS_INC(ble_hs_stats, hci_event);
 
     /* Display to console */
-    host_hci_dbg_event_disp(host_hci_cmd_buf);
+    host_hci_dbg_event_disp(ble_hci_cmd_ack);
 
-    event_code = host_hci_cmd_buf[0];
-    param_len = host_hci_cmd_buf[1];
+    event_code = ble_hci_cmd_ack[0];
+    param_len = ble_hci_cmd_ack[1];
     event_len = param_len + 2;
 
     /* Clear ack fields up front to silence spurious gcc warnings. */
@@ -161,12 +159,12 @@ ble_hci_cmd_process_ack(uint8_t *params_buf, uint8_t params_buf_len,
 
     switch (event_code) {
     case BLE_HCI_EVCODE_COMMAND_COMPLETE:
-        rc = ble_hci_cmd_rx_cmd_complete(event_code, host_hci_cmd_buf,
+        rc = ble_hci_cmd_rx_cmd_complete(event_code, ble_hci_cmd_ack,
                                          event_len, out_ack);
         break;
 
     case BLE_HCI_EVCODE_COMMAND_STATUS:
-        rc = ble_hci_cmd_rx_cmd_status(event_code, host_hci_cmd_buf,
+        rc = ble_hci_cmd_rx_cmd_status(event_code, ble_hci_cmd_ack,
                                        event_len, out_ack);
         break;
 
@@ -187,6 +185,14 @@ ble_hci_cmd_process_ack(uint8_t *params_buf, uint8_t params_buf_len,
             memcpy(params_buf, out_ack->bha_params, out_ack->bha_params_len);
         }
         out_ack->bha_params = params_buf;
+
+        if (out_ack->bha_opcode != expected_opcode) {
+            rc = BLE_HS_ECONTROLLER;
+        }
+    }
+
+    if (rc != 0) {
+        STATS_INC(ble_hs_stats, hci_invalid_ack);
     }
 
     return rc;
@@ -201,15 +207,20 @@ ble_hci_cmd_wait_for_ack(void)
     if (ble_hci_cmd_phony_ack_cb == NULL) {
         rc = BLE_HS_ETIMEOUT_HCI;
     } else {
-        rc = ble_hci_cmd_phony_ack_cb(host_hci_cmd_buf, 260);
+        ble_hci_cmd_ack =
+            ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD);
+        BLE_HS_DBG_ASSERT(ble_hci_cmd_ack != NULL);
+        rc = ble_hci_cmd_phony_ack_cb(ble_hci_cmd_ack, 260);
     }
 #else
     rc = os_sem_pend(&ble_hci_cmd_sem, BLE_HCI_CMD_TIMEOUT);
     switch (rc) {
     case 0:
+        BLE_HS_DBG_ASSERT(ble_hci_cmd_ack != NULL);
         break;
     case OS_TIMEOUT:
         rc = BLE_HS_ETIMEOUT_HCI;
+        STATS_INC(ble_hs_stats, hci_timeout);
         break;
     default:
         rc = BLE_HS_EOS;
@@ -225,8 +236,12 @@ ble_hci_cmd_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len,
                uint8_t *out_evt_buf_len)
 {
     struct ble_hci_ack ack;
+    uint16_t opcode;
     int rc;
 
+    opcode = le16toh((uint8_t *)cmd);
+
+    BLE_HS_DBG_ASSERT(ble_hci_cmd_ack == NULL);
     ble_hci_cmd_lock();
 
     rc = host_hci_cmd_send_buf(cmd);
@@ -236,11 +251,13 @@ ble_hci_cmd_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len,
 
     rc = ble_hci_cmd_wait_for_ack();
     if (rc != 0) {
+        ble_hs_sched_reset(rc);
         goto done;
     }
 
-    rc = ble_hci_cmd_process_ack(evt_buf, evt_buf_len, &ack);
+    rc = ble_hci_cmd_process_ack(opcode, evt_buf, evt_buf_len, &ack);
     if (rc != 0) {
+        ble_hs_sched_reset(rc);
         goto done;
     }
 
@@ -251,6 +268,11 @@ ble_hci_cmd_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len,
     rc = ack.bha_status;
 
 done:
+    if (ble_hci_cmd_ack != NULL) {
+        ble_hci_trans_buf_free(ble_hci_cmd_ack);
+        ble_hci_cmd_ack = NULL;
+    }
+
     ble_hci_cmd_unlock();
     return rc;
 }
@@ -271,17 +293,17 @@ ble_hci_cmd_tx_empty_ack(void *cmd)
 void
 ble_hci_cmd_rx_ack(uint8_t *ack_ev)
 {
-    /* The controller should always reuse the command buffer for its acks. */
-    BLE_HS_DBG_ASSERT(ack_ev == host_hci_cmd_buf);
-
     if (ble_hci_cmd_sem.sem_tokens != 0) {
         /* This ack is unexpected; ignore it. */
+        ble_hci_trans_buf_free(ack_ev);
         return;
     }
+    BLE_HS_DBG_ASSERT(ble_hci_cmd_ack == NULL);
 
     /* Unblock the application now that the HCI command buffer is populated
      * with the acknowledgement.
      */
+    ble_hci_cmd_ack = ack_ev;
     os_sem_release(&ble_hci_cmd_sem);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_hs.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs.c b/net/nimble/host/src/ble_hs.c
index aeba768..6e8a59f 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -23,12 +23,9 @@
 #include "stats/stats.h"
 #include "util/tpq.h"
 #include "os/os.h"
-#include "nimble/hci_transport.h"
+#include "nimble/ble_hci_trans.h"
 #include "host/host_hci.h"
 #include "ble_hs_priv.h"
-#ifdef PHONY_TRANSPORT
-#include "host/ble_hs_test.h"
-#endif
 
 /**
  * The maximum number of events the host will process in a row before returning
@@ -38,27 +35,33 @@
 
 static struct log_handler ble_hs_log_console_handler;
 
-struct os_mempool g_hci_evt_pool;
-static void *ble_hs_hci_evt_buf;
-
-/* XXX: this might be transport layer */
-#define HCI_OS_EVENT_BUF_SIZE   (sizeof(struct os_event))
-
-struct os_mempool g_hci_os_event_pool;
+struct os_mempool ble_hs_hci_ev_pool;
 static void *ble_hs_hci_os_event_buf;
 
+/** OS event - triggers tx of pending notifications and indications. */
 static struct os_event ble_hs_event_tx_notifications = {
     .ev_type = BLE_HS_EVENT_TX_NOTIFICATIONS,
     .ev_arg = NULL,
 };
 
+/** OS event - triggers a full reset. */
+static struct os_event ble_hs_event_reset = {
+    .ev_type = BLE_HS_EVENT_RESET,
+    .ev_arg = NULL,
+};
+
+uint8_t ble_hs_sync_state;
+static int ble_hs_reset_reason;
+
 #if MYNEWT_SELFTEST
 /** Use a higher frequency timer to allow tests to run faster. */
-#define BLE_HS_HEARTBEAT_OS_TICKS         (OS_TICKS_PER_SEC / 10)
+#define BLE_HS_HEARTBEAT_OS_TICKS       (OS_TICKS_PER_SEC / 10)
 #else
-#define BLE_HS_HEARTBEAT_OS_TICKS         OS_TICKS_PER_SEC
+#define BLE_HS_HEARTBEAT_OS_TICKS       OS_TICKS_PER_SEC
 #endif
 
+#define BLE_HS_SYNC_RETRY_RATE          (OS_TICKS_PER_SEC / 10)    
+
 /**
  * Handles unresponsive timeouts and periodic retries in case of resource
  * shortage.
@@ -90,6 +93,9 @@ STATS_NAME_START(ble_hs_stats)
     STATS_NAME(ble_hs_stats, hci_event)
     STATS_NAME(ble_hs_stats, hci_invalid_ack)
     STATS_NAME(ble_hs_stats, hci_unknown_event)
+    STATS_NAME(ble_hs_stats, hci_timeout)
+    STATS_NAME(ble_hs_stats, reset)
+    STATS_NAME(ble_hs_stats, sync)
 STATS_NAME_END(ble_hs_stats)
 
 int
@@ -157,11 +163,7 @@ ble_hs_process_tx_data_queue(void)
     struct os_mbuf *om;
 
     while ((om = os_mqueue_get(&ble_hs_tx_q)) != NULL) {
-#ifdef PHONY_TRANSPORT
-        ble_hs_test_pkt_txed(om);
-#else
-        ble_hci_transport_host_acl_data_send(om);
-#endif
+        ble_hci_trans_hs_acl_tx(om);
     }
 }
 
@@ -171,11 +173,22 @@ ble_hs_process_rx_data_queue(void)
     struct os_mbuf *om;
 
     while ((om = os_mqueue_get(&ble_hs_rx_q)) != NULL) {
-        host_hci_data_rx(om);
+        host_hci_acl_process(om);
     }
 }
 
 static void
+ble_hs_clear_data_queue(struct os_mqueue *mqueue)
+{
+    struct os_mbuf *om;
+
+    while ((om = os_mqueue_get(mqueue)) != NULL) {
+        os_mbuf_free_chain(om);
+    }
+}
+
+
+static void
 ble_hs_heartbeat_timer_reset(uint32_t ticks)
 {
     int rc;
@@ -202,6 +215,85 @@ ble_hs_heartbeat_sched(int32_t ticks_from_now)
 }
 
 /**
+ * Indicates whether the host has synchronized with the controller.
+ * Synchronization must occur before any host procedures can be performed.
+ *
+ * @return                      1 if the host and controller are in sync;
+ *                              0 if the host and controller our out of sync.
+ */
+int
+ble_hs_synced(void)
+{
+    return ble_hs_sync_state == BLE_HS_SYNC_STATE_GOOD;
+}
+
+static int
+ble_hs_sync(void)
+{
+    int rc;
+
+    /* Set the sync state to "bringup."  This allows the parent task to send
+     * the startup sequence to the controller.  No other tasks are allowed to
+     * send any commands.
+     */
+    ble_hs_sync_state = BLE_HS_SYNC_STATE_BRINGUP;
+
+    rc = ble_hs_startup_go();
+    if (rc == 0) {
+        ble_hs_sync_state = BLE_HS_SYNC_STATE_GOOD;
+        if (ble_hs_cfg.sync_cb != NULL) {
+            ble_hs_cfg.sync_cb();
+        }
+    } else {
+        ble_hs_sync_state = BLE_HS_SYNC_STATE_BAD;
+    }
+
+    ble_hs_heartbeat_sched(BLE_HS_SYNC_RETRY_RATE);
+
+    if (rc == 0) {
+        STATS_INC(ble_hs_stats, sync);
+    }
+
+    return rc;
+}
+
+static int
+ble_hs_reset(void)
+{
+    uint16_t conn_handle;
+    int rc;
+
+    STATS_INC(ble_hs_stats, reset);
+
+    ble_hs_sync_state = 0;
+
+    rc = ble_hci_trans_reset();
+    if (rc != 0) {
+        return rc;
+    }
+
+    ble_hs_clear_data_queue(&ble_hs_tx_q);
+    ble_hs_clear_data_queue(&ble_hs_rx_q);
+
+    while (1) {
+        conn_handle = ble_hs_atomic_first_conn_handle();
+        if (conn_handle == BLE_HS_CONN_HANDLE_NONE) {
+            break;
+        }
+
+        ble_gap_conn_broken(conn_handle, ble_hs_reset_reason);
+    }
+
+    if (ble_hs_cfg.reset_cb != NULL && ble_hs_reset_reason != 0) {
+        ble_hs_cfg.reset_cb(ble_hs_reset_reason);
+    }
+    ble_hs_reset_reason = 0;
+
+    rc = ble_hs_sync();
+    return rc;
+}
+
+/**
  * Called once a second by the ble_hs heartbeat timer.  Handles unresponsive
  * timeouts and periodic retries in case of resource shortage.
  */
@@ -210,6 +302,11 @@ ble_hs_heartbeat(void *unused)
 {
     int32_t ticks_until_next;
 
+    if (!ble_hs_sync_state) {
+        ble_hs_reset();
+        return;
+    }
+
     /* Ensure the timer expires at least once in the next second.
      * XXX: This is not very power efficient.  We will need separate timers for
      * each module.
@@ -235,7 +332,9 @@ ble_hs_event_handle(void *unused)
 {
     struct os_callout_func *cf;
     struct os_event *ev;
+    uint8_t *hci_evt;
     os_sr_t sr;
+    int rc;
     int i;
 
     i = 0;
@@ -267,10 +366,15 @@ ble_hs_event_handle(void *unused)
             break;
 
         case BLE_HOST_HCI_EVENT_CTLR_EVENT:
-            host_hci_os_event_proc(ev);
+            hci_evt = ev->ev_arg;
+            rc = os_memblock_put(&ble_hs_hci_ev_pool, ev);
+            BLE_HS_DBG_ASSERT_EVAL(rc == 0);
+
+            host_hci_evt_process(hci_evt);
             break;
 
         case BLE_HS_EVENT_TX_NOTIFICATIONS:
+            BLE_HS_DBG_ASSERT(ev == &ble_hs_event_tx_notifications);
             ble_gatts_tx_notifications();
 
         case OS_EVENT_T_MQUEUE_DATA:
@@ -278,6 +382,11 @@ ble_hs_event_handle(void *unused)
             ble_hs_process_rx_data_queue();
             break;
 
+        case BLE_HS_EVENT_RESET:
+            BLE_HS_DBG_ASSERT(ev == &ble_hs_event_reset);
+            ble_hs_reset();
+            break;
+
         default:
             BLE_HS_DBG_ASSERT(0);
             break;
@@ -292,6 +401,22 @@ ble_hs_event_enqueue(struct os_event *ev)
     os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev);
 }
 
+void
+ble_hs_enqueue_hci_event(uint8_t *hci_evt)
+{
+    struct os_event *ev;
+
+    ev = os_memblock_get(&ble_hs_hci_ev_pool);
+    if (ev == NULL) {
+        ble_hci_trans_buf_free(ev->ev_arg);
+    } else {
+        ev->ev_queued = 0;
+        ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_EVENT;
+        ev->ev_arg = hci_evt;
+        ble_hs_event_enqueue(ev);
+    }
+}
+
 /**
  * Schedules for all pending notifications and indications to be sent in the
  * host parent task.
@@ -309,6 +434,15 @@ ble_hs_notifications_sched(void)
     ble_hs_event_enqueue(&ble_hs_event_tx_notifications);
 }
 
+void
+ble_hs_sched_reset(int reason)
+{
+    BLE_HS_DBG_ASSERT(ble_hs_reset_reason == 0);
+
+    ble_hs_reset_reason = reason;
+    ble_hs_event_enqueue(&ble_hs_event_reset);
+}
+
 /**
  * Synchronizes the host with the controller by sending a sequence of HCI
  * commands.  This function must be called before any other host functionality
@@ -316,6 +450,10 @@ ble_hs_notifications_sched(void)
  * initialized.  Typically, the host-parent-task calls this function at the top
  * of its task routine.
  *
+ * If the host fails to synchronize with the controller (if the controller is
+ * not fully booted, for example), the host will attempt to resynchronize every
+ * 100 ms.  For this reason, an error return code is not necessarily fatal.
+ *
  * @return                      0 on success; nonzero on error.
  */
 int
@@ -325,11 +463,9 @@ ble_hs_start(void)
 
     ble_hs_parent_task = os_sched_get_current_task();
 
-    ble_hs_heartbeat_timer_reset(BLE_HS_HEARTBEAT_OS_TICKS);
-
     ble_gatts_start();
 
-    rc = ble_hs_startup_go();
+    rc = ble_hs_sync();
     return rc;
 }
 
@@ -343,19 +479,18 @@ ble_hs_start(void)
  * @return                      0 on success; nonzero on failure.
  */
 int
-ble_hs_rx_data(struct os_mbuf *om)
+ble_hs_rx_data(struct os_mbuf *om, void *arg)
 {
     int rc;
 
     rc = os_mqueue_put(&ble_hs_rx_q, &ble_hs_evq, om);
-    if (rc != 0) {
+    if (rc == 0) {
+        os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev);
+    } else {
         os_mbuf_free_chain(om);
-        return BLE_HS_EOS;
+        rc = BLE_HS_EOS;
     }
-
-    os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev);
-
-    return 0;
+    return rc;
 }
 
 int
@@ -375,9 +510,6 @@ ble_hs_tx_data(struct os_mbuf *om)
 static void
 ble_hs_free_mem(void)
 {
-    free(ble_hs_hci_evt_buf);
-    ble_hs_hci_evt_buf = NULL;
-
     free(ble_hs_hci_os_event_buf);
     ble_hs_hci_os_event_buf = NULL;
 }
@@ -418,30 +550,17 @@ ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg)
     log_console_handler_init(&ble_hs_log_console_handler);
     log_register("ble_hs", &ble_hs_log, &ble_hs_log_console_handler);
 
-    ble_hs_hci_evt_buf = malloc(OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs,
-                                                 HCI_EVT_BUF_SIZE));
-    if (ble_hs_hci_evt_buf == NULL) {
-        rc = BLE_HS_ENOMEM;
-        goto err;
-    }
-
-    /* Create memory pool of command buffers */
-    rc = os_mempool_init(&g_hci_evt_pool, ble_hs_cfg.max_hci_bufs,
-                         HCI_EVT_BUF_SIZE, ble_hs_hci_evt_buf,
-                         "HCICmdPool");
-    assert(rc == 0);
-
-    ble_hs_hci_os_event_buf = malloc(OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs,
-                                                      HCI_OS_EVENT_BUF_SIZE));
+    ble_hs_hci_os_event_buf = malloc(
+        OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs, sizeof (struct os_event)));
     if (ble_hs_hci_os_event_buf == NULL) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
 
     /* Create memory pool of OS events */
-    rc = os_mempool_init(&g_hci_os_event_pool, ble_hs_cfg.max_hci_bufs,
-                         HCI_OS_EVENT_BUF_SIZE, ble_hs_hci_os_event_buf,
-                         "HCIOsEventPool");
+    rc = os_mempool_init(&ble_hs_hci_ev_pool, ble_hs_cfg.max_hci_bufs,
+                         sizeof (struct os_event), ble_hs_hci_os_event_buf,
+                         "ble_hs_hci_ev_pool");
     assert(rc == 0);
 
     /* Initialize eventq */
@@ -516,6 +635,9 @@ ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg)
     ble_hs_dbg_mutex_locked = 0;
 #endif
 
+    /* Configure the HCI transport to communicate with a host. */
+    ble_hci_trans_cfg_hs(host_hci_evt_rx, NULL, ble_hs_rx_data, NULL);
+
     return 0;
 
 err:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_hs_atomic.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic.c b/net/nimble/host/src/ble_hs_atomic.c
index 36a603d..9c933fc 100644
--- a/net/nimble/host/src/ble_hs_atomic.c
+++ b/net/nimble/host/src/ble_hs_atomic.c
@@ -93,3 +93,23 @@ ble_hs_atomic_conn_set_flags(uint16_t conn_handle, ble_hs_conn_flags_t flags,
 
     return rc;
 }
+
+uint16_t
+ble_hs_atomic_first_conn_handle(void)
+{
+    const struct ble_hs_conn *conn;
+    uint16_t conn_handle;
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_first();
+    if (conn != NULL) {
+        conn_handle = conn->bhc_handle;
+    } else {
+        conn_handle = BLE_HS_CONN_HANDLE_NONE;
+    }
+
+    ble_hs_unlock();
+
+    return conn_handle;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_hs_atomic_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic_priv.h b/net/nimble/host/src/ble_hs_atomic_priv.h
index a08b7ca..d82eeab 100644
--- a/net/nimble/host/src/ble_hs_atomic_priv.h
+++ b/net/nimble/host/src/ble_hs_atomic_priv.h
@@ -28,5 +28,6 @@ int ble_hs_atomic_conn_flags(uint16_t conn_handle,
                              ble_hs_conn_flags_t *out_flags);
 int ble_hs_atomic_conn_set_flags(uint16_t conn_handle,
                                  ble_hs_conn_flags_t flags, int on);
+uint16_t ble_hs_atomic_first_conn_handle(void);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_hs_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h
index 79ef6b9..9e788dd 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -47,9 +47,15 @@ struct ble_hs_conn;
 struct ble_l2cap_chan;
 struct os_mbuf;
 struct os_mempool;
+struct os_event;
 
 #define BLE_HOST_HCI_EVENT_CTLR_EVENT   (OS_EVENT_T_PERUSER + 0)
 #define BLE_HS_EVENT_TX_NOTIFICATIONS   (OS_EVENT_T_PERUSER + 1)
+#define BLE_HS_EVENT_RESET              (OS_EVENT_T_PERUSER + 2)
+
+#define BLE_HS_SYNC_STATE_BAD           0
+#define BLE_HS_SYNC_STATE_BRINGUP       1
+#define BLE_HS_SYNC_STATE_GOOD          2
 
 STATS_SECT_START(ble_hs_stats)
     STATS_SECT_ENTRY(conn_create)
@@ -58,17 +64,26 @@ STATS_SECT_START(ble_hs_stats)
     STATS_SECT_ENTRY(hci_event)
     STATS_SECT_ENTRY(hci_invalid_ack)
     STATS_SECT_ENTRY(hci_unknown_event)
+    STATS_SECT_ENTRY(hci_timeout)
+    STATS_SECT_ENTRY(reset)
+    STATS_SECT_ENTRY(sync)
 STATS_SECT_END
 extern STATS_SECT_DECL(ble_hs_stats) ble_hs_stats;
 
 extern struct ble_hs_cfg ble_hs_cfg;
 extern struct os_mbuf_pool ble_hs_mbuf_pool;
+extern uint8_t ble_hs_sync_state;
 
 extern const uint8_t ble_hs_misc_null_addr[6];
 
 void ble_hs_process_tx_data_queue(void);
 void ble_hs_process_rx_data_queue(void);
 int ble_hs_tx_data(struct os_mbuf *om);
+void ble_hs_enqueue_hci_event(uint8_t *hci_evt);
+void ble_hs_event_enqueue(struct os_event *ev);
+
+int host_hci_evt_rx(uint8_t *hci_ev, void *arg);
+int host_hci_acl_process(struct os_mbuf *om);
 
 int ble_hs_misc_malloc_mempool(void **mem, struct os_mempool *pool,
                                int num_entries, int entry_size, char *name);
@@ -86,6 +101,7 @@ int ble_hs_locked_by_cur_task(void);
 int ble_hs_is_parent_task(void);
 void ble_hs_lock(void);
 void ble_hs_unlock(void);
+void ble_hs_sched_reset(int reason);
 void ble_hs_heartbeat_sched(int32_t ticks);
 void ble_hs_notifications_sched(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_hs_pvcy.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_pvcy.c b/net/nimble/host/src/ble_hs_pvcy.c
index 05f9122..94a5586 100644
--- a/net/nimble/host/src/ble_hs_pvcy.c
+++ b/net/nimble/host/src/ble_hs_pvcy.c
@@ -145,11 +145,12 @@ ble_hs_pvcy_ensure_started(void)
     return 0;
 }
 
-void
+int
 ble_hs_pvcy_set_our_irk(const uint8_t *irk)
 {
     uint8_t tmp_addr[6];
     uint8_t new_irk[16];
+    int rc;
 
     memset(new_irk, 0, sizeof(new_irk));
 
@@ -163,17 +164,33 @@ ble_hs_pvcy_set_our_irk(const uint8_t *irk)
     if (memcmp(ble_hs_pvcy_irk, new_irk, 16) != 0) {
         memcpy(ble_hs_pvcy_irk, new_irk, 16);
 
-        ble_hs_pvcy_set_resolve_enabled(0);
-        ble_hs_pvcy_clear_entries();
-        ble_hs_pvcy_set_resolve_enabled(1);
+        rc = ble_hs_pvcy_set_resolve_enabled(0);
+        if (rc != 0) {
+            return rc;
+        }
+
+        rc = ble_hs_pvcy_clear_entries();
+        if (rc != 0) {
+            return rc;
+        }
+
+        rc = ble_hs_pvcy_set_resolve_enabled(1);
+        if (rc != 0) {
+            return rc;
+        }
 
         /* Push a null address identity to the controller.  The controller uses
          * this entry to generate an RPA when we do advertising with
          * own-addr-type = rpa.
          */
         memset(tmp_addr, 0, 6);
-        ble_hs_pvcy_add_entry(tmp_addr, 0, ble_hs_pvcy_irk);
+        rc = ble_hs_pvcy_add_entry(tmp_addr, 0, ble_hs_pvcy_irk);
+        if (rc != 0) {
+            return rc;
+        }
     }
+
+    return 0;
 }
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_hs_pvcy_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_pvcy_priv.h b/net/nimble/host/src/ble_hs_pvcy_priv.h
index 2635778..16ded35 100644
--- a/net/nimble/host/src/ble_hs_pvcy_priv.h
+++ b/net/nimble/host/src/ble_hs_pvcy_priv.h
@@ -22,7 +22,7 @@
 
 #include <inttypes.h>
 
-void ble_hs_pvcy_set_our_irk(const uint8_t *irk);
+int ble_hs_pvcy_set_our_irk(const uint8_t *irk);
 int ble_hs_pvcy_our_irk(const uint8_t **out_irk);
 int ble_hs_pvcy_remove_entry(uint8_t addr_type, uint8_t *addr);
 int ble_hs_pvcy_add_entry(uint8_t *addr, uint8_t addrtype, uint8_t *irk);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/ble_hs_startup.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_startup.c b/net/nimble/host/src/ble_hs_startup.c
index 45fb5ce..1ce49a7 100644
--- a/net/nimble/host/src/ble_hs_startup.c
+++ b/net/nimble/host/src/ble_hs_startup.c
@@ -222,19 +222,16 @@ ble_hs_startup_go(void)
 
     rc = ble_hs_startup_set_evmask_tx();
     if (rc != 0) {
-        assert(0);
         return rc;
     }
 
     rc = ble_hs_startup_le_set_evmask_tx();
     if (rc != 0) {
-        assert(0);
         return rc;
     }
 
     rc = ble_hs_startup_le_read_buf_sz_tx();
     if (rc != 0) {
-        assert(0);
         return rc;
     }
 
@@ -242,7 +239,6 @@ ble_hs_startup_go(void)
 
     rc = ble_hs_startup_le_read_sup_f_tx();
     if (rc != 0) {
-        assert(0);
         return rc;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/host_dbg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_dbg.c b/net/nimble/host/src/host_dbg.c
index 6b58624..f5d46a3 100644
--- a/net/nimble/host/src/host_dbg.c
+++ b/net/nimble/host/src/host_dbg.c
@@ -23,7 +23,7 @@
 #include "os/os.h"
 #include "console/console.h"
 #include "nimble/hci_common.h"
-#include "nimble/hci_transport.h"
+#include "nimble/ble_hci_trans.h"
 #include "ble_hs_priv.h"
 
 static void

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/host_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci.c b/net/nimble/host/src/host_hci.c
index 791aec2..ed5dd6a 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -23,7 +23,7 @@
 #include "os/os.h"
 #include "console/console.h"
 #include "nimble/hci_common.h"
-#include "nimble/hci_transport.h"
+#include "nimble/ble_hci_trans.h"
 #include "host/host_hci.h"
 #include "host/ble_gap.h"
 #include "ble_hs_priv.h"
@@ -582,7 +582,7 @@ host_hci_set_buf_size(uint16_t pktlen, uint8_t max_pkts)
 }
 
 int
-host_hci_event_rx(uint8_t *data)
+host_hci_evt_process(uint8_t *data)
 {
     const struct host_hci_event_dispatch_entry *entry;
     uint8_t event_code;
@@ -604,40 +604,20 @@ host_hci_event_rx(uint8_t *data)
 
     entry = host_hci_dispatch_entry_find(event_code);
     if (entry == NULL) {
-        STATS_INC(ble_hs_stats, hci_invalid_ack);
+        STATS_INC(ble_hs_stats, hci_unknown_event);
         rc = BLE_HS_ENOTSUP;
     } else {
         rc = entry->hed_fn(event_code, data, event_len);
     }
 
-    return rc;
-}
-
-int
-host_hci_os_event_proc(struct os_event *ev)
-{
-    os_error_t err;
-    int rc;
-
-    rc = host_hci_event_rx(ev->ev_arg);
-
-    /* Free the command buffer */
-    err = os_memblock_put(&g_hci_evt_pool, ev->ev_arg);
-    BLE_HS_DBG_ASSERT_EVAL(err == OS_OK);
-
-    /* Free the event */
-    err = os_memblock_put(&g_hci_os_event_pool, ev);
-    BLE_HS_DBG_ASSERT_EVAL(err == OS_OK);
+    ble_hci_trans_buf_free(data);
 
     return rc;
 }
 
-/* XXX: For now, put this here */
 int
-ble_hci_transport_ctlr_event_send(uint8_t *hci_ev)
+host_hci_evt_rx(uint8_t *hci_ev, void *arg)
 {
-    struct os_event *ev;
-    os_error_t err;
     int enqueue;
 
     BLE_HS_DBG_ASSERT(hci_ev != NULL);
@@ -659,25 +639,12 @@ ble_hci_transport_ctlr_event_send(uint8_t *hci_ev)
     }
 
     if (enqueue) {
-        /* Get an event structure off the queue */
-        ev = (struct os_event *)os_memblock_get(&g_hci_os_event_pool);
-        if (!ev) {
-            err = os_memblock_put(&g_hci_evt_pool, hci_ev);
-            BLE_HS_DBG_ASSERT_EVAL(err == OS_OK);
-            return -1;
-        }
-
-        /* Fill out the event and post to host task. */
-        ev->ev_queued = 0;
-        ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_EVENT;
-        ev->ev_arg = hci_ev;
-        ble_hs_event_enqueue(ev);
+        ble_hs_enqueue_hci_event(hci_ev);
     }
 
     return 0;
 }
 
-
 /**
  * Called when a data packet is received from the controller.  This function
  * consumes the supplied mbuf, regardless of the outcome.
@@ -688,7 +655,7 @@ ble_hci_transport_ctlr_event_send(uint8_t *hci_ev)
  * @return                      0 on success; nonzero on failure.
  */
 int
-host_hci_data_rx(struct os_mbuf *om)
+host_hci_acl_process(struct os_mbuf *om)
 {
     struct hci_data_hdr hci_hdr;
     struct ble_hs_conn *conn;
@@ -703,7 +670,7 @@ host_hci_data_rx(struct os_mbuf *om)
     }
 
 #if (BLETEST_THROUGHPUT_TEST == 0)
-    BLE_HS_LOG(DEBUG, "host_hci_data_rx(): handle=%u pb=%x len=%u data=",
+    BLE_HS_LOG(DEBUG, "host_hci_acl_process(): handle=%u pb=%x len=%u data=",
                BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc), 
                BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc), 
                hci_hdr.hdh_len);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/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 a3e021d..cce2e26 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -24,32 +24,17 @@
 #include "os/os.h"
 #include "console/console.h"
 #include "nimble/hci_common.h"
-#include "nimble/hci_transport.h"
+#include "nimble/ble_hci_trans.h"
 #include "host/host_hci.h"
 #include "host_dbg_priv.h"
 #include "ble_hs_priv.h"
-#ifdef PHONY_TRANSPORT
-#include "host/ble_hs_test.h"
-#endif
-
-/**
- * This buffer holds one of the following:
- * 1. The current outgoing HCI command.
- * 2. The current incoming HCI acknowledgement (command complete or command
- *    status event).
- */
-uint8_t host_hci_cmd_buf[HCI_EVT_BUF_SIZE];
 
 static int
 host_hci_cmd_transport(uint8_t *cmdbuf)
 {
-#ifdef PHONY_TRANSPORT
-    ble_hs_test_hci_txed(cmdbuf);
-    return 0;
-#else
     int rc;
 
-    rc = ble_hci_transport_host_cmd_send(cmdbuf);
+    rc = ble_hci_trans_hs_cmd_tx(cmdbuf);
     switch (rc) {
     case 0:
         return 0;
@@ -60,7 +45,6 @@ host_hci_cmd_transport(uint8_t *cmdbuf)
     default:
         return BLE_HS_EUNKNOWN;
     }
-#endif
 }
 
 void
@@ -79,19 +63,23 @@ host_hci_write_hdr(uint8_t ogf, uint8_t ocf, uint8_t len, void *buf)
 int
 host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, const void *cmddata)
 {
+    uint8_t *buf;
     int rc;
 
-    htole16(host_hci_cmd_buf, ogf << 10 | ocf);
-    host_hci_cmd_buf[2] = len;
+    buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD);
+    BLE_HS_DBG_ASSERT(buf != NULL);
+
+    htole16(buf, ogf << 10 | ocf);
+    buf[2] = len;
     if (len != 0) {
-        memcpy(host_hci_cmd_buf + BLE_HCI_CMD_HDR_LEN, cmddata, len);
+        memcpy(buf + BLE_HCI_CMD_HDR_LEN, cmddata, len);
     }
 
     BLE_HS_LOG(DEBUG, "host_hci_cmd_send: ogf=0x%02x ocf=0x%02x len=%d\n",
                ogf, ocf, len);
-    ble_hs_log_flat_buf(host_hci_cmd_buf, len + BLE_HCI_CMD_HDR_LEN);
+    ble_hs_log_flat_buf(buf, len + BLE_HCI_CMD_HDR_LEN);
     BLE_HS_LOG(DEBUG, "\n");
-    rc = host_hci_cmd_transport(host_hci_cmd_buf);
+    rc = host_hci_cmd_transport(buf);
 
     if (rc == 0) {
         STATS_INC(ble_hs_stats, hci_cmd);
@@ -110,6 +98,24 @@ host_hci_cmd_send_buf(void *buf)
     uint8_t len;
     int rc;
 
+    switch (ble_hs_sync_state) {
+    case BLE_HS_SYNC_STATE_BAD:
+        return BLE_HS_ENOTSYNCED;
+
+    case BLE_HS_SYNC_STATE_BRINGUP:
+        if (!ble_hs_is_parent_task()) {
+            return BLE_HS_ENOTSYNCED;
+        }
+        break;
+
+    case BLE_HS_SYNC_STATE_GOOD:
+        break;
+
+    default:
+        BLE_HS_DBG_ASSERT(0);
+        return BLE_HS_EUNKNOWN;
+    }
+
     u8ptr = buf;
 
     opcode = le16toh(u8ptr + 0);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/test/ble_gap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gap_test.c b/net/nimble/host/src/test/ble_gap_test.c
index faf62c3..2ae3354 100644
--- a/net/nimble/host/src/test/ble_gap_test.c
+++ b/net/nimble/host/src/test/ble_gap_test.c
@@ -1136,6 +1136,7 @@ TEST_CASE(ble_gap_test_case_conn_find)
 
     struct ble_gap_conn_desc desc;
     struct ble_hs_conn *conn;
+    uint8_t pub_addr[6];
     int rc;
 
     /*** We are master; public addresses. */
@@ -1150,6 +1151,10 @@ TEST_CASE(ble_gap_test_case_conn_find)
                                      ble_gap_test_util_connect_cb,
                                      NULL);
 
+
+    rc = ble_hs_id_copy_addr(BLE_ADDR_TYPE_PUBLIC, pub_addr, NULL);
+    TEST_ASSERT_FATAL(rc == 0);
+
     rc = ble_gap_conn_find(8, &desc);
     TEST_ASSERT_FATAL(rc == 0);
     TEST_ASSERT(desc.conn_handle == 8);
@@ -1157,8 +1162,8 @@ TEST_CASE(ble_gap_test_case_conn_find)
     TEST_ASSERT(desc.our_ota_addr_type == BLE_ADDR_TYPE_PUBLIC);
     TEST_ASSERT(desc.peer_ota_addr_type == BLE_ADDR_TYPE_PUBLIC);
     TEST_ASSERT(desc.role == BLE_GAP_ROLE_MASTER);
-    TEST_ASSERT(memcmp(desc.our_ota_addr, g_dev_addr, 6) == 0);
-    TEST_ASSERT(memcmp(desc.our_id_addr, g_dev_addr, 6) == 0);
+    TEST_ASSERT(memcmp(desc.our_ota_addr, pub_addr, 6) == 0);
+    TEST_ASSERT(memcmp(desc.our_id_addr, pub_addr, 6) == 0);
     TEST_ASSERT(memcmp(desc.peer_ota_addr,
                        ((uint8_t[6]){2,3,4,5,6,7}), 6) == 0);
     TEST_ASSERT(memcmp(desc.peer_id_addr,
@@ -1203,7 +1208,7 @@ TEST_CASE(ble_gap_test_case_conn_find)
     TEST_ASSERT(desc.role == BLE_GAP_ROLE_MASTER);
     TEST_ASSERT(memcmp(desc.our_ota_addr,
                        ((uint8_t[6]){0x40,1,2,3,4,5}), 6) == 0);
-    TEST_ASSERT(memcmp(desc.our_id_addr, g_dev_addr, 6) == 0);
+    TEST_ASSERT(memcmp(desc.our_id_addr, pub_addr, 6) == 0);
     TEST_ASSERT(memcmp(desc.peer_ota_addr,
                        ((uint8_t[6]){0x50,1,2,3,4,5}), 6) == 0);
     TEST_ASSERT(memcmp(desc.peer_id_addr,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/test/ble_host_hci_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_host_hci_test.c b/net/nimble/host/src/test/ble_host_hci_test.c
index a8e8d82..32c5cf4 100644
--- a/net/nimble/host/src/test/ble_host_hci_test.c
+++ b/net/nimble/host/src/test/ble_host_hci_test.c
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <string.h>
 #include "nimble/hci_common.h"
+#include "nimble/ble_hci_trans.h"
 #include "host/host_hci.h"
 #include "host/ble_hs_test.h"
 #include "testutil/testutil.h"
@@ -28,13 +29,16 @@
 
 TEST_CASE(ble_host_hci_test_event_bad)
 {
-    uint8_t buf[2];
+    uint8_t *buf;
     int rc;
 
     /*** Invalid event code. */
+    buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
+    TEST_ASSERT_FATAL(buf != NULL);
+
     buf[0] = 0xff;
     buf[1] = 0;
-    rc = host_hci_event_rx(buf);
+    rc = host_hci_evt_process(buf);
     TEST_ASSERT(rc == BLE_HS_ENOTSUP);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/test/ble_hs_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test.c b/net/nimble/host/src/test/ble_hs_test.c
index 16ae9b9..0b89bc9 100644
--- a/net/nimble/host/src/test/ble_hs_test.c
+++ b/net/nimble/host/src/test/ble_hs_test.c
@@ -23,22 +23,6 @@
 #include "testutil/testutil.h"
 #include "ble_hs_test_util.h"
 
-/* Our global device address. */
-uint8_t g_dev_addr[BLE_DEV_ADDR_LEN] = { 0x0a, 0x54, 0xab, 0x49, 0x7f, 0x06 };
-
-void
-ble_hs_test_pkt_txed(struct os_mbuf *om)
-{
-    ble_hs_test_util_prev_tx_enqueue(om);
-}
-
-void
-ble_hs_test_hci_txed(uint8_t *cmdbuf)
-{
-    ble_hs_test_util_enqueue_hci_tx(cmdbuf);
-    os_memblock_put(&g_hci_evt_pool, cmdbuf);
-}
-
 #ifdef MYNEWT_SELFTEST
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/test/ble_hs_test_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.c b/net/nimble/host/src/test/ble_hs_test_util.c
index 1a6dd5e..831a077 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -23,12 +23,21 @@
 #include "testutil/testutil.h"
 #include "nimble/ble.h"
 #include "nimble/hci_common.h"
-#include "nimble/hci_transport.h"
+#include "nimble/ble_hci_trans.h"
 #include "host/ble_hs_adv.h"
 #include "host/ble_hs_id.h"
 #include "host/host_hci.h"
+#include "transport/ram/ble_hci_ram.h"
 #include "ble_hs_test_util.h"
 
+/* Our global device address. */
+uint8_t g_dev_addr[BLE_DEV_ADDR_LEN];
+
+#define BLE_HS_TEST_UTIL_PUB_ADDR_VAL { 0x0a, 0x54, 0xab, 0x49, 0x7f, 0x06 }
+
+static const uint8_t ble_hs_test_util_pub_addr[BLE_DEV_ADDR_LEN] =
+    BLE_HS_TEST_UTIL_PUB_ADDR_VAL;
+
 /** Use lots of small mbufs to ensure correct mbuf usage. */
 #define BLE_HS_TEST_UTIL_NUM_MBUFS      (100)
 #define BLE_HS_TEST_UTIL_BUF_SIZE       OS_ALIGN(100, 4)
@@ -246,13 +255,14 @@ ble_hs_test_util_rx_hci_evt(uint8_t *evt)
     TEST_ASSERT_FATAL(totlen <= UINT8_MAX + BLE_HCI_EVENT_HDR_LEN);
 
     if (os_started()) {
-        evbuf = os_memblock_get(&g_hci_evt_pool);
+        evbuf = ble_hci_trans_buf_alloc(
+            BLE_HCI_TRANS_BUF_EVT_LO);
         TEST_ASSERT_FATAL(evbuf != NULL);
 
         memcpy(evbuf, evt, totlen);
-        rc = ble_hci_transport_ctlr_event_send(evbuf);
+        rc = ble_hci_trans_ll_evt_tx(evbuf);
     } else {
-        rc = host_hci_event_rx(evt);
+        rc = host_hci_evt_process(evt);
     }
 
     TEST_ASSERT_FATAL(rc == 0);
@@ -679,14 +689,6 @@ ble_hs_test_util_adv_start(uint8_t own_addr_type,
 
     if (adv_params->conn_mode != BLE_GAP_CONN_MODE_DIR) {
         acks[i] = (struct ble_hs_test_util_phony_ack) {
-            BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR),
-            ble_hs_test_util_exp_hci_status(i, fail_idx, fail_status),
-            { 0 },
-            1,
-        };
-        i++;
-
-        acks[i] = (struct ble_hs_test_util_phony_ack) {
             BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_SET_ADV_DATA),
             ble_hs_test_util_exp_hci_status(i, fail_idx, fail_status),
         };
@@ -777,6 +779,35 @@ ble_hs_test_util_conn_update(uint16_t conn_handle,
 }
 
 int
+ble_hs_test_util_set_our_irk(const uint8_t *irk, int fail_idx,
+                             uint8_t hci_status)
+{
+    int rc;
+
+    ble_hs_test_util_set_ack_seq(((struct ble_hs_test_util_phony_ack[]) {
+        {
+            BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
+            ble_hs_test_util_exp_hci_status(0, fail_idx, hci_status),
+        },
+        {
+            BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_CLR_RESOLV_LIST),
+            ble_hs_test_util_exp_hci_status(1, fail_idx, hci_status),
+        },
+        {
+            BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
+            ble_hs_test_util_exp_hci_status(2, fail_idx, hci_status),
+        },
+        {
+            BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_ADD_RESOLV_LIST),
+            ble_hs_test_util_exp_hci_status(3, fail_idx, hci_status),
+        },
+    }));
+
+    rc = ble_hs_pvcy_set_our_irk(irk);
+    return rc;
+}
+
+int
 ble_hs_test_util_security_initiate(uint16_t conn_handle, uint8_t hci_status)
 {
     int rc;
@@ -906,7 +937,8 @@ ble_hs_test_util_set_startup_acks(void)
         {
             .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
                                            BLE_HCI_OCF_LE_RD_BUF_SIZE),
-            .evt_params = { 0xff, 0xff, 1 },
+            /* Use a very low buffer size (16) to test fragmentation. */
+            .evt_params = { 0x10, 0x00, 0x20 },
             .evt_params_len = 3,
         },
         {
@@ -916,6 +948,12 @@ ble_hs_test_util_set_startup_acks(void)
             .evt_params_len = 8,
         },
         {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_INFO_PARAMS,
+                                           BLE_HCI_OCF_IP_RD_BD_ADDR),
+            .evt_params = BLE_HS_TEST_UTIL_PUB_ADDR_VAL,
+            .evt_params_len = 6,
+        },
+        {
             .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
                                            BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
         },
@@ -1279,9 +1317,25 @@ ble_hs_test_util_post_test(void *arg)
     ble_hs_test_util_assert_mbufs_freed();
 }
 
+static int
+ble_hs_test_util_pkt_txed(struct os_mbuf *om, void *arg)
+{
+    ble_hs_test_util_prev_tx_enqueue(om);
+    return 0;
+}
+
+static int
+ble_hs_test_util_hci_txed(uint8_t *cmdbuf, void *arg)
+{
+    ble_hs_test_util_enqueue_hci_tx(cmdbuf);
+    ble_hci_trans_buf_free(cmdbuf);
+    return 0;
+}
+
 void
 ble_hs_test_util_init(void)
 {
+    struct ble_hci_ram_cfg hci_cfg;
     struct ble_hs_cfg cfg;
     int rc;
 
@@ -1323,10 +1377,18 @@ ble_hs_test_util_init(void)
 
     ble_hci_set_phony_ack_cb(NULL);
 
-    ble_hs_test_util_prev_hci_tx_clear();
+    ble_hci_trans_cfg_ll(ble_hs_test_util_hci_txed, NULL,
+                                ble_hs_test_util_pkt_txed, NULL);
 
-    ble_hs_id_set_pub(g_dev_addr);
+    hci_cfg = ble_hci_ram_cfg_dflt;
+    hci_cfg.num_evt_bufs = cfg.max_hci_bufs;
+    rc = ble_hci_ram_init(&hci_cfg);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    ble_hs_test_util_set_startup_acks();
 
-    /* Use a very low buffer size (16) to test fragmentation. */
-    host_hci_set_buf_size(16, 64);
+    rc = ble_hs_start();
+    TEST_ASSERT_FATAL(rc == 0);
+
+    ble_hs_test_util_prev_hci_tx_clear();
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/test/ble_hs_test_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.h b/net/nimble/host/src/test/ble_hs_test_util.h
index 9c4b982..00b090f 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.h
+++ b/net/nimble/host/src/test/ble_hs_test_util.h
@@ -106,6 +106,8 @@ int ble_hs_test_util_wl_set(struct ble_gap_white_entry *white_list,
 int ble_hs_test_util_conn_update(uint16_t conn_handle,
                                  struct ble_gap_upd_params *params,
                                  uint8_t hci_status);
+int ble_hs_test_util_set_our_irk(const uint8_t *irk, int fail_idx,
+                                 uint8_t hci_status);
 int ble_hs_test_util_security_initiate(uint16_t conn_handle,
                                        uint8_t hci_status);
 int ble_hs_test_util_l2cap_rx_first_frag(uint16_t conn_handle, uint16_t cid,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/test/ble_os_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_os_test.c b/net/nimble/host/src/test/ble_os_test.c
index 1ab8e0a..e12e489 100644
--- a/net/nimble/host/src/test/ble_os_test.c
+++ b/net/nimble/host/src/test/ble_os_test.c
@@ -21,7 +21,7 @@
 #include "os/os.h"
 #include "testutil/testutil.h"
 #include "nimble/hci_common.h"
-#include "nimble/hci_transport.h"
+#include "nimble/ble_hci_trans.h"
 #include "host/ble_hs_test.h"
 #include "host/ble_gap.h"
 #include "ble_hs_test_util.h"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/host/src/test/ble_sm_test_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_sm_test_util.c b/net/nimble/host/src/test/ble_sm_test_util.c
index 1c052fb..bdecde6 100644
--- a/net/nimble/host/src/test/ble_sm_test_util.c
+++ b/net/nimble/host/src/test/ble_sm_test_util.c
@@ -229,7 +229,7 @@ ble_sm_test_util_init_good(struct ble_sm_test_params *params,
     ble_sm_dbg_set_next_ediv(out_us->ediv);
     ble_sm_dbg_set_next_master_id_rand(out_us->rand_num);
     ble_sm_dbg_set_next_ltk(out_us->ltk);
-    ble_hs_pvcy_set_our_irk(out_us->id_info->irk);
+    ble_hs_test_util_set_our_irk(out_us->id_info->irk, 0, 0);
     ble_sm_dbg_set_next_csrk(out_us->sign_info->sig_key);
 
     if (out_us->public_key != NULL) {
@@ -909,8 +909,20 @@ ble_sm_test_util_verify_tx_lt_key_req_neg_reply(uint16_t conn_handle)
 }
 
 static void
-ble_sm_test_util_set_lt_key_req_reply_ack(uint8_t status,
-                                                uint16_t conn_handle)
+ble_sm_test_util_set_lt_key_req_neg_reply_ack(uint8_t status,
+                                              uint16_t conn_handle)
+{
+    static uint8_t params[BLE_HCI_LT_KEY_REQ_NEG_REPLY_ACK_PARAM_LEN];
+
+    htole16(params, conn_handle);
+    ble_hs_test_util_set_ack_params(
+        host_hci_opcode_join(BLE_HCI_OGF_LE,
+                             BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY),
+        status, params, sizeof params);
+}
+
+static void
+ble_sm_test_util_set_lt_key_req_reply_ack(uint8_t status, uint16_t conn_handle)
 {
     static uint8_t params[BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN];
 
@@ -1303,7 +1315,7 @@ ble_sm_test_util_peer_bonding_bad(uint16_t ediv, uint64_t rand_num)
     TEST_ASSERT(ble_sm_dbg_num_procs() == 0);
 
     /* Receive a long term key request from the controller. */
-    ble_sm_test_util_set_lt_key_req_reply_ack(0, 2);
+    ble_sm_test_util_set_lt_key_req_neg_reply_ack(0, 2);
     ble_sm_test_util_rx_lt_key_req(2, rand_num, ediv);
     TEST_ASSERT(!conn->bhc_sec_state.encrypted);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/include/nimble/ble.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h
index f2041c8..4deb9f3 100644
--- a/net/nimble/include/nimble/ble.h
+++ b/net/nimble/include/nimble/ble.h
@@ -34,10 +34,6 @@ struct ble_encryption_block
     uint8_t     cipher_text[BLE_ENC_BLOCK_SIZE];
 };
 
-/* Shared command pool for transort between host and controller */
-extern struct os_mempool g_hci_evt_pool;
-extern struct os_mempool g_hci_os_event_pool;
-
 /*
  * BLE MBUF structure:
  *

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/include/nimble/ble_hci_trans.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/ble_hci_trans.h b/net/nimble/include/nimble/ble_hci_trans.h
new file mode 100644
index 0000000..822da96
--- /dev/null
+++ b/net/nimble/include/nimble/ble_hci_trans.h
@@ -0,0 +1,152 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_HCI_TRANSPORT_
+#define H_HCI_TRANSPORT_
+
+#include <inttypes.h>
+struct os_mbuf;
+
+#define BLE_HCI_TRANS_CMD_SZ        260
+
+/*** Type of buffers for holding commands and events. */
+/**
+ * Low-priority event (advertising reports).  A request to allocate a
+ * high-priority event buffer may allocate one of these instead if no
+ * high-priority buffers are available.
+ */
+#define BLE_HCI_TRANS_BUF_EVT_LO    1
+
+/* High-priority event (all events except advertising reports). */
+#define BLE_HCI_TRANS_BUF_EVT_HI    2
+
+/* Host-to-controller command. */
+#define BLE_HCI_TRANS_BUF_CMD       3
+
+/** Callback function types; executed when HCI packets are received. */
+typedef int ble_hci_trans_rx_cmd_fn(uint8_t *cmd, void *arg);
+typedef int ble_hci_trans_rx_acl_fn(struct os_mbuf *om, void *arg);
+
+/**
+ * Sends an HCI event from the controller to the host.
+ *
+ * @param cmd                   The HCI event to send.  This buffer must be
+ *                                  allocated via ble_hci_trans_buf_alloc().
+ *
+ * @return                      0 on success;
+ *                              A BLE_ERR_[...] error code on failure.
+ */
+int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev);
+
+/**
+ * Sends ACL data from controller to host.
+ *
+ * @param om                    The ACL data packet to send.
+ *
+ * @return                      0 on success;
+ *                              A BLE_ERR_[...] error code on failure.
+ */
+int ble_hci_trans_ll_acl_tx(struct os_mbuf *om);
+
+/**
+ * Sends an HCI command from the host to the controller.
+ *
+ * @param cmd                   The HCI command to send.  This buffer must be
+ *                                  allocated via ble_hci_trans_buf_alloc().
+ *
+ * @return                      0 on success;
+ *                              A BLE_ERR_[...] error code on failure.
+ */
+int ble_hci_trans_hs_cmd_tx(uint8_t *cmd);
+
+/**
+ * Sends ACL data from host to controller.
+ *
+ * @param om                    The ACL data packet to send.
+ *
+ * @return                      0 on success;
+ *                              A BLE_ERR_[...] error code on failure.
+ */
+int ble_hci_trans_hs_acl_tx(struct os_mbuf *om);
+
+/**
+ * Allocates a flat buffer of the specified type.
+ *
+ * @param type                  The type of buffer to allocate; one of the
+ *                                  BLE_HCI_TRANS_BUF_[...] constants.
+ *
+ * @return                      The allocated buffer on success;
+ *                              NULL on buffer exhaustion.
+ */
+uint8_t *ble_hci_trans_buf_alloc(int type);
+
+/**
+ * Frees the specified flat buffer.  The buffer must have been allocated via
+ * ble_hci_trans_buf_alloc().
+ *
+ * @param buf                   The buffer to free.
+ */
+void ble_hci_trans_buf_free(uint8_t *buf);
+
+/**
+ * Configures the HCI transport to operate with a controller.  The transport
+ * will execute specified callbacks upon receiving HCI packets from the host.
+ *
+ * @param cmd_cb                The callback to execute upon receiving an HCI
+ *                                  command.
+ * @param cmd_arg               Optional argument to pass to the command
+ *                                  callback.
+ * @param acl_cb                The callback to execute upon receiving ACL
+ *                                  data.
+ * @param acl_arg               Optional argument to pass to the ACL
+ *                                  callback.
+ */
+void ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb,
+                          void *cmd_arg,
+                          ble_hci_trans_rx_acl_fn *acl_cb,
+                          void *acl_arg);
+
+/**
+ * Configures the HCI transport to operate with a host.  The transport will
+ * execute specified callbacks upon receiving HCI packets from the controller.
+ *
+ * @param cmd_cb                The callback to execute upon receiving an HCI
+ *                                  event.
+ * @param cmd_arg               Optional argument to pass to the command
+ *                                  callback.
+ * @param acl_cb                The callback to execute upon receiving ACL
+ *                                  data.
+ * @param acl_arg               Optional argument to pass to the ACL
+ *                                  callback.
+ */
+void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb,
+                          void *cmd_arg,
+                          ble_hci_trans_rx_acl_fn *acl_cb,
+                          void *acl_arg);
+
+/**
+ * Resets the HCI module to a clean state.  Frees all buffers and reinitializes
+ * the underlying transport.
+ *
+ * @return                      0 on success;
+ *                              A BLE_ERR_[...] error code on failure.
+ */
+int ble_hci_trans_reset(void);
+
+#endif /* H_HCI_TRANSPORT_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/include/nimble/hci_transport.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/hci_transport.h b/net/nimble/include/nimble/hci_transport.h
deleted file mode 100644
index 7de737c..0000000
--- a/net/nimble/include/nimble/hci_transport.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef H_HCI_TRANSPORT_
-#define H_HCI_TRANSPORT_
-
-/* Send a HCI command from the host to the controller */
-int ble_hci_transport_host_cmd_send(uint8_t *cmd);
-
-/* Send a HCI event from the controller to the host */
-int ble_hci_transport_ctlr_event_send(uint8_t *hci_ev);
-
-/* Send ACL data from host to contoller */
-int ble_hci_transport_host_acl_data_send(struct os_mbuf *om);
-
-#endif /* H_HCI_TRANSPORT_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/transport/ram/include/transport/ram/ble_hci_ram.h
----------------------------------------------------------------------
diff --git a/net/nimble/transport/ram/include/transport/ram/ble_hci_ram.h b/net/nimble/transport/ram/include/transport/ram/ble_hci_ram.h
new file mode 100644
index 0000000..1c5b58e
--- /dev/null
+++ b/net/nimble/transport/ram/include/transport/ram/ble_hci_ram.h
@@ -0,0 +1,15 @@
+#ifndef H_BLE_HCI_RAM_
+#define H_BLE_HCI_RAM_
+
+#include "nimble/ble_hci_trans.h"
+
+struct ble_hci_ram_cfg {
+    uint16_t num_evt_bufs;
+    uint16_t evt_buf_sz;
+};
+
+extern const struct ble_hci_ram_cfg ble_hci_ram_cfg_dflt;
+
+int ble_hci_ram_init(const struct ble_hci_ram_cfg *cfg);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/transport/ram/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/transport/ram/pkg.yml b/net/nimble/transport/ram/pkg.yml
new file mode 100644
index 0000000..a3524a1
--- /dev/null
+++ b/net/nimble/transport/ram/pkg.yml
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: net/nimble/transport/ram
+pkg.description: XXX
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - ble
+    - bluetooth
+
+pkg.deps:
+    - net/nimble
+    - libs/os
+
+pkg.apis:
+    - ble_transport

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/transport/ram/src/ble_hci_ram.c
----------------------------------------------------------------------
diff --git a/net/nimble/transport/ram/src/ble_hci_ram.c b/net/nimble/transport/ram/src/ble_hci_ram.c
new file mode 100644
index 0000000..aac5eb1
--- /dev/null
+++ b/net/nimble/transport/ram/src/ble_hci_ram.c
@@ -0,0 +1,190 @@
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+#include "os/os.h"
+#include "nimble/ble_hci_trans.h"
+#include "transport/ram/ble_hci_ram.h"
+
+/** Default configuration. */
+const struct ble_hci_ram_cfg ble_hci_ram_cfg_dflt = {
+    .num_evt_bufs = 3,
+    .evt_buf_sz = BLE_HCI_TRANS_CMD_SZ,
+};
+
+static ble_hci_trans_rx_cmd_fn *ble_hci_ram_rx_cmd_hs_cb;
+static void *ble_hci_ram_rx_cmd_hs_arg;
+
+static ble_hci_trans_rx_cmd_fn *ble_hci_ram_rx_cmd_ll_cb;
+static void *ble_hci_ram_rx_cmd_ll_arg;
+
+static ble_hci_trans_rx_acl_fn *ble_hci_ram_rx_acl_hs_cb;
+static void *ble_hci_ram_rx_acl_hs_arg;
+
+static ble_hci_trans_rx_acl_fn *ble_hci_ram_rx_acl_ll_cb;
+static void *ble_hci_ram_rx_acl_ll_arg;
+
+static struct os_mempool ble_hci_ram_evt_pool;
+static void *ble_hci_ram_evt_buf;
+
+static uint8_t *ble_hci_ram_hs_cmd_buf;
+static uint8_t ble_hci_ram_hs_cmd_buf_alloced;
+
+void
+ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb,
+                                void *cmd_arg,
+                                ble_hci_trans_rx_acl_fn *acl_cb,
+                                void *acl_arg)
+{
+    ble_hci_ram_rx_cmd_hs_cb = cmd_cb;
+    ble_hci_ram_rx_cmd_hs_arg = cmd_arg;
+    ble_hci_ram_rx_acl_hs_cb = acl_cb;
+    ble_hci_ram_rx_acl_hs_arg = acl_arg;
+}
+
+void
+ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb,
+                                void *cmd_arg,
+                                ble_hci_trans_rx_acl_fn *acl_cb,
+                                void *acl_arg)
+{
+    ble_hci_ram_rx_cmd_ll_cb = cmd_cb;
+    ble_hci_ram_rx_cmd_ll_arg = cmd_arg;
+    ble_hci_ram_rx_acl_ll_cb = acl_cb;
+    ble_hci_ram_rx_acl_ll_arg = acl_arg;
+}
+
+int
+ble_hci_trans_hs_cmd_tx(uint8_t *cmd)
+{
+    int rc;
+
+    assert(ble_hci_ram_rx_cmd_ll_cb != NULL);
+
+    rc = ble_hci_ram_rx_cmd_ll_cb(cmd, ble_hci_ram_rx_cmd_ll_arg);
+    return rc;
+}
+
+int
+ble_hci_trans_ll_evt_tx(uint8_t *hci_ev)
+{
+    int rc;
+
+    assert(ble_hci_ram_rx_cmd_hs_cb != NULL);
+
+    rc = ble_hci_ram_rx_cmd_hs_cb(hci_ev, ble_hci_ram_rx_cmd_hs_arg);
+    return rc;
+}
+
+int
+ble_hci_trans_hs_acl_tx(struct os_mbuf *om)
+{
+    int rc;
+
+    assert(ble_hci_ram_rx_acl_ll_cb != NULL);
+
+    rc = ble_hci_ram_rx_acl_ll_cb(om, ble_hci_ram_rx_acl_ll_arg);
+    return rc;
+}
+
+int
+ble_hci_trans_ll_acl_tx(struct os_mbuf *om)
+{
+    int rc;
+
+    assert(ble_hci_ram_rx_acl_hs_cb != NULL);
+
+    rc = ble_hci_ram_rx_acl_hs_cb(om, ble_hci_ram_rx_acl_hs_arg);
+    return rc;
+}
+
+uint8_t *
+ble_hci_trans_buf_alloc(int type)
+{
+    uint8_t *buf;
+
+    switch (type) {
+    case BLE_HCI_TRANS_BUF_EVT_LO:
+    case BLE_HCI_TRANS_BUF_EVT_HI:
+        buf = os_memblock_get(&ble_hci_ram_evt_pool);
+        break;
+
+    case BLE_HCI_TRANS_BUF_CMD:
+        assert(!ble_hci_ram_hs_cmd_buf_alloced);
+        ble_hci_ram_hs_cmd_buf_alloced = 1;
+        buf = ble_hci_ram_hs_cmd_buf;
+        break;
+
+    default:
+        assert(0);
+        buf = NULL;
+    }
+
+    return buf;
+}
+
+void
+ble_hci_trans_buf_free(uint8_t *buf)
+{
+    int rc;
+
+    if (buf == ble_hci_ram_hs_cmd_buf) {
+        assert(ble_hci_ram_hs_cmd_buf_alloced);
+        ble_hci_ram_hs_cmd_buf_alloced = 0;
+    } else {
+        rc = os_memblock_put(&ble_hci_ram_evt_pool, buf);
+        assert(rc == 0);
+    }
+}
+
+static void
+ble_hci_ram_free_mem(void)
+{
+    free(ble_hci_ram_evt_buf);
+    ble_hci_ram_evt_buf = NULL;
+
+    free(ble_hci_ram_hs_cmd_buf);
+    ble_hci_ram_hs_cmd_buf = NULL;
+    ble_hci_ram_hs_cmd_buf_alloced = 0;
+}
+
+int
+ble_hci_trans_reset(void)
+{
+    return 0;
+}
+
+int
+ble_hci_ram_init(const struct ble_hci_ram_cfg *cfg)
+{
+    int rc;
+
+    ble_hci_ram_free_mem();
+
+    ble_hci_ram_evt_buf = malloc(OS_MEMPOOL_BYTES(cfg->num_evt_bufs,
+                                                  cfg->evt_buf_sz));
+    if (ble_hci_ram_evt_buf == NULL) {
+        rc = ENOMEM;
+        goto err;
+    }
+
+    /* Create memory pool of command buffers */
+    rc = os_mempool_init(&ble_hci_ram_evt_pool, cfg->num_evt_bufs,
+                         cfg->evt_buf_sz, ble_hci_ram_evt_buf,
+                         "ble_hci_ram_evt_pool");
+    if (rc != 0) {
+        rc = EINVAL;
+        goto err;
+    }
+
+    ble_hci_ram_hs_cmd_buf = malloc(BLE_HCI_TRANS_CMD_SZ);
+    if (ble_hci_ram_hs_cmd_buf == NULL) {
+        rc = ENOMEM;
+        goto err;
+    }
+
+    return 0;
+
+err:
+    ble_hci_ram_free_mem();
+    return rc;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h
----------------------------------------------------------------------
diff --git a/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h b/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h
new file mode 100644
index 0000000..1fbaa74
--- /dev/null
+++ b/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h
@@ -0,0 +1,19 @@
+#ifndef H_BLE_HCI_UART_
+#define H_BLE_HCI_UART_
+
+struct ble_hci_uart_cfg {
+    uint32_t baud;
+    uint16_t num_evt_bufs;
+    uint16_t evt_buf_sz;
+    uint8_t uart_port;
+    uint8_t flow_ctrl;
+    uint8_t data_bits;
+    uint8_t stop_bits;
+    uint8_t parity;
+};
+
+extern const struct ble_hci_uart_cfg ble_hci_uart_cfg_dflt;
+
+int ble_hci_uart_init(const struct ble_hci_uart_cfg *cfg);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0fd02e1e/net/nimble/transport/uart/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/transport/uart/pkg.yml b/net/nimble/transport/uart/pkg.yml
new file mode 100644
index 0000000..cce429c
--- /dev/null
+++ b/net/nimble/transport/uart/pkg.yml
@@ -0,0 +1,34 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: net/nimble/transport/uart
+pkg.description: XXX
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - ble
+    - bluetooth
+
+pkg.deps:
+    - hw/hal
+    - libs/os
+    - net/nimble
+
+pkg.apis:
+    - ble_transport