You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/04/28 02:14:00 UTC

[01/50] [abbrv] incubator-mynewt-core git commit: MYNEWT-99: Port encryption to nrf51

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/master bf35f3a7c -> 8ddc20eed


MYNEWT-99: Port encryption to nrf51

Add encryption support for the nrf51. The nrf51 cannot encrypt
or decrypt frames with payload greater than 27 bytes. This
means if you turn on encryption you will have to change the
maximum LL packet size in the nimble options header file to
27 as the default is 251.


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

Branch: refs/heads/master
Commit: a590265d37f3bf671969f15cccf8b92828a1da92
Parents: 73ee5e8
Author: William San Filippo <wi...@runtime.io>
Authored: Mon Apr 18 23:25:04 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Mon Apr 18 23:30:06 2016 -0700

----------------------------------------------------------------------
 net/nimble/controller/src/ble_ll.c      |   3 +-
 net/nimble/controller/src/ble_ll_ctrl.c |  14 +-
 net/nimble/drivers/nrf51/src/ble_phy.c  | 247 ++++++++++++++++++++++++++-
 net/nimble/drivers/nrf52/src/ble_phy.c  |  40 +++--
 net/nimble/include/nimble/nimble_opt.h  |  52 +++---
 5 files changed, 303 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a590265d/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 0ffcfe9..003d594 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -735,8 +735,7 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *ble_hdr)
     chan = ble_hdr->rxinfo.channel;
     crcok = BLE_MBUF_HDR_CRC_OK(ble_hdr);
 
-    ble_ll_log(BLE_LL_LOG_ID_RX_END,
-               rxbuf[0],
+    ble_ll_log(BLE_LL_LOG_ID_RX_END, rxbuf[0],
                ((uint16_t)ble_hdr->rxinfo.flags << 8) | rxbuf[1],
                (BLE_MBUF_HDR_PTR(rxpdu))->end_cputime);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a590265d/net/nimble/controller/src/ble_ll_ctrl.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_ctrl.c b/net/nimble/controller/src/ble_ll_ctrl.c
index 04ddd5b..63b4c98 100644
--- a/net/nimble/controller/src/ble_ll_ctrl.c
+++ b/net/nimble/controller/src/ble_ll_ctrl.c
@@ -31,14 +31,18 @@
 /* To use spec sample data for testing */
 #undef BLE_LL_ENCRYPT_USE_TEST_DATA
 
-/* For console debug to show session key calculation */
+/*
+ * For console debug to show session key calculation. NOTE: if you define
+ * this the stack requirements for the LL task go up considerably. The
+ * default stack will not be enough and must be increased.
+ */
 #undef BLE_LL_ENCRYPT_DEBUG
 #ifdef BLE_LL_ENCRYPT_DEBUG
 #include "console/console.h"
 #endif
 
 /*
- * XXX: TODO
+ * XXX:
  *  1) Do I need to keep track of which procedures have already been done?
  *     Do I need to worry about repeating procedures?
  *  2) Should we create pool of control pdu's?. Dont need more
@@ -52,14 +56,8 @@
  *  5) We are supposed to remember when we do the data length update proc if
  *  the device sent us an unknown rsp. We should not send it another len req.
  *  Implement this how? Through remote supported features?
- *  6) Remember: some procedures dont have timeout rules.
- *  7) Says that we should reset procedure timer whenever a LL control pdu
- *  is queued for transmission. I dont get it... do some procedures send
- *  multiple packets? I guess so.
  *  8) How to count control pdus sent. DO we count enqueued + sent, or only
  *  sent (actually attempted to tx). Do we count failures? How?
- *  9) NOTE: we are not supposed to send a REJECT_IND_EXT unless we know the
- *  slave supports that feature
  */
 
 /*

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a590265d/net/nimble/drivers/nrf51/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf51/src/ble_phy.c b/net/nimble/drivers/nrf51/src/ble_phy.c
index 4de8e83..bc4a258 100644
--- a/net/nimble/drivers/nrf51/src/ble_phy.c
+++ b/net/nimble/drivers/nrf51/src/ble_phy.c
@@ -18,16 +18,36 @@
  */
 
 #include <stdint.h>
+#include <string.h>
 #include <assert.h>
 #include "os/os.h"
 #include "bsp/cmsis_nvic.h"
 #include "nimble/ble.h"
+#include "nimble/nimble_opt.h"
 #include "controller/ble_phy.h"
 #include "controller/ble_ll.h"
 #include "mcu/nrf51_bitfields.h"
 
+/*
+ * XXX: need to make the copy from mbuf into the PHY data structures 32-bit
+ * copies or we are screwed.
+ */
+
 /* XXX: 4) Make sure RF is higher priority interrupt than schedule */
 
+/*
+ * XXX: Maximum possible transmit time is 1 msec for a 60ppm crystal
+ * and 16ms for a 30ppm crystal! We need to limit PDU size based on
+ * crystal accuracy
+ */
+
+/* The NRF51 does not support encryption for payload size < 27 bytes */
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+#if (NIMBLE_OPT_LL_MAX_PKT_SIZE > 27)
+#error "nrf51 does not support encryption with packet size > 27 bytes!"
+#endif
+#endif
+
 /* To disable all radio interrupts */
 #define NRF_RADIO_IRQ_MASK_ALL  (0x34FF)
 
@@ -55,6 +75,7 @@ struct ble_phy_obj
     uint8_t phy_state;
     uint8_t phy_transition;
     uint8_t phy_rx_started;
+    uint8_t phy_encrypted;
     uint32_t phy_access_address;
     struct os_mbuf *rxpdu;
     void *txend_arg;
@@ -62,9 +83,14 @@ struct ble_phy_obj
 };
 struct ble_phy_obj g_ble_phy_data;
 
+/* XXX: if 27 byte packets desired we can make this smaller */
 /* Global transmit/receive buffer */
 static uint32_t g_ble_phy_txrx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
 
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+static uint32_t g_ble_phy_enc_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+#endif
+
 /* Statistics */
 STATS_SECT_START(ble_phy_stats)
     STATS_SECT_ENTRY(phy_isrs)
@@ -128,6 +154,24 @@ STATS_NAME_END(ble_phy_stats)
  *  bit in the NVIC just to be sure when we disable the PHY.
  */
 
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+
+/* Per nordic, the number of bytes needed for scratch is 16 + MAX_PKT_SIZE */
+#define NRF_ENC_SCRATCH_WORDS   (((NIMBLE_OPT_LL_MAX_PKT_SIZE + 16) + 3) / 4)
+
+uint32_t g_nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS];
+
+struct nrf_ccm_data
+{
+    uint8_t key[16];
+    uint64_t pkt_counter;
+    uint8_t dir_bit;
+    uint8_t iv[8];
+} __attribute__((packed));
+
+struct nrf_ccm_data g_nrf_ccm_data;
+#endif
+
 /**
  * ble phy rxpdu get
  *
@@ -185,6 +229,9 @@ ble_phy_isr(void)
     uint32_t irq_en;
     uint32_t state;
     uint32_t wfr_time;
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    uint8_t *dptr;
+#endif
     struct os_mbuf *rxpdu;
     struct ble_mbuf_hdr *ble_hdr;
 
@@ -197,7 +244,7 @@ ble_phy_isr(void)
         assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
 
         ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
-                   0, NRF_TIMER0->CC[2]);
+                   g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
 
         /* Clear events and clear interrupt on disabled event */
         NRF_RADIO->EVENTS_DISABLED = 0;
@@ -205,6 +252,19 @@ ble_phy_isr(void)
         NRF_RADIO->EVENTS_END = 0;
         state = NRF_RADIO->SHORTS;
 
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+        /*
+         * XXX: not sure what to do. We had a HW error during transmission.
+         * For now I just count a stat but continue on like all is good.
+         */
+        if (g_ble_phy_data.phy_encrypted) {
+            if (NRF_CCM->EVENTS_ERROR) {
+                STATS_INC(ble_phy_stats, tx_hw_err);
+                NRF_CCM->EVENTS_ERROR = 0;
+            }
+        }
+#endif
+
         transition = g_ble_phy_data.phy_transition;
         if (transition == BLE_PHY_TRANSITION_TX_RX) {
             /* Clear the rx started flag */
@@ -212,7 +272,23 @@ ble_phy_isr(void)
 
             /* Packet pointer needs to be reset. */
             if (g_ble_phy_data.rxpdu != NULL) {
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+                if (g_ble_phy_data.phy_encrypted) {
+                    NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+                    NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+                    NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+                    NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
+                    NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
+                    NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
+                    NRF_CCM->SHORTS = 0;
+                    NRF_CCM->EVENTS_ENDCRYPT = 0;
+                    NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
+                } else {
+                    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+                }
+#else
                 NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+#endif
 
                 /* I want to know when 1st byte received (after address) */
                 NRF_RADIO->BCC = 8; /* in bits */
@@ -322,7 +398,9 @@ ble_phy_isr(void)
         assert(NRF_RADIO->EVENTS_RSSIEND != 0);
         ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
         ble_hdr->end_cputime = NRF_TIMER0->CC[2];
-
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+        dptr = g_ble_phy_data.rxpdu->om_data;
+#endif
         /* Count PHY crc errors and valid packets */
         crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
         if (!crcok) {
@@ -330,11 +408,53 @@ ble_phy_isr(void)
         } else {
             STATS_INC(ble_phy_stats, rx_valid);
             ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+            if (g_ble_phy_data.phy_encrypted) {
+                /* Only set MIC failure flag if frame is not zero length */
+                if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
+                    ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE;
+                }
+
+                /*
+                 * XXX: not sure how to deal with this. This should not
+                 * be a MIC failure but we should not hand it up. I guess
+                 * this is just some form of rx error and that is how we
+                 * handle it? For now, just set CRC error flags
+                 */
+                if (NRF_CCM->EVENTS_ERROR) {
+                    STATS_INC(ble_phy_stats, rx_hw_err);
+                    ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
+                }
+
+                /*
+                 * XXX: This is a total hack work-around for now but I dont
+                 * know what else to do. If ENDCRYPT is not set and we are
+                 * encrypted we need to not trust this frame and drop it.
+                 */
+                if (NRF_CCM->EVENTS_ENDCRYPT == 0) {
+                    STATS_INC(ble_phy_stats, rx_hw_err);
+                    ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
+                }
+            }
+#endif
         }
 
         /* Call Link Layer receive payload function */
         rxpdu = g_ble_phy_data.rxpdu;
         g_ble_phy_data.rxpdu = NULL;
+
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+        if (g_ble_phy_data.phy_encrypted) {
+            /*
+             * XXX: This is a horrible ugly hack to deal with the RAM S1 byte.
+             * This should get fixed as we should not be handing up the header
+             * and length as part of the pdu.
+             */
+            dptr[2] = dptr[1];
+            dptr[1] = dptr[0];
+            rxpdu->om_data += 1;
+        }
+#endif
         rc = ble_ll_rx_end(rxpdu, ble_hdr);
         if (rc < 0) {
             /* Disable the PHY. */
@@ -390,6 +510,7 @@ ble_phy_init(void)
     NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit;
     NRF_RADIO->PCNF0 = (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) |
                        (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
+    /* XXX: should maxlen be 251 for encryption? */
     NRF_RADIO->PCNF1 = NRF_MAXLEN |
                        (RADIO_PCNF1_ENDIAN_Little <<  RADIO_PCNF1_ENDIAN_Pos) |
                        (NRF_BALEN << RADIO_PCNF1_BALEN_Pos) |
@@ -414,6 +535,14 @@ ble_phy_init(void)
      */
     NRF_PPI->CHENSET = PPI_CHEN_CH27_Msk;
 
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    NRF_CCM->INTENCLR = 0xffffffff;
+    NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
+    NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
+    NRF_CCM->EVENTS_ERROR = 0;
+    memset(g_nrf_encrypt_scratchpad, 0, sizeof(g_nrf_encrypt_scratchpad));
+#endif
+
     /* Set isr in vector table and enable interrupt */
     NVIC_SetPriority(RADIO_IRQn, 0);
     NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr);
@@ -451,7 +580,15 @@ ble_phy_rx(void)
     }
 
     /* Set packet pointer */
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    if (g_ble_phy_data.phy_encrypted) {
+        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+    } else {
+        NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+    }
+#else
     NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+#endif
 
     /* Make sure all interrupts are disabled */
     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
@@ -464,6 +601,24 @@ ble_phy_rx(void)
     NRF_RADIO->EVENTS_RSSIEND = 0;
     NRF_RADIO->EVENTS_DEVMATCH = 0;
 
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    if (g_ble_phy_data.phy_encrypted) {
+        NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+        NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+        NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
+        NRF_CCM->EVENTS_ERROR = 0;
+        NRF_CCM->EVENTS_ENDCRYPT = 0;
+        NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
+        /* XXX: can I just set this once? (i.e per connection)? In other
+           words, only do this during encrypt enable? */
+        NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
+        NRF_CCM->SHORTS = 0;
+        NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
+    }
+#endif
+
+    /* XXX: could it be that I am late turning on the device? That I need
+       to automatically go from rx to tx always? I dont here */
     /* I want to know when 1st byte received (after address) */
     NRF_RADIO->BCC = 8; /* in bits */
     NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
@@ -485,6 +640,55 @@ ble_phy_rx(void)
     return 0;
 }
 
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+/**
+ * Called to enable encryption at the PHY. Note that this state will persist
+ * in the PHY; in other words, if you call this function you have to call
+ * disable so that future PHY transmits/receives will not be encrypted.
+ *
+ * @param pkt_counter
+ * @param iv
+ * @param key
+ * @param is_master
+ */
+void
+ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key,
+                       uint8_t is_master)
+{
+    memcpy(g_nrf_ccm_data.key, key, 16);
+    g_nrf_ccm_data.pkt_counter = pkt_counter;
+    memcpy(g_nrf_ccm_data.iv, iv, 8);
+    g_nrf_ccm_data.dir_bit = is_master;
+    g_ble_phy_data.phy_encrypted = 1;
+
+    /* Encryption uses LFLEN=5, S1LEN = 3. */
+    NRF_RADIO->PCNF0 = (5 << RADIO_PCNF0_LFLEN_Pos) |
+                       (3 << RADIO_PCNF0_S1LEN_Pos) |
+                       (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
+}
+
+void
+ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir)
+{
+    g_nrf_ccm_data.pkt_counter = pkt_counter;
+    g_nrf_ccm_data.dir_bit = dir;
+}
+
+void
+ble_phy_encrypt_disable(void)
+{
+    NRF_PPI->CHENCLR = (PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk);
+    NRF_CCM->TASKS_STOP = 1;
+    NRF_CCM->EVENTS_ERROR = 0;
+
+    /* Switch back to normal length */
+    NRF_RADIO->PCNF0 = (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) |
+                       (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
+
+    g_ble_phy_data.phy_encrypted = 0;
+}
+#endif
+
 void
 ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg)
 {
@@ -525,15 +729,46 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
         return BLE_PHY_ERR_RADIO_STATE;
     }
 
-    /* Write LL header first */
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    if (g_ble_phy_data.phy_encrypted) {
+        /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
+        ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
+        dptr = (uint8_t *)&g_ble_phy_enc_buf[0];
+        dptr[0] = ble_hdr->txinfo.hdr_byte;
+        dptr[1] = ble_hdr->txinfo.pyld_len;
+        dptr[2] = 0;
+        dptr += 3;
+
+        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
+        NRF_CCM->SHORTS = 1;
+        NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+        NRF_CCM->OUTPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
+        NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
+        NRF_CCM->EVENTS_ERROR = 0;
+        NRF_CCM->MODE = CCM_MODE_MODE_Encryption;
+        NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
+        NRF_PPI->CHENCLR = PPI_CHEN_CH25_Msk;
+        NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk;
+    } else {
+        /* RAM representation has S0 and LENGTH fields (2 bytes) */
+        ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
+        dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
+        dptr[0] = ble_hdr->txinfo.hdr_byte;
+        dptr[1] = ble_hdr->txinfo.pyld_len;
+        dptr += 2;
+
+        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
+    }
+#else
+    /* RAM representation has S0 and LENGTH fields (2 bytes) */
     ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
     dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
     dptr[0] = ble_hdr->txinfo.hdr_byte;
     dptr[1] = ble_hdr->txinfo.pyld_len;
     dptr += 2;
 
-    /* Set radio transmit data pointer */
     NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
+#endif
 
     /* Clear the ready, end and disabled events */
     NRF_RADIO->EVENTS_READY = 0;
@@ -638,8 +873,8 @@ ble_phy_txpwr_get(void)
  * ble phy setchan
  *
  * Sets the logical frequency of the transceiver. The input parameter is the
- * BLE channel index (0 to 39, inclusive). The NRF51 frequency register works
- * like this: logical frequency = 2400 + FREQ (MHz).
+ * BLE channel index (0 to 39, inclusive). The NRF frequency register works like
+ * this: logical frequency = 2400 + FREQ (MHz).
  *
  * Thus, to get a logical frequency of 2402 MHz, you would program the
  * FREQUENCY register to 2.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a590265d/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 2c55d48..fee6043 100644
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@ -23,6 +23,7 @@
 #include "os/os.h"
 #include "bsp/cmsis_nvic.h"
 #include "nimble/ble.h"
+#include "nimble/nimble_opt.h"
 #include "controller/ble_phy.h"
 #include "controller/ble_ll.h"
 #include "mcu/nrf52_bitfields.h"
@@ -38,7 +39,7 @@
 #define NRF_RADIO_IRQ_MASK_ALL  (0x34FF)
 
 /*
- * We configure the nrf52 with a 1 byte S0 field, 8 bit length field, and
+ * We configure the nrf with a 1 byte S0 field, 8 bit length field, and
  * zero bit S1 field. The preamble is 8 bits long.
  */
 #define NRF_LFLEN_BITS          (8)
@@ -69,8 +70,10 @@ struct ble_phy_obj
 };
 struct ble_phy_obj g_ble_phy_data;
 
+/* XXX: if 27 byte packets desired we can make this smaller */
 /* Global transmit/receive buffer */
 static uint32_t g_ble_phy_txrx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
 static uint32_t g_ble_phy_enc_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
 #endif
@@ -113,8 +116,8 @@ STATS_NAME_END(ble_phy_stats)
  * 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.
+ *  -> Set up nrf to receive. Clear ADDRESS event register.
+ *  -> Enable ADDRESS interrupt on nrf5 by writing to INTENSET.
  *  -> Enable RX.
  *  -> Disable interrupts globally using OS_ENTER_CRITICAL().
  *  -> Wait until a packet is received and the ADDRESS event occurs.
@@ -139,9 +142,19 @@ STATS_NAME_END(ble_phy_stats)
  */
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-/* NRF requires 43 bytes of scratch for encryption */
-/* XXX: align this? */
-uint32_t g_nrf_encrypt_scratchpad[100];
+
+/*
+ * Per nordic, the number of bytes needed for scratch is 16 + MAX_PKT_SIZE.
+ * However, when I used a smaller size it still overwrote the scratchpad. Until
+ * I figure this out I am just going to allocate 67 words so we have enough
+ * space for 267 bytes of scratch. I used 268 bytes since not sure if this
+ * needs to be aligned and burning a byte is no big deal.
+ */
+//#define NRF_ENC_SCRATCH_WORDS (((NIMBLE_OPT_LL_MAX_PKT_SIZE + 16) + 3) / 4)
+#define NRF_ENC_SCRATCH_WORDS   (67)
+
+uint32_t g_nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS];
+
 struct nrf_ccm_data
 {
     uint8_t key[16];
@@ -184,7 +197,7 @@ ble_phy_rxpdu_get(void)
 }
 
 static void
-nrf52_wait_disabled(void)
+nrf_wait_disabled(void)
 {
     uint32_t state;
 
@@ -544,7 +557,7 @@ int
 ble_phy_rx(void)
 {
     /* Check radio state */
-    nrf52_wait_disabled();
+    nrf_wait_disabled();
     if (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {
         ble_phy_disable();
         STATS_INC(ble_phy_stats, radio_state_errs);
@@ -594,6 +607,8 @@ ble_phy_rx(void)
     }
 #endif
 
+    /* XXX: could it be that I am late turning on the device? That I need
+       to automatically go from rx to tx always? I dont here */
     /* I want to know when 1st byte received (after address) */
     NRF_RADIO->BCC = 8; /* in bits */
     NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
@@ -637,7 +652,6 @@ ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key,
     g_ble_phy_data.phy_encrypted = 1;
 }
 
-
 void
 ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir)
 {
@@ -676,7 +690,7 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
     assert(txpdu != NULL);
 
     /* If radio is not disabled, */
-    nrf52_wait_disabled();
+    nrf_wait_disabled();
 
     if (beg_trans == BLE_PHY_TRANSITION_RX_TX) {
         if ((NRF_RADIO->SHORTS & RADIO_SHORTS_DISABLED_TXEN_Msk) == 0) {
@@ -841,8 +855,8 @@ ble_phy_txpwr_get(void)
  * ble phy setchan
  *
  * Sets the logical frequency of the transceiver. The input parameter is the
- * BLE channel index (0 to 39, inclusive). The NRF52 frequency register
- * works like this: logical frequency = 2400 + FREQ (MHz).
+ * BLE channel index (0 to 39, inclusive). The NRF frequency register works like
+ * this: logical frequency = 2400 + FREQ (MHz).
  *
  * Thus, to get a logical frequency of 2402 MHz, you would program the
  * FREQUENCY register to 2.
@@ -864,7 +878,7 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit)
         return BLE_PHY_ERR_INV_PARAM;
     }
 
-    /* Get correct nrf52 frequency */
+    /* Get correct frequency */
     if (chan < BLE_PHY_NUM_DATA_CHANS) {
         if (chan < 11) {
             /* Data channel 0 starts at 2404. 0 - 10 are contiguous */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a590265d/net/nimble/include/nimble/nimble_opt.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/nimble_opt.h b/net/nimble/include/nimble/nimble_opt.h
index 3e94943..d008d54 100644
--- a/net/nimble/include/nimble/nimble_opt.h
+++ b/net/nimble/include/nimble/nimble_opt.h
@@ -6,7 +6,7 @@
  * 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,
@@ -44,7 +44,7 @@
 #define NIMBLE_OPT_ROLE_BROADCASTER             1
 #endif
 
-#ifndef NIMBLE_OPT_ROLE_OBSERVER   
+#ifndef NIMBLE_OPT_ROLE_OBSERVER
 #define NIMBLE_OPT_ROLE_OBSERVER                1
 #endif
 
@@ -85,23 +85,23 @@
 #define NIMBLE_OPT_GATT_DISC_ALL_DSCS           1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_READ         
+#ifndef NIMBLE_OPT_GATT_READ
 #define NIMBLE_OPT_GATT_READ                    1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_READ_UUID    
+#ifndef NIMBLE_OPT_GATT_READ_UUID
 #define NIMBLE_OPT_GATT_READ_UUID               1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_READ_LONG    
+#ifndef NIMBLE_OPT_GATT_READ_LONG
 #define NIMBLE_OPT_GATT_READ_LONG               1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_READ_MULT    
+#ifndef NIMBLE_OPT_GATT_READ_MULT
 #define NIMBLE_OPT_GATT_READ_MULT               1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_WRITE_NO_RSP 
+#ifndef NIMBLE_OPT_GATT_WRITE_NO_RSP
 #define NIMBLE_OPT_GATT_WRITE_NO_RSP            1
 #endif
 
@@ -109,23 +109,23 @@
 #define NIMBLE_OPT_GATT_SIGNED_WRITE            1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_WRITE              
+#ifndef NIMBLE_OPT_GATT_WRITE
 #define NIMBLE_OPT_GATT_WRITE                   1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_WRITE_LONG         
+#ifndef NIMBLE_OPT_GATT_WRITE_LONG
 #define NIMBLE_OPT_GATT_WRITE_LONG              1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_WRITE_RELIABLE     
+#ifndef NIMBLE_OPT_GATT_WRITE_RELIABLE
 #define NIMBLE_OPT_GATT_WRITE_RELIABLE          1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_NOTIFY             
+#ifndef NIMBLE_OPT_GATT_NOTIFY
 #define NIMBLE_OPT_GATT_NOTIFY                  1
 #endif
 
-#ifndef NIMBLE_OPT_GATT_INDICATE           
+#ifndef NIMBLE_OPT_GATT_INDICATE
 #define NIMBLE_OPT_GATT_INDICATE                1
 #endif
 
@@ -180,7 +180,7 @@
 #define NIMBLE_OPT_ATT_SVR_EXEC_WRITE           1
 #endif
 
-#ifndef NIMBLE_OPT_ATT_SVR_NOTIFY  
+#ifndef NIMBLE_OPT_ATT_SVR_NOTIFY
 #define NIMBLE_OPT_ATT_SVR_NOTIFY               1
 #endif
 
@@ -190,14 +190,14 @@
 
 /*** CONTROLLER ***/
 
-/* 
- * Sleep clock accuracy (sca). This is the amount of drift in the system during 
+/*
+ * Sleep clock accuracy (sca). This is the amount of drift in the system during
  * when the device is sleeping (in parts per million).
  *
  * NOTE: the master sca is an enumerated value based on the sca. Rather than
  * have a piece of code calculate this value, the developer must set this
  * value based on the value of the SCA using the following table:
- * 
+ *
  *  SCA between 251 and 500 ppm (inclusive); master sca = 0
  *  SCA between 151 and 250 ppm (inclusive); master sca = 1
  *  SCA between 101 and 150 ppm (inclusive); master sca = 2
@@ -206,11 +206,11 @@
  *  SCA between 31 and 50 ppm (inclusive); master sca = 5
  *  SCA between 21 and 30 ppm (inclusive); master sca = 6
  *  SCA between 0 and 20 ppm (inclusive); master sca = 7
- * 
+ *
  *  For example:
  *      if your clock drift is 101 ppm, your master should be set to 2.
  *      if your clock drift is 20, your master sca should be set to 7.
- * 
+ *
  *  The values provided below are merely meant to be an example and should
  *  be replaced by values appropriate for your platform.
  */
@@ -227,7 +227,7 @@
 #define NIMBLE_OPT_LL_TX_PWR_DBM                (0)
 #endif
 
-/* 
+/*
  * Determines the maximum rate at which the controller will send the
  * number of completed packets event to the host. Rate is in os time ticks
  */
@@ -240,7 +240,7 @@
 #define NIMBLE_OPT_LL_MFRG_ID                   (0xFFFF)
 #endif
 
-/* 
+/*
  * Configuration items for the number of duplicate advertisers and the
  * number of advertisers from which we have heard a scan response.
  */
@@ -257,16 +257,20 @@
 #define NIMBLE_OPT_LL_WHITELIST_SIZE            (8)
 #endif
 
-/* 
+/*
  * Data length management definitions for connections. These define the maximum
- * size of the PDU's that will be sent and/or received in a connection. 
+ * size of the PDU's that will be sent and/or received in a connection.
  */
+#ifndef NIMBLE_OPT_LL_MAX_PKT_SIZE
+#define NIMBLE_OPT_LL_MAX_PKT_SIZE              (251)
+#endif
+
 #ifndef NIMBLE_OPT_LL_SUPP_MAX_RX_BYTES
-#define NIMBLE_OPT_LL_SUPP_MAX_RX_BYTES         (251)
+#define NIMBLE_OPT_LL_SUPP_MAX_RX_BYTES         (NIMBLE_OPT_LL_MAX_PKT_SIZE)
 #endif
 
 #ifndef NIMBLE_OPT_LL_SUPP_MAX_TX_BYTES
-#define NIMBLE_OPT_LL_SUPP_MAX_TX_BYTES         (251)
+#define NIMBLE_OPT_LL_SUPP_MAX_TX_BYTES         (NIMBLE_OPT_LL_MAX_PKT_SIZE)
 #endif
 
 #ifndef NIMBLE_OPT_LL_CONN_INIT_MAX_TX_BYTES


[11/50] [abbrv] incubator-mynewt-core git commit: ble host - major changes.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_gattc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gattc.c b/net/nimble/host/src/ble_gattc.c
index ffd57c8..64502f3 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -31,7 +31,7 @@
  * $definitions / declarations                                               *
  *****************************************************************************/
 
-#define BLE_GATT_UNRESPONSIVE_TIMEOUT           30000   /* Milliseconds. */
+#define BLE_GATT_UNRESPONSIVE_TIMEOUT           (30 * OS_TICKS_PER_SEC)
 
 #define BLE_GATT_OP_NONE                        UINT8_MAX
 #define BLE_GATT_OP_MTU                         0
@@ -39,23 +39,25 @@
 #define BLE_GATT_OP_DISC_SVC_UUID               2
 #define BLE_GATT_OP_FIND_INC_SVCS               3
 #define BLE_GATT_OP_DISC_ALL_CHRS               4
-#define BLE_GATT_OP_DISC_CHR_UUID              5
+#define BLE_GATT_OP_DISC_CHR_UUID               5
 #define BLE_GATT_OP_DISC_ALL_DSCS               6
 #define BLE_GATT_OP_READ                        7
 #define BLE_GATT_OP_READ_UUID                   8
 #define BLE_GATT_OP_READ_LONG                   9
 #define BLE_GATT_OP_READ_MULT                   10
-#define BLE_GATT_OP_WRITE_NO_RSP                11
-#define BLE_GATT_OP_WRITE                       12
-#define BLE_GATT_OP_WRITE_LONG                  13
-#define BLE_GATT_OP_WRITE_RELIABLE              14
-#define BLE_GATT_OP_NOTIFY                      15
-#define BLE_GATT_OP_INDICATE                    16
-#define BLE_GATT_OP_MAX                         17
+#define BLE_GATT_OP_WRITE                       11
+#define BLE_GATT_OP_WRITE_LONG                  12
+#define BLE_GATT_OP_WRITE_RELIABLE              13
+#define BLE_GATT_OP_INDICATE                    14
+#define BLE_GATT_OP_MAX                         15
 
 /** Represents an in-progress GATT procedure. */
 struct ble_gattc_proc {
-    struct ble_fsm_proc fsm_proc;
+    STAILQ_ENTRY(ble_gattc_proc) next;
+
+    uint32_t exp_os_ticks;
+    uint16_t conn_handle;
+    uint8_t op;
 
     union {
         struct {
@@ -117,9 +119,6 @@ struct ble_gattc_proc {
         } read;
 
         struct {
-            uint16_t prev_handle;
-            uint16_t end_handle;
-            uint8_t uuid128[16];
             ble_gatt_attr_fn *cb;
             void *cb_arg;
         } read_uuid;
@@ -132,14 +131,12 @@ struct ble_gattc_proc {
         } read_long;
 
         struct {
-            uint16_t *handles;
-            uint8_t num_handles;
-            ble_gatt_mult_attr_fn *cb;
+            ble_gatt_attr_fn *cb;
             void *cb_arg;
         } read_mult;
 
         struct {
-            struct ble_gatt_attr attr;
+            uint16_t att_handle;
             ble_gatt_attr_fn *cb;
             void *cb_arg;
         } write;
@@ -160,284 +157,139 @@ struct ble_gattc_proc {
         } write_reliable;
 
         struct {
-            struct ble_gatt_attr attr;
-            ble_gatt_attr_fn *cb;
-            void *cb_arg;
-        } notify;
-
-        struct {
-            struct ble_gatt_attr attr;
             ble_gatt_attr_fn *cb;
+            uint16_t chr_val_handle;
             void *cb_arg;
         } indicate;
     };
 };
 
-/**
- * Kick functions - these trigger the pending ATT transmit for an active GATT
- * procedure.
- */
-typedef int ble_gattc_kick_fn(struct ble_gattc_proc *proc);
-typedef void ble_gattc_err_fn(struct ble_gattc_proc *proc, int status,
-                              uint16_t att_handle);
-
-static int ble_gattc_mtu_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_disc_all_svcs_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_disc_svc_uuid_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_find_inc_svcs_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_disc_all_chrs_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_disc_chr_uuid_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_disc_all_dscs_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_read_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_read_uuid_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_read_long_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_read_mult_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_write_no_rsp_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_write_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_write_long_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_write_reliable_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_notify_kick(struct ble_gattc_proc *proc);
-static int ble_gattc_indicate_kick(struct ble_gattc_proc *proc);
+STAILQ_HEAD(ble_gattc_proc_list, ble_gattc_proc);
 
 /**
  * Error functions - these handle an incoming ATT error response and apply it
  * to the appropriate active GATT procedure.
  */
-static void ble_gattc_mtu_err(struct ble_gattc_proc *proc, int status,
+typedef void ble_gattc_err_fn(struct ble_gattc_proc *proc, int status,
                               uint16_t att_handle);
-static void ble_gattc_disc_all_svcs_err(struct ble_gattc_proc *proc,
-                                        int status, uint16_t att_handle);
-static void ble_gattc_disc_svc_uuid_err(struct ble_gattc_proc *proc,
-                                        int status, uint16_t att_handle);
-static void ble_gattc_find_inc_svcs_err(struct ble_gattc_proc *proc,
-                                        int status, uint16_t att_handle);
-static void ble_gattc_disc_all_chrs_err(struct ble_gattc_proc *proc,
-                                        int status, uint16_t att_handle);
-static void ble_gattc_disc_chr_uuid_err(struct ble_gattc_proc *proc,
-                                        int status, uint16_t att_handle);
-static void ble_gattc_disc_all_dscs_err(struct ble_gattc_proc *proc,
-                                        int status, uint16_t att_handle);
-static void ble_gattc_read_err(struct ble_gattc_proc *proc, int status,
-                               uint16_t att_handle);
-static void ble_gattc_read_uuid_err(struct ble_gattc_proc *proc, int status,
-                                    uint16_t att_handle);
-static void ble_gattc_read_long_err(struct ble_gattc_proc *proc, int status,
-                                    uint16_t att_handle);
-static void ble_gattc_read_mult_err(struct ble_gattc_proc *proc, int status,
-                                    uint16_t att_handle);
-static void ble_gattc_write_err(struct ble_gattc_proc *proc, int status,
-                                uint16_t att_handle);
-static void ble_gattc_write_long_err(struct ble_gattc_proc *proc, int status,
-                                     uint16_t att_handle);
-static void ble_gattc_write_reliable_err(struct ble_gattc_proc *proc,
-                                         int status, uint16_t att_handle);
-static void ble_gattc_indicate_err(struct ble_gattc_proc *proc, int status,
-                                   uint16_t att_handle);
+static ble_gattc_err_fn ble_gattc_mtu_err;
+static ble_gattc_err_fn ble_gattc_disc_all_svcs_err;
+static ble_gattc_err_fn ble_gattc_disc_svc_uuid_err;
+static ble_gattc_err_fn ble_gattc_find_inc_svcs_err;
+static ble_gattc_err_fn ble_gattc_disc_all_chrs_err;
+static ble_gattc_err_fn ble_gattc_disc_chr_uuid_err;
+static ble_gattc_err_fn ble_gattc_disc_all_dscs_err;
+static ble_gattc_err_fn ble_gattc_read_err;
+static ble_gattc_err_fn ble_gattc_read_uuid_err;
+static ble_gattc_err_fn ble_gattc_read_long_err;
+static ble_gattc_err_fn ble_gattc_read_mult_err;
+static ble_gattc_err_fn ble_gattc_write_err;
+static ble_gattc_err_fn ble_gattc_write_long_err;
+static ble_gattc_err_fn ble_gattc_write_reliable_err;
+static ble_gattc_err_fn ble_gattc_indicate_err;
+
+static ble_gattc_err_fn * const ble_gattc_err_dispatch[BLE_GATT_OP_MAX] = {
+    [BLE_GATT_OP_MTU]               = ble_gattc_mtu_err,
+    [BLE_GATT_OP_DISC_ALL_SVCS]     = ble_gattc_disc_all_svcs_err,
+    [BLE_GATT_OP_DISC_SVC_UUID]     = ble_gattc_disc_svc_uuid_err,
+    [BLE_GATT_OP_FIND_INC_SVCS]     = ble_gattc_find_inc_svcs_err,
+    [BLE_GATT_OP_DISC_ALL_CHRS]     = ble_gattc_disc_all_chrs_err,
+    [BLE_GATT_OP_DISC_CHR_UUID]     = ble_gattc_disc_chr_uuid_err,
+    [BLE_GATT_OP_DISC_ALL_DSCS]     = ble_gattc_disc_all_dscs_err,
+    [BLE_GATT_OP_READ]              = ble_gattc_read_err,
+    [BLE_GATT_OP_READ_UUID]         = ble_gattc_read_uuid_err,
+    [BLE_GATT_OP_READ_LONG]         = ble_gattc_read_long_err,
+    [BLE_GATT_OP_READ_MULT]         = ble_gattc_read_mult_err,
+    [BLE_GATT_OP_WRITE]             = ble_gattc_write_err,
+    [BLE_GATT_OP_WRITE_LONG]        = ble_gattc_write_long_err,
+    [BLE_GATT_OP_WRITE_RELIABLE]    = ble_gattc_write_reliable_err,
+    [BLE_GATT_OP_INDICATE]          = ble_gattc_indicate_err,
+};
 
 /**
  * Receive functions - these handle specific incoming responses and apply them
  * to the appropriate active GATT procedure.
  */
-static int
-ble_gattc_find_inc_svcs_rx_adata(struct ble_gattc_proc *proc,
-                                 struct ble_att_read_type_adata *adata);
-static int
-ble_gattc_find_inc_svcs_rx_complete(struct ble_gattc_proc *proc,
-                                    int status);
-static int
-ble_gattc_find_inc_svcs_rx_read_rsp(struct ble_gattc_proc *proc,
-                                    int status, void *value, int value_len);
-static int
-ble_gattc_disc_all_chrs_rx_adata(struct ble_gattc_proc *proc,
-                                 struct ble_att_read_type_adata *adata);
-static int
-ble_gattc_disc_all_chrs_rx_complete(struct ble_gattc_proc *proc,
-                                    int status);
-static int
-ble_gattc_disc_chr_uuid_rx_adata(struct ble_gattc_proc *proc,
-                                 struct ble_att_read_type_adata *adata);
-static int
-ble_gattc_disc_chr_uuid_rx_complete(struct ble_gattc_proc *proc,
-                                    int status);
-static int
-ble_gattc_read_rx_read_rsp(struct ble_gattc_proc *proc, int status,
-                           void *value, int value_len);
-static int
-ble_gattc_read_long_rx_read_rsp(struct ble_gattc_proc *proc, int status,
-                                void *value, int value_len);
-static int
-ble_gattc_read_uuid_rx_adata(struct ble_gattc_proc *proc,
-                             struct ble_att_read_type_adata *adata);
-static int
-ble_gattc_read_uuid_rx_complete(struct ble_gattc_proc *proc, int status);
-static int
-ble_gattc_write_long_rx_prep(struct ble_gattc_proc *proc,
-                             int status, struct ble_att_prep_write_cmd *rsp,
-                             void *attr_data, uint16_t attr_len);
-static int
-ble_gattc_write_long_rx_exec(struct ble_gattc_proc *proc, int status);
-
-static int
-ble_gattc_write_reliable_rx_prep(struct ble_gattc_proc *proc, int status,
-                                 struct ble_att_prep_write_cmd *rsp,
-                                 void *attr_data, uint16_t attr_len);
-static int
-ble_gattc_write_reliable_rx_exec(struct ble_gattc_proc *proc, int status);
-
-
 typedef int ble_gattc_rx_adata_fn(struct ble_gattc_proc *proc,
                                   struct ble_att_read_type_adata *adata);
-struct ble_gattc_rx_adata_entry {
-    uint8_t op;
-    ble_gattc_rx_adata_fn *cb;
-};
-
-typedef int ble_gattc_rx_complete_fn(struct ble_gattc_proc *proc, int status);
-struct ble_gattc_rx_complete_entry {
-    uint8_t op;
-    ble_gattc_rx_complete_fn *cb;
-};
-
-typedef int ble_gattc_rx_attr_fn(struct ble_gattc_proc *proc, int status,
-                                 void *value, int value_len);
-struct ble_gattc_rx_attr_entry {
-    uint8_t op;
-    ble_gattc_rx_attr_fn *cb;
-};
 
 typedef int ble_gattc_rx_prep_fn(struct ble_gattc_proc *proc, int status,
                                  struct ble_att_prep_write_cmd *rsp,
                                  void *attr_data, uint16_t attr_len);
 
-struct ble_gattc_rx_prep_entry {
-    uint8_t op;
-    ble_gattc_rx_prep_fn *cb;
-};
+typedef int ble_gattc_rx_attr_fn(struct ble_gattc_proc *proc, int status,
+                                 void *value, int value_len);
 
+typedef int ble_gattc_rx_complete_fn(struct ble_gattc_proc *proc, int status);
 typedef int ble_gattc_rx_exec_fn(struct ble_gattc_proc *proc, int status);
 
-struct ble_gattc_rx_exec_entry {
+static ble_gattc_rx_adata_fn ble_gattc_find_inc_svcs_rx_adata;
+static ble_gattc_rx_complete_fn ble_gattc_find_inc_svcs_rx_complete;
+static ble_gattc_rx_attr_fn ble_gattc_find_inc_svcs_rx_read_rsp;
+static ble_gattc_rx_adata_fn ble_gattc_disc_all_chrs_rx_adata;
+static ble_gattc_rx_complete_fn ble_gattc_disc_all_chrs_rx_complete;
+static ble_gattc_rx_adata_fn ble_gattc_disc_chr_uuid_rx_adata;
+static ble_gattc_rx_complete_fn ble_gattc_disc_chr_uuid_rx_complete;
+static ble_gattc_rx_attr_fn ble_gattc_read_rx_read_rsp;
+static ble_gattc_rx_attr_fn ble_gattc_read_long_rx_read_rsp;
+static ble_gattc_rx_adata_fn ble_gattc_read_uuid_rx_adata;
+static ble_gattc_rx_complete_fn ble_gattc_read_uuid_rx_complete;
+static ble_gattc_rx_prep_fn ble_gattc_write_long_rx_prep;
+static ble_gattc_rx_exec_fn ble_gattc_write_long_rx_exec;
+static ble_gattc_rx_prep_fn ble_gattc_write_reliable_rx_prep;
+static ble_gattc_rx_exec_fn ble_gattc_write_reliable_rx_exec;
+
+static const struct ble_gattc_rx_adata_entry {
     uint8_t op;
-    ble_gattc_rx_exec_fn *cb;
-};
-
-static const struct ble_gattc_rx_adata_entry
-    ble_gattc_rx_read_type_elem_entries[] = {
-
+    ble_gattc_rx_adata_fn *cb;
+} ble_gattc_rx_read_type_elem_entries[] = {
     { BLE_GATT_OP_FIND_INC_SVCS,    ble_gattc_find_inc_svcs_rx_adata },
     { BLE_GATT_OP_DISC_ALL_CHRS,    ble_gattc_disc_all_chrs_rx_adata },
-    { BLE_GATT_OP_DISC_CHR_UUID,   ble_gattc_disc_chr_uuid_rx_adata },
+    { BLE_GATT_OP_DISC_CHR_UUID,    ble_gattc_disc_chr_uuid_rx_adata },
     { BLE_GATT_OP_READ_UUID,        ble_gattc_read_uuid_rx_adata },
 };
 
-static const struct ble_gattc_rx_complete_entry
-    ble_gattc_rx_read_type_complete_entries[] = {
-
+static const struct ble_gattc_rx_complete_entry {
+    uint8_t op;
+    ble_gattc_rx_complete_fn *cb;
+} ble_gattc_rx_read_type_complete_entries[] = {
     { BLE_GATT_OP_FIND_INC_SVCS,    ble_gattc_find_inc_svcs_rx_complete },
     { BLE_GATT_OP_DISC_ALL_CHRS,    ble_gattc_disc_all_chrs_rx_complete },
-    { BLE_GATT_OP_DISC_CHR_UUID,   ble_gattc_disc_chr_uuid_rx_complete },
+    { BLE_GATT_OP_DISC_CHR_UUID,    ble_gattc_disc_chr_uuid_rx_complete },
     { BLE_GATT_OP_READ_UUID,        ble_gattc_read_uuid_rx_complete },
 };
 
-static const struct ble_gattc_rx_attr_entry ble_gattc_rx_read_rsp_entries[] = {
+static const struct ble_gattc_rx_attr_entry {
+    uint8_t op;
+    ble_gattc_rx_attr_fn *cb;
+} ble_gattc_rx_read_rsp_entries[] = {
     { BLE_GATT_OP_READ,             ble_gattc_read_rx_read_rsp },
     { BLE_GATT_OP_READ_LONG,        ble_gattc_read_long_rx_read_rsp },
     { BLE_GATT_OP_FIND_INC_SVCS,    ble_gattc_find_inc_svcs_rx_read_rsp },
 };
 
-static const struct ble_gattc_rx_prep_entry ble_gattc_rx_prep_entries[] = {
+static const struct ble_gattc_rx_prep_entry {
+    uint8_t op;
+    ble_gattc_rx_prep_fn *cb;
+} ble_gattc_rx_prep_entries[] = {
     { BLE_GATT_OP_WRITE_LONG,       ble_gattc_write_long_rx_prep },
     { BLE_GATT_OP_WRITE_RELIABLE,   ble_gattc_write_reliable_rx_prep },
 };
 
-static const struct ble_gattc_rx_exec_entry ble_gattc_rx_exec_entries[] = {
+static const struct ble_gattc_rx_exec_entry {
+    uint8_t op;
+    ble_gattc_rx_exec_fn *cb;
+} ble_gattc_rx_exec_entries[] = {
     { BLE_GATT_OP_WRITE_LONG,       ble_gattc_write_long_rx_exec },
     { BLE_GATT_OP_WRITE_RELIABLE,   ble_gattc_write_reliable_rx_exec },
 };
 
-/**
- * Dispatch entries - this array maps GATT procedure types to their
- * corresponding kick and error functions.
- */
-static const struct ble_gattc_dispatch_entry {
-    ble_gattc_kick_fn *kick_cb;
-    ble_gattc_err_fn *err_cb;
-} ble_gattc_dispatch[BLE_GATT_OP_MAX] = {
-    [BLE_GATT_OP_MTU] = {
-        .kick_cb = ble_gattc_mtu_kick,
-        .err_cb = ble_gattc_mtu_err,
-    },
-    [BLE_GATT_OP_DISC_ALL_SVCS] = {
-        .kick_cb = ble_gattc_disc_all_svcs_kick,
-        .err_cb = ble_gattc_disc_all_svcs_err,
-    },
-    [BLE_GATT_OP_DISC_SVC_UUID] = {
-        .kick_cb = ble_gattc_disc_svc_uuid_kick,
-        .err_cb = ble_gattc_disc_svc_uuid_err,
-    },
-    [BLE_GATT_OP_FIND_INC_SVCS] = {
-        .kick_cb = ble_gattc_find_inc_svcs_kick,
-        .err_cb = ble_gattc_find_inc_svcs_err,
-    },
-    [BLE_GATT_OP_DISC_ALL_CHRS] = {
-        .kick_cb = ble_gattc_disc_all_chrs_kick,
-        .err_cb = ble_gattc_disc_all_chrs_err,
-    },
-    [BLE_GATT_OP_DISC_CHR_UUID] = {
-        .kick_cb = ble_gattc_disc_chr_uuid_kick,
-        .err_cb = ble_gattc_disc_chr_uuid_err,
-    },
-    [BLE_GATT_OP_DISC_ALL_DSCS] = {
-        .kick_cb = ble_gattc_disc_all_dscs_kick,
-        .err_cb = ble_gattc_disc_all_dscs_err,
-    },
-    [BLE_GATT_OP_READ] = {
-        .kick_cb = ble_gattc_read_kick,
-        .err_cb = ble_gattc_read_err,
-    },
-    [BLE_GATT_OP_READ_UUID] = {
-        .kick_cb = ble_gattc_read_uuid_kick,
-        .err_cb = ble_gattc_read_uuid_err,
-    },
-    [BLE_GATT_OP_READ_LONG] = {
-        .kick_cb = ble_gattc_read_long_kick,
-        .err_cb = ble_gattc_read_long_err,
-    },
-    [BLE_GATT_OP_READ_MULT] = {
-        .kick_cb = ble_gattc_read_mult_kick,
-        .err_cb = ble_gattc_read_mult_err,
-    },
-    [BLE_GATT_OP_WRITE_NO_RSP] = {
-        .kick_cb = ble_gattc_write_no_rsp_kick,
-        .err_cb = NULL,
-    },
-    [BLE_GATT_OP_WRITE] = {
-        .kick_cb = ble_gattc_write_kick,
-        .err_cb = ble_gattc_write_err,
-    },
-    [BLE_GATT_OP_WRITE_LONG] = {
-        .kick_cb = ble_gattc_write_long_kick,
-        .err_cb = ble_gattc_write_long_err,
-    },
-    [BLE_GATT_OP_WRITE_RELIABLE] = {
-        .kick_cb = ble_gattc_write_reliable_kick,
-        .err_cb = ble_gattc_write_reliable_err,
-    },
-    [BLE_GATT_OP_NOTIFY] = {
-        .kick_cb = ble_gattc_notify_kick,
-        .err_cb = NULL,
-    },
-    [BLE_GATT_OP_INDICATE] = {
-        .kick_cb = ble_gattc_indicate_kick,
-        .err_cb = ble_gattc_indicate_err,
-    },
-};
-
+/* Maintains the list of active GATT client procedures. */
 static void *ble_gattc_proc_mem;
 static struct os_mempool ble_gattc_proc_pool;
+static struct ble_gattc_proc_list ble_gattc_procs;
 
-static struct ble_fsm ble_gattc_fsm;
-
+/* Statistics. */
 STATS_SECT_DECL(ble_gattc_stats) ble_gattc_stats;
 STATS_NAME_START(ble_gattc_stats)
     STATS_NAME(ble_gattc_stats, mtu)
@@ -477,31 +329,15 @@ STATS_NAME_START(ble_gattc_stats)
 STATS_NAME_END(ble_gattc_stats)
 
 /*****************************************************************************
- * $mutex                                                                    *
+ * $log                                                                      *
  *****************************************************************************/
 
 static void
-ble_gattc_lock(void)
-{
-    ble_fsm_lock(&ble_gattc_fsm);
-}
-
-static void
-ble_gattc_unlock(void)
-{
-    ble_fsm_unlock(&ble_gattc_fsm);
-}
-
-int
-ble_gattc_locked_by_cur_task(void)
+ble_gattc_log_proc_init(char *name)
 {
-    return ble_fsm_locked_by_cur_task(&ble_gattc_fsm);
+    BLE_HS_LOG(INFO, "GATT procedure initiated: %s", name);
 }
 
-/*****************************************************************************
- * $log                                                                      *
- *****************************************************************************/
-
 static void
 ble_gattc_log_uuid(void *uuid128)
 {
@@ -519,14 +355,16 @@ ble_gattc_log_uuid(void *uuid128)
 static void
 ble_gattc_log_disc_svc_uuid(struct ble_gattc_proc *proc)
 {
-    BLE_HS_LOG(INFO, "uuid=");
+    ble_gattc_log_proc_init("discover service by uuid; uuid=");
     ble_gattc_log_uuid(proc->disc_svc_uuid.service_uuid);
+    BLE_HS_LOG(INFO, "\n");
 }
 
 static void
 ble_gattc_log_find_inc_svcs(struct ble_gattc_proc *proc)
 {
-    BLE_HS_LOG(INFO, "start_handle=%d end_handle=%d",
+    ble_gattc_log_proc_init("find included services; ");
+    BLE_HS_LOG(INFO, "start_handle=%d end_handle=%d\n",
                proc->find_inc_svcs.prev_handle + 1,
                proc->find_inc_svcs.end_handle);
 }
@@ -534,7 +372,8 @@ ble_gattc_log_find_inc_svcs(struct ble_gattc_proc *proc)
 static void
 ble_gattc_log_disc_all_chrs(struct ble_gattc_proc *proc)
 {
-    BLE_HS_LOG(INFO, "start_handle=%d end_handle=%d",
+    ble_gattc_log_proc_init("discover all characteristics; ");
+    BLE_HS_LOG(INFO, "start_handle=%d end_handle=%d\n",
                proc->disc_all_chrs.prev_handle + 1,
                proc->disc_all_chrs.end_handle);
 }
@@ -542,72 +381,89 @@ ble_gattc_log_disc_all_chrs(struct ble_gattc_proc *proc)
 static void
 ble_gattc_log_disc_chr_uuid(struct ble_gattc_proc *proc)
 {
+    ble_gattc_log_proc_init("discover characteristics by uuid; ");
     BLE_HS_LOG(INFO, "start_handle=%d end_handle=%d uuid=",
                proc->disc_chr_uuid.prev_handle + 1,
                proc->disc_chr_uuid.end_handle);
-
     ble_gattc_log_uuid(proc->disc_chr_uuid.chr_uuid);
+    BLE_HS_LOG(INFO, "\n");
 }
 
 static void
 ble_gattc_log_disc_all_dscs(struct ble_gattc_proc *proc)
 {
-    BLE_HS_LOG(INFO, "chr_def_handle=%d end_handle=%d",
+    ble_gattc_log_proc_init("discover all descriptors; ");
+    BLE_HS_LOG(INFO, "chr_def_handle=%d end_handle=%d\n",
                proc->disc_all_dscs.chr_def_handle,
                proc->disc_all_dscs.end_handle);
 }
 
 static void
-ble_gattc_log_read(struct ble_gattc_proc *proc)
+ble_gattc_log_read(uint16_t att_handle)
 {
-    BLE_HS_LOG(INFO, "att_handle=%d", proc->read.handle);
+    ble_gattc_log_proc_init("read; ");
+    BLE_HS_LOG(INFO, "att_handle=%d\n", att_handle);
 }
 
 static void
-ble_gattc_log_read_uuid(struct ble_gattc_proc *proc)
+ble_gattc_log_read_uuid(uint16_t start_handle, uint16_t end_handle,
+                        uint8_t *uuid128)
 {
     uint16_t uuid16;
 
+    ble_gattc_log_proc_init("read by uuid; ");
     BLE_HS_LOG(INFO, "start_handle=%d end_handle=%d uuid=",
-               proc->read_uuid.prev_handle + 1, proc->read_uuid.end_handle);
+               start_handle, end_handle);
 
-    uuid16 = ble_uuid_128_to_16(proc->read_uuid.uuid128);
+    uuid16 = ble_uuid_128_to_16(uuid128);
     if (uuid16 != 0) {
         BLE_HS_LOG(INFO, "0x%04x", uuid16);
     } else {
-        ble_gattc_log_uuid(proc->read_uuid.uuid128);
+        ble_gattc_log_uuid(uuid128);
     }
+    BLE_HS_LOG(INFO, "\n");
 }
 
 static void
 ble_gattc_log_read_long(struct ble_gattc_proc *proc)
 {
-    BLE_HS_LOG(INFO, "att_handle=%d", proc->read_long.handle);
+    ble_gattc_log_proc_init("read long; ");
+    BLE_HS_LOG(INFO, "att_handle=%d\n", proc->read_long.handle);
 }
 
 static void
-ble_gattc_log_read_mult(struct ble_gattc_proc *proc)
+ble_gattc_log_read_mult(uint16_t *handles, uint8_t num_handles)
 {
     int i;
 
+    ble_gattc_log_proc_init("read multiple; ");
     BLE_HS_LOG(INFO, "att_handles=");
-    for (i = 0; i < proc->read_mult.num_handles; i++) {
-        BLE_HS_LOG(INFO, "%s%d", i != 0 ? "," : "",
-                   proc->read_mult.handles[i]);
+    for (i = 0; i < num_handles; i++) {
+        BLE_HS_LOG(INFO, "%s%d", i != 0 ? "," : "", handles[i]);
     }
+    BLE_HS_LOG(INFO, "\n");
 }
 
 static void
-ble_gattc_log_write(struct ble_gattc_proc *proc)
+ble_gattc_log_write(uint16_t att_handle, uint16_t len, int expecting_rsp)
 {
-    BLE_HS_LOG(INFO, "att_handle=%d len=%d",
-               proc->write.attr.handle, proc->write.attr.value_len);
+    char *name;
+
+    if (expecting_rsp) {
+        name = "write; ";
+    } else {
+        name = "write no rsp; ";
+    }
+
+    ble_gattc_log_proc_init(name);
+    BLE_HS_LOG(INFO, "att_handle=%d len=%d\n", att_handle, len);
 }
 
 static void
 ble_gattc_log_write_long(struct ble_gattc_proc *proc)
 {
-    BLE_HS_LOG(INFO, "att_handle=%d len=%d",
+    ble_gattc_log_proc_init("write long; ");
+    BLE_HS_LOG(INFO, "att_handle=%d len=%d\n",
                proc->write_long.attr.handle, proc->write_long.attr.value_len);
 }
 
@@ -616,32 +472,33 @@ ble_gattc_log_write_reliable(struct ble_gattc_proc *proc)
 {
     int i;
 
+    ble_gattc_log_proc_init("write reliable; ");
     BLE_HS_LOG(INFO, "att_handles=");
     for (i = 0; i < proc->write_reliable.num_attrs; i++) {
         BLE_HS_LOG(INFO, "%s%d", i != 0 ? "," : "",
                    proc->write_reliable.attrs[i].handle);
     }
+    BLE_HS_LOG(INFO, "\n");
 }
 
 static void
-ble_gattc_log_notify(struct ble_gattc_proc *proc)
+ble_gattc_log_notify(uint16_t att_handle)
 {
-    BLE_HS_LOG(INFO, "att_handle=%d", proc->notify.attr.handle);
+    ble_gattc_log_proc_init("notify; ");
+    BLE_HS_LOG(INFO, "att_handle=%d\n", att_handle);
 }
 
 static void
-ble_gattc_log_indicate(struct ble_gattc_proc *proc)
+ble_gattc_log_indicate(uint16_t att_handle)
 {
-    BLE_HS_LOG(INFO, "att_handle=%d", proc->indicate.attr.handle);
+    ble_gattc_log_proc_init("indicate; ");
+    BLE_HS_LOG(INFO, "att_handle=%d\n", att_handle);
 }
 
 /*****************************************************************************
  * $rx entry                                                                 *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
 static const void *
 ble_gattc_rx_entry_find(uint8_t op, const void *rx_entries, int num_entries)
 {
@@ -670,8 +527,6 @@ ble_gattc_rx_entry_find(uint8_t op, const void *rx_entries, int num_entries)
 /**
  * Allocates a proc entry.
  *
- * Lock restrictions: None.
- *
  * @return                      An entry on success; null on failure.
  */
 static struct ble_gattc_proc *
@@ -689,11 +544,9 @@ ble_gattc_proc_alloc(void)
 
 /**
  * Frees the specified proc entry.  No-op if passed a null pointer.
- *
- * Lock restrictions: None.
  */
 static void
-ble_gattc_proc_free(struct ble_fsm_proc *proc)
+ble_gattc_proc_free(struct ble_gattc_proc *proc)
 {
     int rc;
 
@@ -703,24 +556,58 @@ ble_gattc_proc_free(struct ble_fsm_proc *proc)
     }
 }
 
+static void
+ble_gattc_proc_insert(struct ble_gattc_proc *proc)
+{
+    ble_hs_lock();
+    STAILQ_INSERT_HEAD(&ble_gattc_procs, proc, next);
+    ble_hs_unlock();
+}
+
+static void
+ble_gattc_proc_set_timer(struct ble_gattc_proc *proc)
+{
+    proc->exp_os_ticks = os_time_get() + BLE_GATT_UNRESPONSIVE_TIMEOUT;
+}
+
+static void
+ble_gattc_process_status(struct ble_gattc_proc *proc, int status)
+{
+    if (status == 0) {
+        ble_gattc_proc_set_timer(proc);
+        ble_gattc_proc_insert(proc);
+    } else {
+        ble_gattc_proc_free(proc);
+    }
+}
+
+/*****************************************************************************
+ * $util                                                                     *
+ *****************************************************************************/
+
+/**
+ * Retrieves the dispatch entry with the specified op code.
+ */
+static ble_gattc_err_fn *
+ble_gattc_err_dispatch_get(uint8_t op)
+{
+    BLE_HS_DBG_ASSERT(op < BLE_GATT_OP_MAX);
+    return ble_gattc_err_dispatch[op];
+}
+
 /**
  * Tests if a proc entry fits the specified criteria.
  *
- * Lock restrictions:
- *     o Caller locks gattc.
- *
  * @param proc                  The procedure to test.
  * @param conn_handle           The connection handle to match against.
  * @param op                    The op code to match against, or
  *                                  BLE_GATT_OP_NONE to ignore this criterion.
- * @param expecting_only        1=Only match entries expecting a response;
- *                                  0=Ignore this criterion.
  *
  * @return                      1 if the proc matches; 0 otherwise.
  */
 static int
-ble_gattc_proc_matches(struct ble_fsm_proc *proc, uint16_t conn_handle,
-                       uint8_t op, int expecting_only)
+ble_gattc_proc_matches(struct ble_gattc_proc *proc, uint16_t conn_handle,
+                       uint8_t op)
 {
     if (conn_handle != proc->conn_handle) {
         return 0;
@@ -730,111 +617,161 @@ ble_gattc_proc_matches(struct ble_fsm_proc *proc, uint16_t conn_handle,
         return 0;
     }
 
-    if (expecting_only &&
-        !(proc->flags & BLE_FSM_PROC_F_EXPECTING)) {
-
-        return 0;
-    }
-
     return 1;
 }
 
-/**
- * Sets the specified proc entry's "pending" flag (i.e., indicates that the
- * GATT procedure is stalled until it transmits its next ATT request.
- *
- * Lock restrictions:
- *     o Caller locks gattc.
- */
-static void
-ble_gattc_proc_set_pending(struct ble_gattc_proc *proc)
+static struct ble_gattc_proc *
+ble_gattc_extract(uint16_t conn_handle, uint8_t op)
 {
-    ble_fsm_proc_set_pending(&proc->fsm_proc);
-    ble_hs_kick_gatt();
+    struct ble_gattc_proc *proc;
+    struct ble_gattc_proc *prev;
+
+    ble_hs_lock();
+
+    prev = NULL;
+    STAILQ_FOREACH(proc, &ble_gattc_procs, next) {
+        if (ble_gattc_proc_matches(proc, conn_handle, op)) {
+            if (prev == NULL) {
+                STAILQ_REMOVE_HEAD(&ble_gattc_procs, next);
+            } else {
+                STAILQ_REMOVE_AFTER(&ble_gattc_procs, prev, next);
+            }
+            break;
+        }
+        prev = proc;
+    }
+
+    ble_hs_unlock();
+
+    return proc;
 }
 
-/**
- * Creates a new proc entry and sets its fields to the specified values.  The
- * entry is automatically inserted into the global proc list, and its "pending"
- * flag is set.
- *
- * Lock restrictions:
- *     o Caller locks gattc.
- *
- * @param conn_handle           The handle of the connection associated with
- *                                  the GATT procedure.
- * @param op                    The op code for the proc entry (one of the
- *                                  BLE_GATT_OP_[...] constants).
- * @param out_proc              On success, the new entry's address gets
- *                                  written here.
- *
- * @return                      0 on success; BLE_HS error code on failure.
- */
-static int
-ble_gattc_new_proc(uint16_t conn_handle, uint8_t op,
-                   struct ble_gattc_proc **out_proc)
+static void
+ble_gattc_extract_by_conn(uint16_t conn_handle,
+                          struct ble_gattc_proc_list *dst_list)
 {
     struct ble_gattc_proc *proc;
+    struct ble_gattc_proc *prev;
+    struct ble_gattc_proc *next;
 
-    proc = ble_gattc_proc_alloc();
-    if (proc == NULL) {
-        return BLE_HS_ENOMEM;
-    }
-
-    memset(proc, 0, sizeof *proc);
-    proc->fsm_proc.op = op;
-    proc->fsm_proc.conn_handle = conn_handle;
+    STAILQ_INIT(dst_list);
 
-    STAILQ_INSERT_TAIL(&ble_gattc_fsm.procs, &proc->fsm_proc, next);
+    ble_hs_lock();
 
-    *out_proc = proc;
+    prev = NULL;
+    proc = STAILQ_FIRST(&ble_gattc_procs);
+    while (proc != NULL) {
+        next = STAILQ_NEXT(proc, next);
 
-    return 0;
-}
+        if (proc->conn_handle == conn_handle) {
+            if (prev == NULL) {
+                STAILQ_REMOVE_HEAD(&ble_gattc_procs, next);
+            } else {
+                STAILQ_REMOVE_AFTER(&ble_gattc_procs, prev, next);
+            }
+            STAILQ_INSERT_TAIL(dst_list, proc, next);
+        }
 
-/*****************************************************************************
- * $util                                                                     *
- *****************************************************************************/
+        prev = proc;
+        proc = next;
+    }
 
-/**
- * Retrieves the dispatch entry with the specified op code.
- *
- * Lock restrictions: None.
- */
-static const struct ble_gattc_dispatch_entry *
-ble_gattc_dispatch_get(uint8_t op)
-{
-    BLE_HS_DBG_ASSERT(op < BLE_GATT_OP_MAX);
-    return ble_gattc_dispatch + op;
+    ble_hs_unlock();
 }
 
-static int
-ble_gattc_heartbeat_extract_cb(struct ble_fsm_proc *proc, void *arg)
+static void
+ble_gattc_extract_expired(struct ble_gattc_proc_list *dst_list)
 {
-    uint32_t *now;
+    struct ble_gattc_proc *proc;
+    struct ble_gattc_proc *prev;
+    struct ble_gattc_proc *next;
+    uint32_t now;
+    int32_t time_diff;
 
-    now = arg;
+    now = os_time_get();
+    STAILQ_INIT(dst_list);
 
-    if (proc->flags & BLE_FSM_PROC_F_EXPECTING) {
-        if (*now - proc->tx_time >= BLE_GATT_UNRESPONSIVE_TIMEOUT) {
-            return BLE_FSM_EXTRACT_EMOVE_CONTINUE;
+    ble_hs_lock();
+
+    prev = NULL;
+    proc = STAILQ_FIRST(&ble_gattc_procs);
+    while (proc != NULL) {
+        next = STAILQ_NEXT(proc, next);
+
+        time_diff = now - proc->exp_os_ticks;
+        if (time_diff >= 0) {
+            if (prev == NULL) {
+                STAILQ_REMOVE_HEAD(&ble_gattc_procs, next);
+            } else {
+                STAILQ_REMOVE_AFTER(&ble_gattc_procs, prev, next);
+            }
+            STAILQ_INSERT_TAIL(dst_list, proc, next);
         }
+
+        prev = proc;
+        proc = next;
     }
 
-    /* If a proc failed due to low memory, don't extract it, but set its 
-     * pending bit.
-     */
-    if (proc->flags & BLE_FSM_PROC_F_NO_MEM) {
-        proc->flags &= ~BLE_FSM_PROC_F_NO_MEM;
-        if (ble_fsm_proc_can_pend(proc)) {
-            ble_fsm_proc_set_pending(proc);
+    ble_hs_unlock();
+}
+
+static struct ble_gattc_proc *
+ble_gattc_extract_with_rx_entry(uint16_t conn_handle,
+                                const void *rx_entries, int num_entries,
+                                const void **out_rx_entry)
+{
+    struct ble_gattc_proc *proc;
+    struct ble_gattc_proc *prev;
+    const void *rx_entry;
+
+    ble_hs_lock();
+
+    prev = NULL;
+    STAILQ_FOREACH(proc, &ble_gattc_procs, next) {
+        if (proc->conn_handle == conn_handle) {
+            rx_entry = ble_gattc_rx_entry_find(proc->op, rx_entries,
+                                               num_entries);
+            if (rx_entry != NULL) {
+                if (prev == NULL) {
+                    STAILQ_REMOVE_HEAD(&ble_gattc_procs, next);
+                } else {
+                    STAILQ_REMOVE_AFTER(&ble_gattc_procs, prev, next);
+                }
+
+                *out_rx_entry = rx_entry;
+                break;
+            }
         }
+
+        prev = proc;
     }
 
-    return BLE_FSM_EXTRACT_EKEEP_CONTINUE;
+    ble_hs_unlock();
+
+    return proc;
 }
 
 /**
+ * Searches the main proc list for an "expecting" entry whose connection handle
+ * and op code match those specified.  If a matching entry is found, it is
+ * removed from the list and returned.
+ *
+ * @param conn_handle           The connection handle to match against.
+ * @param rx_entries            The array of rx entries corresponding to the
+ *                                  op code of the incoming response.
+ * @param out_rx_entry          On success, the address of the matching rx
+ *                                  entry is written to this pointer.
+ *
+ * @return                      The matching proc entry on success;
+ *                                  null on failure.
+ */
+#define BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, rx_entries, out_rx_entry)  \
+    ble_gattc_extract_with_rx_entry(                                          \
+        (conn_handle), (rx_entries),                                          \
+        sizeof (rx_entries) / sizeof (rx_entries)[0],                         \
+        (const void **)(out_rx_entry))
+
+/**
  * Applies periodic checks and actions to all active procedures.
  *
  * All procedures that failed due to memory exaustion have their pending flag
@@ -844,44 +781,33 @@ ble_gattc_heartbeat_extract_cb(struct ble_fsm_proc *proc, void *arg)
  * seconds are aborted, and their corresponding connection is terminated.
  *
  * Called by the host heartbeat timer; executed every second.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 void
 ble_gattc_heartbeat(void)
 {
-    struct ble_fsm_proc_list temp_list;
-    struct ble_fsm_proc *proc;
-    uint32_t now;
-
-    now = os_time_get();
+    struct ble_gattc_proc_list exp_list;
+    struct ble_gattc_proc *proc;
 
     /* Remove timed-out procedures from the main list and insert them into a
      * temporary list.  For any stalled procedures, set their pending bit so
      * they can be retried.
      */
-    ble_fsm_proc_extract_list(&ble_gattc_fsm, &temp_list,
-                              ble_gattc_heartbeat_extract_cb, &now);
+    ble_gattc_extract_expired(&exp_list);
 
     /* Terminate the connection associated with each timed-out procedure. */
-    STAILQ_FOREACH(proc, &temp_list, next) {
+    while ((proc = STAILQ_FIRST(&exp_list)) != NULL) {
         STATS_INC(ble_gattc_stats, proc_timeout);
         ble_gap_terminate(proc->conn_handle);
-    }
 
-    /* Concatenate the list of timed out procedures back onto the end of the
-     * main list.
-     */
-    ble_fsm_proc_concat(&ble_gattc_fsm, &temp_list);
+        STAILQ_REMOVE_HEAD(&exp_list, next);
+        ble_gattc_proc_free(proc);
+    }
 }
 
 /**
  * Returns a pointer to a GATT error object with the specified fields.  The
  * returned object is statically allocated, so this function is not reentrant.
  * This function should only ever be called by the ble_hs task.
- *
- * Lock restrictions: None.
  */
 struct ble_gatt_error *
 ble_gattc_error(int status, uint16_t att_handle)
@@ -905,9 +831,6 @@ ble_gattc_error(int status, uint16_t att_handle)
  * Calls an mtu-exchange proc's callback with the specified parameters.  If the
  * proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -917,7 +840,7 @@ ble_gattc_mtu_cb(struct ble_gattc_proc *proc, int status, uint16_t att_handle,
 {
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, mtu_fail);
@@ -926,7 +849,7 @@ ble_gattc_mtu_cb(struct ble_gattc_proc *proc, int status, uint16_t att_handle,
     if (proc->mtu.cb == NULL) {
         rc = 0;
     } else {
-        rc = proc->mtu.cb(proc->fsm_proc.conn_handle,
+        rc = proc->mtu.cb(proc->conn_handle,
                           ble_gattc_error(status, att_handle),
                           mtu, proc->mtu.cb_arg);
     }
@@ -935,53 +858,7 @@ ble_gattc_mtu_cb(struct ble_gattc_proc *proc, int status, uint16_t att_handle,
 }
 
 /**
- * Triggers a pending transmit for the specified mtu-exchange proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-static int
-ble_gattc_mtu_kick(struct ble_gattc_proc *proc)
-{
-    struct ble_att_mtu_cmd req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
-    int rc;
-
-    ble_hs_conn_lock();
-
-    rc = ble_att_conn_chan_find(proc->fsm_proc.conn_handle, &conn, &chan);
-    if (rc == 0) {
-        req.bamc_mtu = chan->blc_my_mtu;
-    }
-
-    ble_hs_conn_unlock();
-
-    if (rc != 0) {
-        goto err;
-    }
-
-    rc = ble_att_clt_tx_mtu(proc->fsm_proc.conn_handle, &req);
-    if (rc != 0) {
-        goto err;
-    }
-
-    return 0;
-
-err:
-    if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-        return BLE_HS_EAGAIN;
-    } else {
-        ble_gattc_mtu_cb(proc, rc, 0, 0);
-        return BLE_HS_EDONE;
-    }
-}
-
-/**
  * Handles an incoming ATT error response for the specified mtu-exchange proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gattc_mtu_err(struct ble_gattc_proc *proc, int status, uint16_t att_handle)
@@ -990,26 +867,8 @@ ble_gattc_mtu_err(struct ble_gattc_proc *proc, int status, uint16_t att_handle)
 }
 
 /**
- * Handles an incoming ATT exchange mtu response for the specified mtu-exchange
- * proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-static int
-ble_gattc_mtu_rx_rsp(struct ble_gattc_proc *proc,
-                     int status, uint16_t chan_mtu)
-{
-    ble_gattc_mtu_cb(proc, status, 0, chan_mtu);
-    return 1;
-}
-
-/**
  * Initiates GATT procedure: Exchange MTU.
  *
- * Lock restrictions:
- *     o Caller unlocks gattc.
- *
  * @param conn_handle           The connection over which to execute the
  *                                  procedure.
  * @param cb                    The function to call to report procedure status
@@ -1019,27 +878,51 @@ ble_gattc_mtu_rx_rsp(struct ble_gattc_proc *proc,
 int
 ble_gattc_exchange_mtu(uint16_t conn_handle, ble_gatt_mtu_fn *cb, void *cb_arg)
 {
+    struct ble_att_mtu_cmd req;
     struct ble_gattc_proc *proc;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
     int rc;
 
     STATS_INC(ble_gattc_stats, mtu);
 
-    ble_gattc_lock();
+    proc = ble_gattc_proc_alloc();
+    if (proc == NULL) {
+        return BLE_HS_ENOMEM;
+    }
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_MTU, &proc);
+    proc->op = BLE_GATT_OP_MTU;
+    proc->conn_handle = conn_handle;
+    proc->mtu.cb = cb;
+    proc->mtu.cb_arg = cb_arg;
+
+    ble_gattc_log_proc_init("exchange mtu\n");
+
+    ble_hs_lock();
+
+    rc = ble_att_conn_chan_find(proc->conn_handle, &conn, &chan);
     if (rc == 0) {
-        proc->mtu.cb = cb;
-        proc->mtu.cb_arg = cb_arg;
+        req.bamc_mtu = chan->blc_my_mtu;
+    }
 
-        BLE_HS_LOG(INFO, "GATT procedure initiated: exchange mtu\n");
+    ble_hs_unlock();
 
-        ble_gattc_proc_set_pending(proc);
-    } else {
-        STATS_INC(ble_gattc_stats, mtu_fail);
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = ble_att_clt_tx_mtu(proc->conn_handle, &req);
+    if (rc != 0) {
+        goto err;
     }
 
-    ble_gattc_unlock();
+    ble_gattc_proc_insert(proc);
 
+    return 0;
+
+err:
+    STATS_INC(ble_gattc_stats, mtu_fail);
+    ble_gattc_proc_free((void *)proc);
     return rc;
 }
 
@@ -1051,9 +934,6 @@ ble_gattc_exchange_mtu(uint16_t conn_handle, ble_gatt_mtu_fn *cb, void *cb_arg)
  * Calls a discover-all-services proc's callback with the specified parameters.
  * If the proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -1064,7 +944,7 @@ ble_gattc_disc_all_svcs_cb(struct ble_gattc_proc *proc,
 {
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_svcs_fail);
@@ -1073,7 +953,7 @@ ble_gattc_disc_all_svcs_cb(struct ble_gattc_proc *proc,
     if (proc->disc_all_svcs.cb == NULL) {
         rc = 0;
     } else {
-        rc = proc->disc_all_svcs.cb(proc->fsm_proc.conn_handle,
+        rc = proc->disc_all_svcs.cb(proc->conn_handle,
                                     ble_gattc_error(status, att_handle),
                                     service, proc->disc_all_svcs.cb_arg);
     }
@@ -1083,12 +963,9 @@ ble_gattc_disc_all_svcs_cb(struct ble_gattc_proc *proc,
 
 /**
  * Triggers a pending transmit for the specified discover-all-services proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
-ble_gattc_disc_all_svcs_kick(struct ble_gattc_proc *proc)
+ble_gattc_disc_all_svcs_go(struct ble_gattc_proc *proc, int cb_on_err)
 {
     struct ble_att_read_group_type_req req;
     uint8_t uuid128[16];
@@ -1099,27 +976,21 @@ ble_gattc_disc_all_svcs_kick(struct ble_gattc_proc *proc)
 
     req.bagq_start_handle = proc->disc_all_svcs.prev_handle + 1;
     req.bagq_end_handle = 0xffff;
-    rc = ble_att_clt_tx_read_group_type(proc->fsm_proc.conn_handle, &req,
-                                        uuid128);
+    rc = ble_att_clt_tx_read_group_type(proc->conn_handle, &req, uuid128);
 
     if (rc != 0) {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            rc = BLE_HS_EAGAIN;
-        } else {
+        if (cb_on_err) {
             ble_gattc_disc_all_svcs_cb(proc, rc, 0, NULL);
-            rc = BLE_HS_EDONE;
         }
+        return rc;
     }
 
-    return rc;
+    return 0;
 }
 
 /**
  * Handles an incoming ATT error response for the specified
  * discover-all-services proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gattc_disc_all_svcs_err(struct ble_gattc_proc *proc, int status,
@@ -1136,9 +1007,6 @@ ble_gattc_disc_all_svcs_err(struct ble_gattc_proc *proc, int status,
 /**
  * Handles an incoming attribute data entry from a read-group-type response for
  * the specified discover-all-services proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_all_svcs_rx_adata(struct ble_gattc_proc *proc,
@@ -1163,7 +1031,7 @@ ble_gattc_disc_all_svcs_rx_adata(struct ble_gattc_proc *proc,
         break;
 
     default:
-        rc = BLE_HS_EMSGSIZE;
+        rc = BLE_HS_EBADDATA;
         goto done;
     }
 
@@ -1182,29 +1050,33 @@ ble_gattc_disc_all_svcs_rx_adata(struct ble_gattc_proc *proc,
 
 done:
     cbrc = ble_gattc_disc_all_svcs_cb(proc, rc, 0, &service);
-    if (rc == 0) {
-        rc = cbrc;
+    if (rc != 0 || cbrc != 0) {
+        return BLE_HS_EDONE;
+    } else {
+        return 0;
     }
-    return rc;
 }
 
 /**
  * Handles a notification that an incoming read-group-type response has been
  * fully processed.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_all_svcs_rx_complete(struct ble_gattc_proc *proc, int status)
 {
+    int rc;
+
     if (status != 0 || proc->disc_all_svcs.prev_handle == 0xffff) {
         /* Error or all svcs discovered. */
         ble_gattc_disc_all_svcs_cb(proc, status, 0, NULL);
-        return 1;
+        return BLE_HS_EDONE;
     } else {
         /* Send follow-up request. */
-        ble_gattc_proc_set_pending(proc);
+        rc = ble_gattc_disc_all_svcs_go(proc, 1);
+        if (rc != 0) {
+            return BLE_HS_EDONE;
+        }
+
         return 0;
     }
 }
@@ -1212,9 +1084,6 @@ ble_gattc_disc_all_svcs_rx_complete(struct ble_gattc_proc *proc, int status)
 /**
  * Initiates GATT procedure: Discover All Primary Services.
  *
- * Lock restrictions:
- *     o Caller unlocks gattc.
- *
  * @param conn_handle           The connection over which to execute the
  *                                  procedure.
  * @param cb                    The function to call to report procedure status
@@ -1234,19 +1103,23 @@ ble_gattc_disc_all_svcs(uint16_t conn_handle, ble_gatt_disc_svc_fn *cb,
 
     STATS_INC(ble_gattc_stats, disc_all_svcs);
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_ALL_SVCS, &proc);
-    if (rc == 0) {
-        proc->disc_all_svcs.prev_handle = 0x0000;
-        proc->disc_all_svcs.cb = cb;
-        proc->disc_all_svcs.cb_arg = cb_arg;
-
-        BLE_HS_LOG(INFO, "GATT procedure initiated: discover all services\n");
-
-        ble_gattc_proc_set_pending(proc);
-    } else {
+    proc = ble_gattc_proc_alloc();
+    if (proc == NULL) {
         STATS_INC(ble_gattc_stats, disc_all_svcs_fail);
+        return BLE_HS_ENOMEM;
     }
 
+    proc->op = BLE_GATT_OP_DISC_ALL_SVCS;
+    proc->conn_handle = conn_handle;
+    proc->disc_all_svcs.prev_handle = 0x0000;
+    proc->disc_all_svcs.cb = cb;
+    proc->disc_all_svcs.cb_arg = cb_arg;
+
+    ble_gattc_log_proc_init("discover all services\n");
+
+    rc = ble_gattc_disc_all_svcs_go(proc, 0);
+    ble_gattc_process_status(proc, rc);
+
     return rc;
 }
 
@@ -1258,9 +1131,6 @@ ble_gattc_disc_all_svcs(uint16_t conn_handle, ble_gatt_disc_svc_fn *cb,
  * Calls a discover-service-by-uuid proc's callback with the specified
  * parameters.  If the proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -1271,7 +1141,7 @@ ble_gattc_disc_svc_uuid_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_svc_uuid_fail);
@@ -1280,7 +1150,7 @@ ble_gattc_disc_svc_uuid_cb(struct ble_gattc_proc *proc, int status,
     if (proc->disc_svc_uuid.cb == NULL) {
         rc = 0;
     } else {
-        rc = proc->disc_svc_uuid.cb(proc->fsm_proc.conn_handle,
+        rc = proc->disc_svc_uuid.cb(proc->conn_handle,
                                     ble_gattc_error(status, att_handle),
                                     service, proc->disc_svc_uuid.cb_arg);
     }
@@ -1290,12 +1160,9 @@ ble_gattc_disc_svc_uuid_cb(struct ble_gattc_proc *proc, int status,
 
 /**
  * Triggers a pending transmit for the specified discover-service-by-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
-ble_gattc_disc_svc_uuid_kick(struct ble_gattc_proc *proc)
+ble_gattc_disc_svc_uuid_go(struct ble_gattc_proc *proc, int cb_on_err)
 {
     struct ble_att_find_type_value_req req;
     int rc;
@@ -1304,26 +1171,21 @@ ble_gattc_disc_svc_uuid_kick(struct ble_gattc_proc *proc)
     req.bavq_end_handle = 0xffff;
     req.bavq_attr_type = BLE_ATT_UUID_PRIMARY_SERVICE;
 
-    rc = ble_att_clt_tx_find_type_value(proc->fsm_proc.conn_handle, &req,
+    rc = ble_att_clt_tx_find_type_value(proc->conn_handle, &req,
                                         proc->disc_svc_uuid.service_uuid, 16);
     if (rc != 0) {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            rc = BLE_HS_EAGAIN;
-        } else {
+        if (cb_on_err) {
             ble_gattc_disc_svc_uuid_cb(proc, rc, 0, NULL);
-            rc = BLE_HS_EDONE;
         }
+        return rc;
     }
 
-    return rc;
+    return 0;
 }
 
 /**
  * Handles an incoming ATT error response for the specified
  * discover-service-by-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gattc_disc_svc_uuid_err(struct ble_gattc_proc *proc, int status,
@@ -1340,9 +1202,6 @@ ble_gattc_disc_svc_uuid_err(struct ble_gattc_proc *proc, int status,
 /**
  * Handles an incoming "handles info" entry from a find-type-value response for
  * the specified discover-service-by-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_svc_uuid_rx_hinfo(struct ble_gattc_proc *proc,
@@ -1368,29 +1227,32 @@ ble_gattc_disc_svc_uuid_rx_hinfo(struct ble_gattc_proc *proc,
 
 done:
     cbrc = ble_gattc_disc_svc_uuid_cb(proc, rc, 0, &service);
-    if (rc != 0) {
-        rc = cbrc;
+    if (rc != 0 || cbrc != 0) {
+        return BLE_HS_EDONE;
+    } else {
+        return 0;
     }
-    return rc;
 }
 
 /**
  * Handles a notification that a find-type-value response has been fully
  * processed for the specified discover-service-by-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_svc_uuid_rx_complete(struct ble_gattc_proc *proc, int status)
 {
+    int rc;
+
     if (status != 0 || proc->disc_svc_uuid.prev_handle == 0xffff) {
         /* Error or all svcs discovered. */
         ble_gattc_disc_svc_uuid_cb(proc, status, 0, NULL);
-        return 1;
+        return BLE_HS_EDONE;
     } else {
         /* Send follow-up request. */
-        ble_gattc_proc_set_pending(proc);
+        rc = ble_gattc_disc_svc_uuid_go(proc, 1);
+        if (rc != 0) {
+            return BLE_HS_EDONE;
+        }
         return 0;
     }
 }
@@ -1398,9 +1260,6 @@ ble_gattc_disc_svc_uuid_rx_complete(struct ble_gattc_proc *proc, int status)
 /**
  * Initiates GATT procedure: Discover Primary Service by Service UUID.
  *
- * Lock restrictions:
- *     o Caller unlocks gattc.
- *
  * @param conn_handle           The connection over which to execute the
  *                                  procedure.
  * @param service_uuid128       The 128-bit UUID of the service to discover.
@@ -1421,23 +1280,24 @@ ble_gattc_disc_svc_by_uuid(uint16_t conn_handle, void *service_uuid128,
 
     STATS_INC(ble_gattc_stats, disc_svc_uuid);
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_SVC_UUID, &proc);
-    if (rc == 0) {
-        memcpy(proc->disc_svc_uuid.service_uuid, service_uuid128, 16);
-        proc->disc_svc_uuid.prev_handle = 0x0000;
-        proc->disc_svc_uuid.cb = cb;
-        proc->disc_svc_uuid.cb_arg = cb_arg;
-
-        BLE_HS_LOG(INFO, "GATT procedure initiated: discover service by "
-                         "uuid; ");
-        ble_gattc_log_disc_svc_uuid(proc);
-        BLE_HS_LOG(INFO, "\n");
-
-        ble_gattc_proc_set_pending(proc);
-    } else {
+    proc = ble_gattc_proc_alloc();
+    if (proc == NULL) {
         STATS_INC(ble_gattc_stats, disc_svc_uuid_fail);
+        return BLE_HS_ENOMEM;
     }
 
+    proc->op = BLE_GATT_OP_DISC_SVC_UUID;
+    proc->conn_handle = conn_handle;
+    memcpy(proc->disc_svc_uuid.service_uuid, service_uuid128, 16);
+    proc->disc_svc_uuid.prev_handle = 0x0000;
+    proc->disc_svc_uuid.cb = cb;
+    proc->disc_svc_uuid.cb_arg = cb_arg;
+
+    ble_gattc_log_disc_svc_uuid(proc);
+
+    rc = ble_gattc_disc_svc_uuid_go(proc, 0);
+    ble_gattc_process_status(proc, rc);
+
     return rc;
 }
 
@@ -1449,9 +1309,6 @@ ble_gattc_disc_svc_by_uuid(uint16_t conn_handle, void *service_uuid128,
  * Calls a find-included-services proc's callback with the specified
  * parameters.  If the proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -1462,7 +1319,7 @@ ble_gattc_find_inc_svcs_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, find_inc_svcs_fail);
@@ -1471,7 +1328,7 @@ ble_gattc_find_inc_svcs_cb(struct ble_gattc_proc *proc, int status,
     if (proc->find_inc_svcs.cb == NULL) {
         rc = 0;
     } else {
-        rc = proc->find_inc_svcs.cb(proc->fsm_proc.conn_handle,
+        rc = proc->find_inc_svcs.cb(proc->conn_handle,
                                     ble_gattc_error(status, att_handle),
                                     service, proc->find_inc_svcs.cb_arg);
     }
@@ -1481,12 +1338,9 @@ ble_gattc_find_inc_svcs_cb(struct ble_gattc_proc *proc, int status,
 
 /**
  * Triggers a pending transmit for the specified find-included-services proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
-ble_gattc_find_inc_svcs_kick(struct ble_gattc_proc *proc)
+ble_gattc_find_inc_svcs_go(struct ble_gattc_proc *proc, int cb_on_err)
 {
     struct ble_att_read_type_req read_type_req;
     struct ble_att_read_req read_req;
@@ -1502,32 +1356,27 @@ ble_gattc_find_inc_svcs_kick(struct ble_gattc_proc *proc)
         rc = ble_uuid_16_to_128(BLE_ATT_UUID_INCLUDE, uuid128);
         BLE_HS_DBG_ASSERT_EVAL(rc == 0);
 
-        rc = ble_att_clt_tx_read_type(proc->fsm_proc.conn_handle,
+        rc = ble_att_clt_tx_read_type(proc->conn_handle,
                                       &read_type_req, uuid128);
     } else {
         /* Read the UUID of the previously found service. */
         read_req.barq_handle = proc->find_inc_svcs.cur_start;
-        rc = ble_att_clt_tx_read(proc->fsm_proc.conn_handle, &read_req);
+        rc = ble_att_clt_tx_read(proc->conn_handle, &read_req);
     }
 
     if (rc != 0) {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
-        } else {
+        if (cb_on_err) {
             ble_gattc_find_inc_svcs_cb(proc, rc, 0, NULL);
-            return BLE_HS_EDONE;
         }
+        return rc;
     }
 
-    return rc;
+    return 0;
 }
 
 /**
  * Handles an incoming ATT error response for the specified
  * find-included-services proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gattc_find_inc_svcs_err(struct ble_gattc_proc *proc, int status,
@@ -1546,9 +1395,6 @@ ble_gattc_find_inc_svcs_err(struct ble_gattc_proc *proc, int status,
 /**
  * Handles an incoming read-response for the specified find-included-services
  * proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_find_inc_svcs_rx_read_rsp(struct ble_gattc_proc *proc, int status,
@@ -1582,24 +1428,25 @@ ble_gattc_find_inc_svcs_rx_read_rsp(struct ble_gattc_proc *proc, int status,
     /* We are done with this service; proceed to the next. */
     proc->find_inc_svcs.cur_start = 0;
     proc->find_inc_svcs.cur_end = 0;
-    ble_gattc_proc_set_pending(proc);
+    rc = ble_gattc_find_inc_svcs_go(proc, 1);
+    if (rc != 0) {
+        goto done;
+    }
 
     rc = 0;
 
 done:
     cbrc = ble_gattc_find_inc_svcs_cb(proc, rc, 0, &service);
-    if (rc == 0) {
-        rc = cbrc;
+    if (rc != 0 || cbrc != 0) {
+        return BLE_HS_EDONE;
+    } else {
+        return 0;
     }
-    return rc;
 }
 
 /**
  * Handles an incoming "attribute data" entry from a read-by-type response for
  * the specified find-included-services proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_find_inc_svcs_rx_adata(struct ble_gattc_proc *proc,
@@ -1648,7 +1495,8 @@ ble_gattc_find_inc_svcs_rx_adata(struct ble_gattc_proc *proc,
         break;
 
     default:
-        return BLE_HS_EBADDATA;
+        rc = BLE_HS_EBADDATA;
+        goto done;
     }
 
     rc = 0;
@@ -1659,28 +1507,36 @@ done:
         if (rc != 0) {
             rc = cbrc;
         }
+    } else {
+        cbrc = 0;
     }
 
-    return rc;
+    if (rc != 0 || cbrc != 0) {
+        return BLE_HS_EDONE;
+    } else {
+        return 0;
+    }
 }
 
 /**
  * Handles a notification that a read-by-type response has been fully
  * processed for the specified find-included-services proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_find_inc_svcs_rx_complete(struct ble_gattc_proc *proc, int status)
 {
+    int rc;
+
     if (status != 0 || proc->find_inc_svcs.prev_handle == 0xffff) {
         /* Error or all svcs discovered. */
         ble_gattc_find_inc_svcs_cb(proc, status, 0, NULL);
-        return 1;
+        return BLE_HS_EDONE;
     } else {
         /* Send follow-up request. */
-        ble_gattc_proc_set_pending(proc);
+        rc = ble_gattc_find_inc_svcs_go(proc, 1);
+        if (rc != 0) {
+            return BLE_HS_EDONE;
+        }
         return 0;
     }
 }
@@ -1688,9 +1544,6 @@ ble_gattc_find_inc_svcs_rx_complete(struct ble_gattc_proc *proc, int status)
 /**
  * Initiates GATT procedure: Find Included Services.
  *
- * Lock restrictions:
- *     o Caller unlocks gattc.
- *
  * @param conn_handle           The connection over which to execute the
  *                                  procedure.
  * @param start_handle          The handle to begin the search at (generally
@@ -1715,23 +1568,25 @@ ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle,
 
     STATS_INC(ble_gattc_stats, find_inc_svcs);
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_FIND_INC_SVCS, &proc);
-    if (rc == 0) {
-        proc->find_inc_svcs.prev_handle = start_handle - 1;
-        proc->find_inc_svcs.end_handle = end_handle;
-        proc->find_inc_svcs.cb = cb;
-        proc->find_inc_svcs.cb_arg = cb_arg;
-
-        BLE_HS_LOG(INFO, "GATT procedure initiated: find included services; ");
-        ble_gattc_log_find_inc_svcs(proc);
-        BLE_HS_LOG(INFO, "\n");
-
-        ble_gattc_proc_set_pending(proc);
-    } else {
+    proc = ble_gattc_proc_alloc();
+    if (proc == NULL) {
         STATS_INC(ble_gattc_stats, find_inc_svcs_fail);
+        return BLE_HS_ENOMEM;
     }
 
-    return rc;
+    proc->op = BLE_GATT_OP_FIND_INC_SVCS;
+    proc->conn_handle = conn_handle;
+    proc->find_inc_svcs.prev_handle = start_handle - 1;
+    proc->find_inc_svcs.end_handle = end_handle;
+    proc->find_inc_svcs.cb = cb;
+    proc->find_inc_svcs.cb_arg = cb_arg;
+
+    ble_gattc_log_find_inc_svcs(proc);
+
+    rc = ble_gattc_find_inc_svcs_go(proc, 0);
+    ble_gattc_process_status(proc, rc);
+
+    return 0;
 }
 
 /*****************************************************************************
@@ -1742,9 +1597,6 @@ ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle,
  * Calls a discover-all-characteristics proc's callback with the specified
  * parameters.  If the proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -1754,7 +1606,7 @@ ble_gattc_disc_all_chrs_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_chrs_fail);
@@ -1763,7 +1615,7 @@ ble_gattc_disc_all_chrs_cb(struct ble_gattc_proc *proc, int status,
     if (proc->disc_all_chrs.cb == NULL) {
         rc = 0;
     } else {
-        rc = proc->disc_all_chrs.cb(proc->fsm_proc.conn_handle,
+        rc = proc->disc_all_chrs.cb(proc->conn_handle,
                                     ble_gattc_error(status, att_handle), chr,
                                     proc->disc_all_chrs.cb_arg);
     }
@@ -1774,12 +1626,9 @@ ble_gattc_disc_all_chrs_cb(struct ble_gattc_proc *proc, int status,
 /**
  * Triggers a pending transmit for the specified discover-all-characteristics
  * proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
-ble_gattc_disc_all_chrs_kick(struct ble_gattc_proc *proc)
+ble_gattc_disc_all_chrs_go(struct ble_gattc_proc *proc, int cb_on_err)
 {
     struct ble_att_read_type_req req;
     uint8_t uuid128[16];
@@ -1791,26 +1640,21 @@ ble_gattc_disc_all_chrs_kick(struct ble_gattc_proc *proc)
     req.batq_start_handle = proc->disc_all_chrs.prev_handle + 1;
     req.batq_end_handle = proc->disc_all_chrs.end_handle;
 
-    rc = ble_att_clt_tx_read_type(proc->fsm_proc.conn_handle, &req, uuid128);
+    rc = ble_att_clt_tx_read_type(proc->conn_handle, &req, uuid128);
 
     if (rc != 0) {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            rc = BLE_HS_EAGAIN;
-        } else {
+        if (cb_on_err) {
             ble_gattc_disc_all_chrs_cb(proc, rc, 0, NULL);
-            rc = BLE_HS_EDONE;
         }
+        return rc;
     }
 
-    return rc;
+    return 0;
 }
 
 /**
  * Handles an incoming ATT error response for the specified
  * discover-all-characteristics proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gattc_disc_all_chrs_err(struct ble_gattc_proc *proc, int status,
@@ -1827,9 +1671,6 @@ ble_gattc_disc_all_chrs_err(struct ble_gattc_proc *proc, int status,
 /**
  * Handles an incoming "attribute data" entry from a read-by-type response for
  * the specified discover-all-characteristics proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_all_chrs_rx_adata(struct ble_gattc_proc *proc,
@@ -1876,32 +1717,34 @@ ble_gattc_disc_all_chrs_rx_adata(struct ble_gattc_proc *proc,
 
 done:
     cbrc = ble_gattc_disc_all_chrs_cb(proc, rc, 0, &chr);
-    if (rc == 0) {
-        rc = cbrc;
+    if (rc != 0 || cbrc != 0) {
+        return BLE_HS_EDONE;
+    } else {
+        return 0;
     }
-
-    return rc;
 }
 
 /**
  * Handles a notification that a read-by-type response has been fully
  * processed for the specified discover-all-characteristics proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_all_chrs_rx_complete(struct ble_gattc_proc *proc, int status)
 {
+    int rc;
+
     if (status != 0 ||
         proc->disc_all_chrs.prev_handle == proc->disc_all_chrs.end_handle) {
 
         /* Error or all svcs discovered. */
         ble_gattc_disc_all_chrs_cb(proc, status, 0, NULL);
-        return 1;
+        return BLE_HS_EDONE;
     } else {
         /* Send follow-up request. */
-        ble_gattc_proc_set_pending(proc);
+        rc = ble_gattc_disc_all_chrs_go(proc, 1);
+        if (rc != 0) {
+            return BLE_HS_EDONE;
+        }
         return 0;
     }
 }
@@ -1909,9 +1752,6 @@ ble_gattc_disc_all_chrs_rx_complete(struct ble_gattc_proc *proc, int status)
 /**
  * Initiates GATT procedure: Discover All Characteristics of a Service.
  *
- * Lock restrictions:
- *     o Caller unlocks gattc.
- *
  * @param conn_handle           The connection over which to execute the
  *                                  procedure.
  * @param start_handle          The handle to begin the search at (generally
@@ -1936,24 +1776,25 @@ ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle,
 
     STATS_INC(ble_gattc_stats, disc_all_chrs);
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_ALL_CHRS, &proc);
-    if (rc == 0) {
-        proc->disc_all_chrs.prev_handle = start_handle - 1;
-        proc->disc_all_chrs.end_handle = end_handle;
-        proc->disc_all_chrs.cb = cb;
-        proc->disc_all_chrs.cb_arg = cb_arg;
-
-        BLE_HS_LOG(INFO, "GATT procedure initiated: discover all "
-                         "characteristics; ");
-        ble_gattc_log_disc_all_chrs(proc);
-        BLE_HS_LOG(INFO, "\n");
-
-        ble_gattc_proc_set_pending(proc);
-    } else {
+    proc = ble_gattc_proc_alloc();
+    if (proc == NULL) {
         STATS_INC(ble_gattc_stats, disc_all_chrs_fail);
+        return BLE_HS_ENOMEM;
     }
 
-    return rc;
+    proc->op = BLE_GATT_OP_DISC_ALL_CHRS;
+    proc->conn_handle = conn_handle;
+    proc->disc_all_chrs.prev_handle = start_handle - 1;
+    proc->disc_all_chrs.end_handle = end_handle;
+    proc->disc_all_chrs.cb = cb;
+    proc->disc_all_chrs.cb_arg = cb_arg;
+
+    ble_gattc_log_disc_all_chrs(proc);
+
+    rc = ble_gattc_disc_all_chrs_go(proc, 0);
+    ble_gattc_process_status(proc, rc);
+
+    return 0;
 }
 
 /*****************************************************************************
@@ -1964,9 +1805,6 @@ ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle,
  * Calls a discover-characteristic-by-uuid proc's callback with the specified
  * parameters.  If the proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -1980,12 +1818,12 @@ ble_gattc_disc_chr_uuid_cb(struct ble_gattc_proc *proc, int status,
         STATS_INC(ble_gattc_stats, disc_chrs_uuid_fail);
     }
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (proc->disc_chr_uuid.cb == NULL) {
         rc = 0;
     } else {
-        rc = proc->disc_chr_uuid.cb(proc->fsm_proc.conn_handle,
+        rc = proc->disc_chr_uuid.cb(proc->conn_handle,
                                     ble_gattc_error(status, att_handle), chr,
                                     proc->disc_chr_uuid.cb_arg);
     }
@@ -1996,12 +1834,9 @@ ble_gattc_disc_chr_uuid_cb(struct ble_gattc_proc *proc, int status,
 /**
  * Triggers a pending transmit for the specified
  * discover-characteristic-by-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
-ble_gattc_disc_chr_uuid_kick(struct ble_gattc_proc *proc)
+ble_gattc_disc_chr_uuid_go(struct ble_gattc_proc *proc, int cb_on_err)
 {
     struct ble_att_read_type_req req;
     uint8_t uuid128[16];
@@ -2013,26 +1848,21 @@ ble_gattc_disc_chr_uuid_kick(struct ble_gattc_proc *proc)
     req.batq_start_handle = proc->disc_chr_uuid.prev_handle + 1;
     req.batq_end_handle = proc->disc_chr_uuid.end_handle;
 
-    rc = ble_att_clt_tx_read_type(proc->fsm_proc.conn_handle, &req, uuid128);
+    rc = ble_att_clt_tx_read_type(proc->conn_handle, &req, uuid128);
 
     if (rc != 0) {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            rc = BLE_HS_EAGAIN;
-        } else {
+        if (cb_on_err) {
             ble_gattc_disc_chr_uuid_cb(proc, rc, 0, NULL);
-            rc = BLE_HS_EDONE;
         }
+        return rc;
     }
 
-    return rc;
+    return 0;
 }
 
 /**
  * Handles an incoming ATT error response for the specified
  * discover-characteristic-by-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gattc_disc_chr_uuid_err(struct ble_gattc_proc *proc, int status,
@@ -2049,9 +1879,6 @@ ble_gattc_disc_chr_uuid_err(struct ble_gattc_proc *proc, int status,
 /**
  * Handles an incoming "attribute data" entry from a read-by-type response for
  * the specified discover-characteristics-by-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_chr_uuid_rx_adata(struct ble_gattc_proc *proc,
@@ -2102,33 +1929,38 @@ done:
         memcmp(chr.uuid128, proc->disc_chr_uuid.chr_uuid, 16) == 0) {
 
         cbrc = ble_gattc_disc_chr_uuid_cb(proc, rc, 0, &chr);
-        if (rc == 0) {
-            rc = cbrc;
-        }
+    } else {
+        cbrc = 0;
     }
 
-    return rc;
+    if (rc != 0 || cbrc != 0) {
+        return BLE_HS_EDONE;
+    } else {
+        return 0;
+    }
 }
 
 /**
  * Handles a notification that a read-by-type response has been fully
  * processed for the specified discover-characteristics-by-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_chr_uuid_rx_complete(struct ble_gattc_proc *proc, int status)
 {
+    int rc;
+
     if (status != 0 ||
         proc->disc_chr_uuid.prev_handle == proc->disc_chr_uuid.end_handle) {
 
         /* Error or all svcs discovered. */
         ble_gattc_disc_chr_uuid_cb(proc, status, 0, NULL);
-        return 1;
+        return BLE_HS_EDONE;
     } else {
         /* Send follow-up request. */
-        ble_gattc_proc_set_pending(proc);
+        rc = ble_gattc_disc_chr_uuid_go(proc, 1);
+        if (rc != 0) {
+            return BLE_HS_EDONE;
+        }
         return 0;
     }
 }
@@ -2136,9 +1968,6 @@ ble_gattc_disc_chr_uuid_rx_complete(struct ble_gattc_proc *proc, int status)
 /**
  * Initiates GATT procedure: Discover Characteristics by UUID.
  *
- * Lock restrictions:
- *     o Caller unlocks gattc.
- *
  * @param conn_handle           The connection over which to execute the
  *                                  procedure.
  * @param start_handle          The handle to begin the search at (generally
@@ -2165,25 +1994,26 @@ ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle,
 
     STATS_INC(ble_gattc_stats, disc_chrs_uuid);
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_CHR_UUID, &proc);
-    if (rc == 0) {
-        memcpy(proc->disc_chr_uuid.chr_uuid, uuid128, 16);
-        proc->disc_chr_uuid.prev_handle = start_handle - 1;
-        proc->disc_chr_uuid.end_handle = end_handle;
-        proc->disc_chr_uuid.cb = cb;
-        proc->disc_chr_uuid.cb_arg = cb_arg;
-
-        BLE_HS_LOG(INFO, "GATT procedure initiated: discover characteristics "
-                         "by uuid; ");
-        ble_gattc_log_disc_chr_uuid(proc);
-        BLE_HS_LOG(INFO, "\n");
-
-        ble_gattc_proc_set_pending(proc);
-    } else {
+    proc = ble_gattc_proc_alloc();
+    if (proc == NULL) {
         STATS_INC(ble_gattc_stats, disc_chrs_uuid_fail);
+        return BLE_HS_ENOMEM;
     }
 
-    return rc;
+    proc->op = BLE_GATT_OP_DISC_CHR_UUID;
+    proc->conn_handle = conn_handle;
+    memcpy(proc->disc_chr_uuid.chr_uuid, uuid128, 16);
+    proc->disc_chr_uuid.prev_handle = start_handle - 1;
+    proc->disc_chr_uuid.end_handle = end_handle;
+    proc->disc_chr_uuid.cb = cb;
+    proc->disc_chr_uuid.cb_arg = cb_arg;
+
+    ble_gattc_log_disc_chr_uuid(proc);
+
+    rc = ble_gattc_disc_chr_uuid_go(proc, 0);
+    ble_gattc_process_status(proc, rc);
+
+    return 0;
 }
 
 /*****************************************************************************
@@ -2194,9 +2024,6 @@ ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle,
  * Calls a discover-all-descriptors proc's callback with the specified
  * parameters.  If the proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -2210,12 +2037,12 @@ ble_gattc_disc_all_dscs_cb(struct ble_gattc_proc *proc, int status,
         STATS_INC(ble_gattc_stats, disc_all_dscs_fail);
     }
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (proc->disc_all_dscs.cb == NULL) {
         rc = 0;
     } else {
-        rc = proc->disc_all_dscs.cb(proc->fsm_proc.conn_handle,
+        rc = proc->disc_all_dscs.cb(proc->conn_handle,
                                     ble_gattc_error(status, att_handle),
                                     proc->disc_all_dscs.chr_def_handle,
                                     dsc, proc->disc_all_dscs.cb_arg);
@@ -2226,12 +2053,9 @@ ble_gattc_disc_all_dscs_cb(struct ble_gattc_proc *proc, int status,
 
 /**
  * Triggers a pending transmit for the specified discover-all-descriptors proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
-ble_gattc_disc_all_dscs_kick(struct ble_gattc_proc *proc)
+ble_gattc_disc_all_dscs_go(struct ble_gattc_proc *proc, int cb_on_err)
 {
     struct ble_att_find_info_req req;
     int rc;
@@ -2239,25 +2063,20 @@ ble_gattc_disc_all_dscs_kick(struct ble_gattc_proc *proc)
     req.bafq_start_handle = proc->disc_all_dscs.prev_handle + 1;
     req.bafq_end_handle = proc->disc_all_dscs.end_handle;
 
-    rc = ble_att_clt_tx_find_info(proc->fsm_proc.conn_handle, &req);
+    rc = ble_att_clt_tx_find_info(proc->conn_handle, &req);
     if (rc != 0) {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            rc = BLE_HS_EAGAIN;
-        } else {
+        if (cb_on_err) {
             ble_gattc_disc_all_dscs_cb(proc, rc, 0, NULL);
-            rc = BLE_HS_EDONE;
         }
+        return rc;
     }
 
-    return rc;
+    return 0;
 }
 
 /**
  * Handles an incoming ATT error response for the specified
  * discover-all-descriptors proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gattc_disc_all_dscs_err(struct ble_gattc_proc *proc, int status,
@@ -2274,9 +2093,6 @@ ble_gattc_disc_all_dscs_err(struct ble_gattc_proc *proc, int status,
 /**
  * Handles an incoming "information data" entry from a find-information
  * response for the specified discover-all-descriptors proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_all_dscs_rx_idata(struct ble_gattc_proc *proc,
@@ -2300,31 +2116,34 @@ done:
     memcpy(dsc.uuid128, idata->uuid128, 16);
 
     cbrc = ble_gattc_disc_all_dscs_cb(proc, rc, 0, &dsc);
-    if (rc == 0) {
-        rc = cbrc;
+    if (rc != 0 || cbrc != 0) {
+        return BLE_HS_EDONE;
+    } else {
+        return 0;
     }
-    return rc;
 }
 
 /**
  * Handles a notification that a find-information response has been fully
  * processed for the specified discover-all-descriptors proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_disc_all_dscs_rx_complete(struct ble_gattc_proc *proc, int status)
 {
+    int rc;
+
     if (status != 0 ||
         proc->disc_all_dscs.prev_handle == proc->disc_all_dscs.end_handle) {
 
         /* Error or all descriptors discovered. */
         ble_gattc_disc_all_dscs_cb(proc, status, 0, NULL);
-        return 1;
+        return BLE_HS_EDONE;
     } else {
         /* Send follow-up request. */
-        ble_gattc_proc_set_pending(proc);
+        rc = ble_gattc_disc_all_dscs_go(proc, 1);
+        if (rc != 0) {
+            return BLE_HS_EDONE;
+        }
         return 0;
     }
 }
@@ -2332,9 +2151,6 @@ ble_gattc_disc_all_dscs_rx_complete(struct ble_gattc_proc *proc, int status)
 /**
  * Initiates GATT procedure: Discover All Characteristic Descriptors.
  *
- * Lock restrictions:
- *     o Caller unlocks gattc.
- *
  * @param conn_handle           The connection over which to execute the
  *                                  procedure.
  * @param chr_def_handle        The handle of the characteristic definition
@@ -2359,25 +2175,26 @@ ble_gattc_disc_all_dscs(uint16_t conn_handle, uint16_t chr_def_handle,
 
     STATS_INC(ble_gattc_stats, disc_all_dscs);
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_DISC_ALL_DSCS, &proc);
-    if (rc == 0) {
-        proc->disc_all_dscs.chr_def_handle = chr_def_handle;
-        proc->disc_all_dscs.prev_handle = chr_def_handle + 1;
-        proc->disc_all_dscs.end_handle = chr_end_handle;
-        proc->disc_all_dscs.cb = cb;
-        proc->disc_all_dscs.cb_arg = cb_arg;
-
-        BLE_HS_LOG(INFO, "GATT procedure initiated: discover all "
-                         "descriptors; ");
-        ble_gattc_log_disc_all_dscs(proc);
-        BLE_HS_LOG(INFO, "\n");
-
-        ble_gattc_proc_set_pending(proc);
-    } else {
+    proc = ble_gattc_proc_alloc();
+    if (proc == NULL) {
         STATS_INC(ble_gattc_stats, disc_all_dscs_fail);
+        return BLE_HS_ENOMEM;
     }
 
-    return rc;
+    proc->op = BLE_GATT_OP_DISC_ALL_DSCS;
+    proc->conn_handle = conn_handle;
+    proc->disc_all_dscs.chr_def_handle = chr_def_handle;
+    proc->disc_all_dscs.prev_handle = chr_def_handle + 1;
+    proc->disc_all_dscs.end_handle = chr_end_handle;
+    proc->disc_all_dscs.cb = cb;
+    proc->disc_all_dscs.cb_arg = cb_arg;
+
+    ble_gattc_log_disc_all_dscs(proc);
+
+    rc = ble_gattc_disc_all_dscs_go(proc, 0);
+    ble_gattc_process_status(proc, rc);
+
+    return 0;
 }
 
 /*****************************************************************************
@@ -2388,9 +2205,6 @@ ble_gattc_disc_all_dscs(uint16_t conn_handle, uint16_t chr_def_handle,
  * Calls a read-characteristic proc's callback with the specified parameters.
  * If the proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -2400,7 +2214,7 @@ ble_gattc_read_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_fail);
@@ -2409,7 +2223,7 @@ ble_gattc_read_cb(struct ble_gattc_proc *proc, int status,
     if (proc->read.cb == NULL) {
         rc = 0;
     } else {
-        rc = proc->read.cb(proc->fsm_proc.conn_handle,
+        rc = proc->read.cb(proc->conn_handle,
                            ble_gattc_error(status, att_handle), attr,
                            proc->read.cb_arg);
     }
@@ -2418,38 +2232,8 @@ ble_gattc_read_cb(struct ble_gattc_proc *proc, int status,
 }
 
 /**
- * Triggers a pending transmit for the specified read-characteristic-value
- * proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-static int
-ble_gattc_read_kick(struct ble_gattc_proc *proc)
-{
-    struct ble_att_read_req req;
-    int rc;
-
-    req.barq_handle = proc->read.handle;
-    rc = ble_att_clt_tx_read(proc->fsm_proc.conn_handle, &req);
-    if (rc != 0) {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            rc = BLE_HS_EAGAIN;
-        } else {
-            ble_gattc_read_cb(proc, rc, 0, NULL);
-            rc = BLE_HS_EDONE;
-        }
-    }
-
-    return rc;
-}
-
-/**
  * Handles an incoming ATT error response for the specified
  * read-characteristic-value proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gattc_read_err(struct ble_gattc_proc *proc, int status,
@@ -2461,9 +2245,6 @@ ble_gattc_read_err(struct ble_gattc_proc *proc, int status,
 /**
  * Handles an incoming read-response for the specified
  * read-characteristic-value proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_read_rx_read_rsp(struct ble_gattc_proc *proc, int status,
@@ -2479,15 +2260,12 @@ ble_gattc_read_rx_read_rsp(struct ble_gattc_proc *proc, int status,
     ble_gattc_read_cb(proc, status, 0, &attr);
 
     /* The read operation only has a single request / response exchange. */
-    return 1;
+    return BLE_HS_EDONE;
 }
 
 /**
  * Initiates GATT procedure: Read Characteristic Value.
  *
- * Lock restrictions:
- *     o Caller unlocks gattc.
- *
  * @param conn_handle           The connection over which to execute the
  *                                  procedure.
  * @param attr_handle           The handle of the characteristic value to read.
@@ -2504,25 +2282,38 @@ ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle,
 #endif
 
     struct ble_gattc_proc *proc;
+    struct ble_att_read_req req;
     int rc;
 
     STATS_INC(ble_gattc_stats, read);
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_READ, &proc);
-    if (rc == 0) {
-        proc->read.handle = attr_handle;
-        proc->read.cb = cb;
-        proc->read.cb_arg = cb_arg;
+    proc = ble_gattc_proc_alloc();
+    if (proc == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
 
-        BLE_HS_LOG(INFO, "GATT procedure initiated: read; ");
-        ble_gattc_log_read(proc);
-        BLE_HS_LOG(INFO, "\n");
+    proc->op = BLE_GATT_OP_READ;
+    proc->conn_handle = conn_handle;
+    proc->read.handle = attr_handle;
+    proc->read.cb = cb;
+    proc->read.cb_arg = cb_arg;
 
-        ble_gattc_proc_set_pending(proc);
-    } else {
-        STATS_INC(ble_gattc_stats, read_fail);
+    ble_gattc_log_read(attr_handle);
+
+    req.barq_handle = attr_handle;
+    rc = ble_att_clt_tx_read(proc->conn_handle, &req);
+    if (rc != 0) {
+        goto err;
     }
 
+    ble_gattc_proc_insert(proc);
+
+    return 0;
+
+err:
+    STATS_INC(ble_gattc_stats, read_fail);
+    ble_gattc_proc_free((void *)proc);
     return rc;
 }
 
@@ -2534,9 +2325,6 @@ ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle,
  * Calls a read-using-characteristic-uuid proc's callback with the specified
  * parameters.  If the proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -2546,7 +2334,7 @@ ble_gattc_read_uuid_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_uuid_fail);
@@ -2555,39 +2343,9 @@ ble_gattc_read_uuid_cb(struct ble_gattc_proc *proc, int status,
     if (proc->read_uuid.cb == NULL) {
         rc = 0;
     } else {
-        rc = proc->read_uuid.cb(proc->fsm_proc.conn_handle,
-                                 ble_gattc_error(status, att_handle), attr,
-                                 proc->read_uuid.cb_arg);
-    }
-
-    return rc;
-}
-
-/**
- * Triggers a pending transmit for the specified read-using-characteristic-uuid
- * proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-static int
-ble_gattc_read_uuid_kick(struct ble_gattc_proc *proc)
-{
-    struct ble_att_read_type_req req;
-    int rc;
-
-    req.batq_start_handle = proc->read_uuid.prev_handle + 1;
-    req.batq_end_handle = proc->read_uuid.end_handle;
-    rc = ble_att_clt_tx_read_type(proc->fsm_proc.conn_handle, &req,
-                                  proc->read_uuid.uuid128);
-
-    if (rc != 0) {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            rc = BLE_HS_EAGAIN;
-        } else {
-            ble_gattc_read_uuid_cb(proc, rc, 0, NULL);
-            rc = BLE_HS_EDONE;
-        }
+        rc = proc->read_uuid.cb(proc->conn_handle,
+                                ble_gattc_error(status, att_handle), attr,
+                                proc->read_uuid.cb_arg);
     }
 
     return rc;
@@ -2596,9 +2354,6 @@ ble_gattc_read_uuid_kick(struct ble_gattc_proc *proc)
 /**
  * Handles an incoming ATT error response for the specified
  * read-using-characteristic-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gattc_read_uuid_err(struct ble_gattc_proc *proc, int status,
@@ -2614,9 +2369,6 @@ ble_gattc_read_uuid_err(struct ble_gattc_proc *proc, int status,
 /**
  * Handles an incoming "attribute data" entry from a read-by-type response for
  * the specified read-using-characteristic-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_read_uuid_rx_adata(struct ble_gattc_proc *proc,
@@ -2632,43 +2384,26 @@ ble_gattc_read_uuid_rx_adata(struct ble_gattc_proc *proc,
 
     rc = ble_gattc_read_uuid_cb(proc, 0, 0, &attr);
     if (rc != 0) {
-        return rc;
+        return BLE_HS_EDONE;
     }
 
-    proc->read_uuid.prev_handle = adata->att_handle;
-
     return 0;
 }
 
 /**
  * Handles a notification that a read-by-type response has been fully
  * processed for the specified read-using-characteristic-uuid proc.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static int
 ble_gattc_read_uuid_rx_complete(struct ble_gattc_proc *proc, int status)
 {
-    if (status != 0 ||
-        proc->read_uuid.prev_handle == proc->read_uuid.end_handle) {
-
-        /* Error or entire range read. */
-        ble_gattc_read_uuid_cb(proc, status, 0, NULL);
-        return 1;
-    } else {
-        /* Send follow-up request. */
-        ble_gattc_proc_set_pending(proc);
-        return 0;
-    }
+    ble_gattc_read_uuid_cb(proc, status, 0, NULL);
+    return BLE_HS_EDONE;
 }
 
 /**
  * Initiates GATT procedure: Read Using Characteristic UUID.
  *
- * Lock restrictions:
- *     o Caller unlocks gattc.
- *
  * @param conn_handle           The connection over which to execute the
  *                                  procedure.
  * @param start_handle          The first handle to search (generally the
@@ -2688,28 +2423,39 @@ ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle,
     return BLE_HS_ENOTSUP;
 #endif
 
+    struct ble_att_read_type_req req;
     struct ble_gattc_proc *proc;
     int rc;
 
     STATS_INC(ble_gattc_stats, read_uuid);
 
-    rc = ble_gattc_new_proc(conn_handle, BLE_GATT_OP_READ_UUID, &proc);
-    if (rc == 0) {
-        proc->read_uuid.prev_handle = start_handle - 1;
-        proc->read_uuid.end_handle = end_handle;
-        memcpy(proc->read_uuid.uuid128, uuid128, 16);
-        proc->read_uuid.cb = cb;
-        proc->read_uuid.cb_arg = cb_arg;
+    proc = ble_gattc_proc_alloc();
+    if (proc == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
 
-        BLE_HS_LOG(INFO, "GATT procedure initiated: read by uuid; ");
-        ble_gattc_log_read_uuid(proc);
-        BLE_HS_LOG(INFO, "\n");
+    proc->op = BLE_GATT_OP_READ_UUID;
+    proc->conn_handle = conn_handle;
+    proc->read_uuid.cb = cb;
+    proc->read_uuid.cb_arg = cb_arg;
 
-        ble_gattc_proc_set_pending(proc);
-    } else {
-        STATS_INC(ble_gattc_stats, read_uuid_fail);
+    ble_gattc_log_read_uuid(start_handle, end_handle, uuid128);
+
+    req.batq_start_handle = start_handle;
+    req.batq_end_handle = end_handle;
+    rc = ble_att_clt_tx_read_type(conn_handle, &req, uuid128);
+    if (rc != 0) {
+        goto err;
     }
 
+    ble_gattc_proc_insert(proc);
+
+    return 0;
+
+err:
+    STATS_INC(ble_gattc_stats, read_uuid_fail);
+    ble_gattc_proc_free((void *)proc);
     return rc;
 }
 
@@ -2721,9 +2467,6 @@ ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle,
  * Calls a read-long-characteristic proc's callback with the specified
  * parameters.  If the proc has no callback, this function is a no-op.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      The return code of the callback (or 0 if there
  *                                  is no callback).
  */
@@ -2733,7 +2476,7 @@ ble_gattc_read_long_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_long_fail);
@@ -2742,7 +2485,7 @@ ble_gattc_read_long_cb(struct ble_g

<TRUNCATED>


[07/50] [abbrv] incubator-mynewt-core git commit: os sim; deal with system time going backwards

Posted by ma...@apache.org.
os sim; deal with system time going backwards


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

Branch: refs/heads/master
Commit: f6bc99f0a1d9d1daa1c8e35d171075f2f2129548
Parents: 1a6f234
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Tue Apr 19 16:56:45 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Tue Apr 19 16:56:45 2016 -0700

----------------------------------------------------------------------
 libs/os/src/arch/sim/os_arch_sim.c | 55 +++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f6bc99f0/libs/os/src/arch/sim/os_arch_sim.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/sim/os_arch_sim.c b/libs/os/src/arch/sim/os_arch_sim.c
index 7a3b27d..1d43ab2 100644
--- a/libs/os/src/arch/sim/os_arch_sim.c
+++ b/libs/os/src/arch/sim/os_arch_sim.c
@@ -6,7 +6,7 @@
  * 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,
@@ -30,7 +30,7 @@
 #include <setjmp.h>
 #include <signal.h>
 #include <sys/time.h>
-#include <assert.h> 
+#include <assert.h>
 #include <util/util.h>
 
 struct stack_frame {
@@ -49,7 +49,7 @@ CTASSERT(offsetof(struct stack_frame, sf_jb) == 4);
 extern void os_arch_frame_init(struct stack_frame *sf);
 
 #define sim_setjmp(__jb) sigsetjmp(__jb, 0)
-#define sim_longjmp(__jb, __ret) siglongjmp(__jb, __ret) 
+#define sim_longjmp(__jb, __ret) siglongjmp(__jb, __ret)
 
 #define OS_USEC_PER_TICK    (1000000 / OS_TICKS_PER_SEC)
 
@@ -79,12 +79,12 @@ os_arch_task_start(struct stack_frame *sf, int rc)
     task = sf->sf_task;
     task->t_func(task->t_arg);
 
-    /* This should never return */ 
-    assert(0); 
+    /* This should never return */
+    assert(0);
 }
 
 os_stack_t *
-os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size) 
+os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
 {
     struct stack_frame *sf;
 
@@ -146,7 +146,7 @@ ctxsw_handler(int sig)
  *
  * Returns 1 if signals were already blocked and 0 otherwise.
  */
-os_sr_t 
+os_sr_t
 os_arch_save_sr(void)
 {
     int error;
@@ -293,11 +293,11 @@ signals_cleanup(void)
 static void
 timer_handler(int sig)
 {
-    struct timeval time_now, time_diff; 
+    struct timeval time_now, time_diff;
     int ticks;
 
     static struct timeval time_last;
-    static int time_inited; 
+    static int time_inited;
 
     if (!time_inited) {
         gettimeofday(&time_last, NULL);
@@ -305,26 +305,33 @@ timer_handler(int sig)
     }
 
     gettimeofday(&time_now, NULL);
-    timersub(&time_now, &time_last, &time_diff);
+    if (timercmp(&time_now, &time_last, <)) {
+        /*
+         * System time going backwards.
+         */
+        time_last = time_now;
+    } else {
+        timersub(&time_now, &time_last, &time_diff);
 
-    ticks = time_diff.tv_sec * OS_TICKS_PER_SEC;
-    ticks += time_diff.tv_usec / OS_USEC_PER_TICK;
+        ticks = time_diff.tv_sec * OS_TICKS_PER_SEC;
+        ticks += time_diff.tv_usec / OS_USEC_PER_TICK;
 
-    /*
-     * Update 'time_last' but account for the remainder usecs that did not
-     * contribute towards whole 'ticks'.
-     */
-    time_diff.tv_sec = 0;
-    time_diff.tv_usec %= OS_USEC_PER_TICK;
-    timersub(&time_now, &time_diff, &time_last);
+        /*
+         * Update 'time_last' but account for the remainder usecs that did not
+         * contribute towards whole 'ticks'.
+         */
+        time_diff.tv_sec = 0;
+        time_diff.tv_usec %= OS_USEC_PER_TICK;
+        timersub(&time_now, &time_diff, &time_last);
 
-    os_time_advance(ticks);
+        os_time_advance(ticks);
+    }
 }
 
 static void
 start_timer(void)
 {
-    struct itimerval it; 
+    struct itimerval it;
     int rc;
 
     memset(&it, 0, sizeof(it));
@@ -349,7 +356,7 @@ stop_timer(void)
     assert(rc == 0);
 }
 
-os_error_t 
+os_error_t
 os_arch_os_init(void)
 {
     mypid = getpid();
@@ -378,7 +385,7 @@ os_arch_os_init(void)
 os_error_t
 os_arch_os_start(void)
 {
-    struct stack_frame *sf; 
+    struct stack_frame *sf;
     struct os_task *t;
     os_sr_t sr;
 
@@ -395,7 +402,7 @@ os_arch_os_start(void)
     t = os_sched_next_task();
     os_sched_set_current_task(t);
 
-    g_os_started = 1; 
+    g_os_started = 1;
 
     sf = (struct stack_frame *) t->t_stackptr;
     sim_longjmp(sf->sf_jb, 1);


[04/50] [abbrv] incubator-mynewt-core git commit: nffs - blocks were missing from end of files.

Posted by ma...@apache.org.
nffs - blocks were missing from end of files.

There was a bug in how nffs determines which block comes last in a file
inode.  This process is still horribly inefficient (MYNEWT-161), but it
should at least work now.


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

Branch: refs/heads/master
Commit: 3abe7404b76f6025483486a64646f02acdca24b8
Parents: 27605cb
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Apr 18 20:09:26 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Apr 19 14:32:22 2016 -0700

----------------------------------------------------------------------
 fs/nffs/src/nffs_restore.c | 132 +++++++++++++++++++++++-----------------
 1 file changed, 76 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3abe7404/fs/nffs/src/nffs_restore.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_restore.c b/fs/nffs/src/nffs_restore.c
index 947a359..8f9c9f8 100644
--- a/fs/nffs/src/nffs_restore.c
+++ b/fs/nffs/src/nffs_restore.c
@@ -218,6 +218,76 @@ nffs_restore_inode_from_dummy_entry(struct nffs_inode *out_inode,
     out_inode->ni_inode_entry = inode_entry;
 }
 
+static int
+nffs_restore_find_file_end_block(struct nffs_hash_entry *block_entry)
+{
+    struct nffs_inode_entry *inode_entry;
+    struct nffs_block block;
+    int rc;
+
+    rc = nffs_block_from_hash_entry(&block, block_entry);
+    assert(rc == 0);
+
+    inode_entry = block.nb_inode_entry;
+
+    /* Make sure the parent inode (file) points to the latest data block
+     * restored so far.
+     *
+     * XXX: This is an O(n) operation (n = # of blocks in the file), and is
+     * horribly inefficient for large files.  MYNEWT-161 has been opened to
+     * address this.
+     */
+    if (inode_entry->nie_last_block_entry == NULL) {
+        /* This is the first data block restored for this file. */
+        inode_entry->nie_last_block_entry = block_entry;
+        NFFS_LOG(DEBUG, "setting last block: %u\n", block_entry->nhe_id);
+    } else {
+        /* Determine if this this data block comes after our current idea of
+         * the file's last data block.
+         */
+
+        rc = nffs_block_find_predecessor(
+            block_entry, inode_entry->nie_last_block_entry->nhe_id);
+        switch (rc) {
+        case 0:
+            /* The currently-last block is a predecessor of the new block; the
+             * new block comes later.
+             */
+            NFFS_LOG(DEBUG, "replacing last block: %u --> %u\n",
+                     inode_entry->nie_last_block_entry->nhe_id,
+                     block_entry->nhe_id);
+            inode_entry->nie_last_block_entry = block_entry;
+            break;
+
+        case FS_ENOENT:
+            break;
+
+        default:
+            return rc;
+        }
+    }
+
+    return 0;
+}
+
+
+static int
+nffs_restore_find_file_ends(void)
+{
+    struct nffs_hash_entry *block_entry;
+    int rc;
+    int i;
+
+    NFFS_HASH_FOREACH(block_entry, i) {
+        if (!nffs_hash_id_is_inode(block_entry->nhe_id)) {
+            rc = nffs_restore_find_file_end_block(block_entry);
+            assert(rc == 0);
+        }
+    }
+
+    return 0;
+}
+
 /**
  * Performs a sweep of the RAM representation at the end of a successful
  * restore.  The sweep phase performs the following actions of each inode in
@@ -483,13 +553,13 @@ nffs_restore_inode(const struct nffs_disk_inode *disk_inode, uint8_t area_idx,
     }
 
     if (nffs_hash_id_is_file(inode_entry->nie_hash_entry.nhe_id)) {
-        NFFS_LOG(DEBUG, "restoring file; id=%d\n",
+        NFFS_LOG(DEBUG, "restoring file; id=0x%08x\n",
                  inode_entry->nie_hash_entry.nhe_id);
         if (inode_entry->nie_hash_entry.nhe_id >= nffs_hash_next_file_id) {
             nffs_hash_next_file_id = inode_entry->nie_hash_entry.nhe_id + 1;
         }
     } else {
-        NFFS_LOG(DEBUG, "restoring dir; id=%d\n",
+        NFFS_LOG(DEBUG, "restoring dir; id=0x%08x\n",
                  inode_entry->nie_hash_entry.nhe_id);
         if (inode_entry->nie_hash_entry.nhe_id >= nffs_hash_next_dir_id) {
             nffs_hash_next_dir_id = inode_entry->nie_hash_entry.nhe_id + 1;
@@ -619,7 +689,7 @@ nffs_restore_block(const struct nffs_disk_block *disk_block, uint8_t area_idx,
         nffs_restore_largest_block_data_len = disk_block->ndb_data_len;
     }
 
-    NFFS_LOG(DEBUG, "restoring block; id=%u seq=%u inode_id=%u prev_id=%u "
+    NFFS_LOG(DEBUG, "restoring block; id=0x%08x seq=%u inode_id=%u prev_id=%u "
              "data_len=%u\n", disk_block->ndb_id, disk_block->ndb_seq,
              disk_block->ndb_inode_id, disk_block->ndb_prev_id,
              disk_block->ndb_data_len);
@@ -632,59 +702,6 @@ nffs_restore_block(const struct nffs_disk_block *disk_block, uint8_t area_idx,
         }
     }
 
-    /* Make sure the parent inode (file) points to the latest data block
-     * restored so far.
-     *
-     * XXX: This is an O(n) operation (n = # of blocks in the file), and is
-     * horribly inefficient for large files.  MYNEWT-161 has been opened to
-     * address this.
-     */
-    if (inode_entry->nie_last_block_entry == NULL) {
-        /* This is the first data block restored for this file. */
-        inode_entry->nie_last_block_entry = entry;
-        NFFS_LOG(DEBUG, "setting last block: %u\n", entry->nhe_id);
-    } else {
-        /* Determine if this this data block comes after our current idea of
-         * the file's last data block.
-         */
-
-        rc = nffs_block_find_predecessor(
-            entry, inode_entry->nie_last_block_entry->nhe_id);
-        switch (rc) {
-        case 0:
-            /* The currently-last block is a predecessor of the new block; the
-             * new block comes later.
-             */
-            NFFS_LOG(DEBUG, "replacing last block: %u --> %u\n",
-                     inode_entry->nie_last_block_entry->nhe_id,
-                     entry->nhe_id);
-            inode_entry->nie_last_block_entry = entry;
-            break;
-
-        case FS_ENOENT:
-            /* The currently-last block is not a known predecessor of the new
-             * block.  There are two possibilities:
-             *     (1) The new block comes before the currently-last block.
-             *     (2) The new block comes later, but the two blocks are not
-             *         chained in RAM yet because an intervening block has yet
-             *         to be restored.
-             * If we can find the new block by searching backwards from the
-             * currently-last black, then (1) is true.  Otherwise, (2) is true.
-             */
-            rc = nffs_block_find_predecessor(
-                inode_entry->nie_last_block_entry, entry->nhe_id);
-            if (rc == FS_ENOENT) {
-                inode_entry->nie_last_block_entry = entry;
-                NFFS_LOG(DEBUG, "replacing last block: %u --> %u\n",
-                         inode_entry->nie_last_block_entry->nhe_id,
-                         entry->nhe_id);
-            }
-            break;
-
-        default:
-            return rc;
-        }
-    }
 
     return 0;
 
@@ -1135,6 +1152,9 @@ nffs_restore_full(const struct nffs_area_desc *area_descs)
         goto err;
     }
 
+    /* Find the last block in each file inode. */
+    nffs_restore_find_file_ends();
+
     /* Delete from RAM any objects that were invalidated when subsequent areas
      * were restored.
      */


[14/50] [abbrv] incubator-mynewt-core git commit: Update example apps to account for blehost changes

Posted by ma...@apache.org.
Update example apps to account for blehost changes


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

Branch: refs/heads/master
Commit: 7235e90ad0fdbe44faa2afce0130c3f1cdc782d7
Parents: e32f9f9
Author: Christopher Collins <cc...@apache.org>
Authored: Fri Apr 15 21:04:28 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Apr 19 18:11:03 2016 -0700

----------------------------------------------------------------------
 apps/bleprph/src/main.c                 |   8 +-
 apps/bletest/src/main.c                 |  92 +++++----------------
 apps/bletiny/src/main.c                 | 114 ++++++---------------------
 net/nimble/host/include/host/host_hci.h |   1 +
 net/nimble/host/src/ble_hci_util.c      |  29 +++++++
 net/nimble/host/src/ble_hci_util.h      |   1 +
 net/nimble/host/src/host_hci_cmd.c      |  32 +++++++-
 net/nimble/include/nimble/hci_common.h  |   3 +-
 8 files changed, 110 insertions(+), 170 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7235e90a/apps/bleprph/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bleprph/src/main.c b/apps/bleprph/src/main.c
index e99c624..a9d8657 100755
--- a/apps/bleprph/src/main.c
+++ b/apps/bleprph/src/main.c
@@ -191,9 +191,6 @@ bleprph_task_handler(void *unused)
      */
     gatt_svr_init();
 
-    /* Initialize eventq */
-    os_eventq_init(&bleprph_evq);
-
     /* Begin advertising. */
     bleprph_advertise();
 
@@ -283,7 +280,10 @@ main(void)
     cfg.max_l2cap_chans = 3;
     cfg.max_l2cap_sig_procs = 2;
 
-    rc = ble_hs_init(BLEPRPH_BLE_HS_PRIO, &cfg);
+    /* Initialize eventq */
+    os_eventq_init(&bleprph_evq);
+
+    rc = ble_hs_init(&bleprph_evq, &cfg);
     assert(rc == 0);
 
     /* Initialize the console (for log output). */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7235e90a/apps/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c
index 254abcb..d66a91a 100755
--- a/apps/bletest/src/main.c
+++ b/apps/bletest/src/main.c
@@ -223,7 +223,6 @@ bletest_inc_adv_pkt_num(void)
 
         rc = host_hci_cmd_le_set_adv_data(g_host_adv_data, g_host_adv_len);
         assert(rc == 0);
-        host_hci_outstanding_opcode = 0;
     }
 }
 #endif
@@ -244,7 +243,6 @@ bletest_send_conn_update(uint16_t handle)
 
     rc = host_hci_cmd_le_conn_update(&hcu);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 }
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
@@ -258,7 +256,6 @@ void
 bletest_send_ltk_req_neg_reply(uint16_t handle)
 {
     host_hci_cmd_le_lt_key_req_neg_reply(handle);
-    host_hci_outstanding_opcode = 0;
 }
 
 void
@@ -269,7 +266,6 @@ bletest_send_ltk_req_reply(uint16_t handle)
     hkr.conn_handle = handle;
     swap_buf(hkr.long_term_key, (uint8_t *)g_bletest_LTK, 16);
     host_hci_cmd_le_lt_key_req_reply(&hkr);
-    host_hci_outstanding_opcode = 0;
 }
 #endif
 
@@ -368,7 +364,6 @@ bletest_init_advertising(void)
     /* Set the advertising parameters */
     rc = host_hci_cmd_le_set_adv_params(&adv);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* If we are using a random address, we need to set it */
     if (adv.own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
@@ -376,19 +371,16 @@ bletest_init_advertising(void)
         rand_addr[5] |= 0xc0;
         rc = host_hci_cmd_le_set_rand_addr(rand_addr);
         assert(rc == 0);
-        host_hci_outstanding_opcode = 0;
     }
 
     /* Set advertising data */
     if (adv_len != 0) {
         rc = host_hci_cmd_le_set_adv_data(&g_host_adv_data[0], adv_len);
         assert(rc == 0);
-        host_hci_outstanding_opcode = 0;
 
         /* Set scan response data */
         rc = host_hci_cmd_le_set_scan_rsp_data(&g_host_adv_data[0], adv_len);
         assert(rc == 0);
-        host_hci_outstanding_opcode = 0;
     }
 }
 #endif
@@ -408,7 +400,6 @@ bletest_init_scanner(void)
                                          BLE_HCI_ADV_OWN_ADDR_PUBLIC,
                                          BLETEST_CFG_SCAN_FILT_POLICY);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     filter_policy = BLETEST_CFG_SCAN_FILT_POLICY;
     if (filter_policy & 1) {
@@ -421,7 +412,6 @@ bletest_init_scanner(void)
         dev_addr[5] = 0x08;
         rc = host_hci_cmd_le_add_to_whitelist(dev_addr, BLE_ADDR_TYPE_PUBLIC);
         assert(rc == 0);
-        host_hci_outstanding_opcode = 0;
     }
 }
 
@@ -435,12 +425,10 @@ bletest_execute_scanner(void)
         if (g_bletest_state) {
             rc = host_hci_cmd_le_set_scan_enable(0, BLETEST_CFG_FILT_DUP_ADV);
             assert(rc == 0);
-            host_hci_outstanding_opcode = 0;
             g_bletest_state = 0;
         } else {
             rc = host_hci_cmd_le_set_scan_enable(1, BLETEST_CFG_FILT_DUP_ADV);
             assert(rc == 0);
-            host_hci_outstanding_opcode = 0;
             g_bletest_state = 1;
         }
         g_next_os_time += (OS_TICKS_PER_SEC * 60);
@@ -485,12 +473,10 @@ bletest_init_initiator(void)
         rand_addr[5] |= 0xc0;
         rc = host_hci_cmd_le_set_rand_addr(rand_addr);
         assert(rc == 0);
-        host_hci_outstanding_opcode = 0;
     }
 
     rc = host_hci_cmd_le_create_connection(hcc);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 }
 
 void
@@ -513,11 +499,9 @@ bletest_execute_initiator(void)
 
             /* Ask for version information */
             rc = host_hci_cmd_rd_rem_version(handle);
-            host_hci_outstanding_opcode = 0;
 
             /* Ask for remote used features */
             rc = host_hci_cmd_le_read_rem_used_feat(handle);
-            host_hci_outstanding_opcode = 0;
 
             /* Scanning better be stopped! */
             assert(ble_ll_scan_enabled() == 0);
@@ -541,7 +525,6 @@ bletest_execute_initiator(void)
                 for (i = 0; i < g_bletest_current_conns; ++i) {
                     if (ble_ll_conn_find_active_conn(i + 1)) {
                         host_hci_cmd_le_rd_chanmap(i+1);
-                        host_hci_outstanding_opcode = 0;
                     }
                 }
             } else if (g_bletest_state == 2) {
@@ -551,7 +534,6 @@ bletest_execute_initiator(void)
                 new_chan_map[3] = 0x1F;
                 new_chan_map[4] = 0;
                 host_hci_cmd_le_set_host_chan_class(new_chan_map);
-                host_hci_outstanding_opcode = 0;
             } else if (g_bletest_state == 4) {
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
                 struct hci_start_encrypt hsle;
@@ -563,7 +545,6 @@ bletest_execute_initiator(void)
                         swap_buf(hsle.long_term_key, (uint8_t *)g_bletest_LTK,
                                  16);
                         host_hci_cmd_le_start_encrypt(&hsle);
-                        host_hci_outstanding_opcode = 0;
                     }
                 }
 #endif
@@ -571,7 +552,6 @@ bletest_execute_initiator(void)
                 for (i = 0; i < g_bletest_current_conns; ++i) {
                     if (ble_ll_conn_find_active_conn(i + 1)) {
                         host_hci_cmd_read_rssi(i+1);
-                        host_hci_outstanding_opcode = 0;
                     }
                 }
             }
@@ -639,14 +619,12 @@ bletest_execute_advertiser(void)
 
             /* Send the remote used features command */
             rc = host_hci_cmd_le_read_rem_used_feat(handle);
-            host_hci_outstanding_opcode = 0;
             if (rc) {
                 return;
             }
 
             /* Send the remote read version command */
             rc = host_hci_cmd_rd_rem_version(handle);
-            host_hci_outstanding_opcode = 0;
             if (rc) {
                 return;
             }
@@ -665,7 +643,6 @@ bletest_execute_advertiser(void)
                 g_dev_addr[5] += 1;
                 bletest_init_advertising();
                 rc = host_hci_cmd_le_set_adv_enable(1);
-                host_hci_outstanding_opcode = 0;
             }
         }
     }
@@ -860,7 +837,6 @@ bletest_task_handler(void *arg)
     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 */
@@ -884,78 +860,64 @@ bletest_task_handler(void *arg)
     event_mask = 0x7FF;
     rc = host_hci_cmd_le_set_event_mask(event_mask);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Turn on all events */
     event_mask = 0xffffffffffffffff;
     rc = host_hci_cmd_set_event_mask(event_mask);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Read device address */
     rc = host_hci_cmd_rd_bd_addr();
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Read local features */
     rc = host_hci_cmd_rd_local_feat();
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Read local commands */
     rc = host_hci_cmd_rd_local_cmd();
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Read version */
     rc = host_hci_cmd_rd_local_version();
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Read supported states */
     rc = host_hci_cmd_le_read_supp_states();
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Read maximum data length */
     rc = host_hci_cmd_le_read_max_datalen();
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Read suggested data length */
     rc = host_hci_cmd_le_read_sugg_datalen();
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* write suggested default data length */
     rc = host_hci_cmd_le_write_sugg_datalen(BLETEST_CFG_SUGG_DEF_TXOCTETS,
                                             BLETEST_CFG_SUGG_DEF_TXTIME);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Read suggested data length */
     rc = host_hci_cmd_le_read_sugg_datalen();
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Set data length (note: we know there is no connection; just a test) */
     rc = host_hci_cmd_le_set_datalen(0x1234,
                                      BLETEST_CFG_SUGG_DEF_TXOCTETS,
                                      BLETEST_CFG_SUGG_DEF_TXTIME);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
 
     /* Encrypt a block */
     rc = host_hci_cmd_le_encrypt((uint8_t *)g_ble_ll_encrypt_test_key,
                                  (uint8_t *)g_ble_ll_encrypt_test_plain_text);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Get a random number */
     rc = host_hci_cmd_le_rand();
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 
     /* Wait some time before starting */
     os_time_delay(OS_TICKS_PER_SEC);
@@ -967,7 +929,6 @@ bletest_task_handler(void *arg)
 #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
     rc = host_hci_cmd_le_set_adv_enable(1);
     assert(rc == 0);
-    host_hci_outstanding_opcode = 0;
 #endif
 
     bletest_timer_cb(NULL);
@@ -988,34 +949,6 @@ bletest_task_handler(void *arg)
 }
 
 /**
- * init_tasks
- *
- * Called by main.c after os_init(). This function performs initializations
- * that are required before tasks are running.
- *
- * @return int 0 success; error otherwise.
- */
-static int
-init_tasks(void)
-{
-    int rc;
-
-    os_task_init(&bletest_task, "bletest", bletest_task_handler, NULL,
-                 BLETEST_TASK_PRIO, OS_WAIT_FOREVER, bletest_stack,
-                 BLETEST_STACK_SIZE);
-
-    /* Initialize host HCI */
-    rc = ble_hs_init(HOST_TASK_PRIO, NULL);
-    assert(rc == 0);
-
-    /* Initialize the BLE LL */
-    rc = ble_ll_init(BLE_LL_TASK_PRI, MBUF_NUM_MBUFS, BLE_MBUF_PAYLOAD_SIZE);
-    assert(rc == 0);
-
-    return 0;
-}
-
-/**
  * main
  *
  * The main function for the project. This function initializes the os, calls
@@ -1123,19 +1056,34 @@ main(void)
     }
 #endif
 
-    shell_task_init(SHELL_TASK_PRIO, shell_stack, SHELL_TASK_STACK_SIZE,
+    rc = shell_task_init(SHELL_TASK_PRIO, shell_stack, SHELL_TASK_STACK_SIZE,
                          SHELL_MAX_INPUT_LEN);
+    assert(rc == 0);
+
+    rc = nmgr_task_init(NEWTMGR_TASK_PRIO, newtmgr_stack,
+                        NEWTMGR_TASK_STACK_SIZE);
+    assert(rc == 0);
 
-    nmgr_task_init(NEWTMGR_TASK_PRIO, newtmgr_stack, NEWTMGR_TASK_STACK_SIZE);
 #if 0
     imgmgr_module_init();
 #endif
 
     /* Init statistics module */
-    stats_module_init();
+    rc = stats_module_init();
+    assert(rc == 0);
 
-    /* Init tasks */
-    init_tasks();
+    /* Initialize the BLE LL */
+    rc = ble_ll_init(BLE_LL_TASK_PRI, MBUF_NUM_MBUFS, BLE_MBUF_PAYLOAD_SIZE);
+    assert(rc == 0);
+
+    /* Initialize host */
+    rc = ble_hs_init(&g_bletest_evq, NULL);
+    assert(rc == 0);
+
+    rc = os_task_init(&bletest_task, "bletest", bletest_task_handler, NULL,
+                      BLETEST_TASK_PRIO, OS_WAIT_FOREVER, bletest_stack,
+                      BLETEST_STACK_SIZE);
+    assert(rc == 0);
 
     /* Start the OS */
     os_start();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7235e90a/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index 2cec311..70193fc 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -47,16 +47,16 @@
  * app uses some of nimble's internal details for logging.
  */
 #include "../src/ble_hs_conn.h"
+#include "../src/ble_hci_util.h"
 
 #define BSWAP16(x)  ((uint16_t)(((x) << 8) | (((x) & 0xff00) >> 8)))
 
 /* Nimble task priorities */
 #define BLE_LL_TASK_PRI         (OS_TASK_PRI_HIGHEST)
-#define HOST_TASK_PRIO          (1)
 
 #define SHELL_TASK_PRIO         (3)
 #define SHELL_MAX_INPUT_LEN     (64)
-#define SHELL_TASK_STACK_SIZE   (OS_STACK_ALIGN(210))
+#define SHELL_TASK_STACK_SIZE   (OS_STACK_ALIGN(288))
 static bssnz_t os_stack_t shell_stack[SHELL_TASK_STACK_SIZE];
 
 static struct os_mutex bletiny_mutex;
@@ -85,8 +85,8 @@ struct os_mbuf_pool default_mbuf_pool;
 struct os_mempool default_mbuf_mpool;
 
 /* BLETINY variables */
-#define BLETINY_STACK_SIZE             (OS_STACK_ALIGN(210))
-#define BLETINY_TASK_PRIO              (HOST_TASK_PRIO + 1)
+#define BLETINY_STACK_SIZE             (OS_STACK_ALIGN(288))
+#define BLETINY_TASK_PRIO              1
 
 #if NIMBLE_OPT_ROLE_CENTRAL
 #define BLETINY_MAX_SVCS               32
@@ -98,7 +98,7 @@ struct os_mempool default_mbuf_mpool;
 #define BLETINY_MAX_DSCS               1
 #endif
 
-struct os_eventq g_bletiny_evq;
+struct os_eventq bletiny_evq;
 struct os_task bletiny_task;
 bssnz_t os_stack_t bletiny_stack[BLETINY_STACK_SIZE];
 
@@ -136,7 +136,7 @@ uint8_t bletiny_gatt_service_changed[4];
 #ifdef DEVICE_NAME
 #define BLETINY_AUTO_DEVICE_NAME    XSTR(DEVICE_NAME)
 #else
-#define BLETINY_AUTO_DEVICE_NAME    NULL
+#define BLETINY_AUTO_DEVICE_NAME    ""
 #endif
 
 void
@@ -684,11 +684,10 @@ bletiny_dsc_add(uint16_t conn_handle, uint16_t chr_def_handle,
 static void
 bletiny_start_auto_advertise(void)
 {
-#if 0
     struct ble_hs_adv_fields fields;
     int rc;
 
-    if (BLETINY_AUTO_DEVICE_NAME != NULL) {
+    if (BLETINY_AUTO_DEVICE_NAME[0] != '\0') {
         memset(&fields, 0, sizeof fields);
 
         fields.name = (uint8_t *)BLETINY_AUTO_DEVICE_NAME;
@@ -705,7 +704,6 @@ bletiny_start_auto_advertise(void)
             return;
         }
     }
-#endif
 }
 
 static int
@@ -805,32 +803,6 @@ bletiny_on_read(uint16_t conn_handle, struct ble_gatt_error *error,
 }
 
 static int
-bletiny_on_read_mult(uint16_t conn_handle, struct ble_gatt_error *error,
-                      uint16_t *attr_handles, uint8_t num_attr_handles,
-                      uint8_t *attr_data, uint16_t attr_data_len, void *arg)
-{
-    int i;
-
-    if (error != NULL) {
-        bletiny_print_error("ERROR READING CHARACTERISTICS", conn_handle,
-                             error);
-    } else {
-        console_printf("multiple characteristic read complete; conn_handle=%d "
-                       "attr_handles=", conn_handle);
-        for (i = 0; i < num_attr_handles; i++) {
-            console_printf("%s%d", i != 0 ? "," : "", attr_handles[i]);
-        }
-
-        console_printf(" len=%d value=", attr_data_len);
-        bletiny_print_bytes(attr_data, attr_data_len);
-        console_printf("\n");
-    }
-
-    return 0;
-
-}
-
-static int
 bletiny_on_write(uint16_t conn_handle, struct ble_gatt_error *error,
                   struct ble_gatt_attr *attr, void *arg)
 {
@@ -977,27 +949,6 @@ bletiny_on_scan(int event, int status, struct ble_gap_disc_desc *desc,
     }
 }
 
-#if 0
-static void
-bletiny_on_rx_rssi(struct ble_hci_ack *ack, void *unused)
-{
-    struct hci_read_rssi_ack_params params;
-
-    if (ack->bha_params_len != BLE_HCI_READ_RSSI_ACK_PARAM_LEN) {
-        console_printf("invalid rssi response; len=%d\n",
-                       ack->bha_params_len);
-        return;
-    }
-
-    params.status = ack->bha_params[0];
-    params.connection_handle = le16toh(ack->bha_params + 1);
-    params.rssi = ack->bha_params[3];
-
-    console_printf("rssi response received; status=%d conn=%d rssi=%d\n",
-                   params.status, params.connection_handle, params.rssi);
-}
-#endif
-
 int
 bletiny_exchange_mtu(uint16_t conn_handle)
 {
@@ -1111,7 +1062,7 @@ bletiny_read_mult(uint16_t conn_handle, uint16_t *attr_handles,
     int rc;
 
     rc = ble_gattc_read_mult(conn_handle, attr_handles, num_attr_handles,
-                             bletiny_on_read_mult, NULL);
+                             bletiny_on_read, NULL);
     return rc;
 }
 
@@ -1137,8 +1088,8 @@ bletiny_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, void *value,
 {
     int rc;
 
-    rc = ble_gattc_write_no_rsp(conn_handle, attr_handle, value, value_len,
-                                bletiny_on_write, NULL);
+    rc = ble_gattc_write_no_rsp(conn_handle, attr_handle, value, value_len);
+
     return rc;
 }
 
@@ -1268,41 +1219,20 @@ bletiny_l2cap_update(uint16_t conn_handle,
     return rc;
 }
 
-#if 0
-static int
-bletiny_tx_rssi_req(void *arg)
-{
-    intptr_t conn_handle;
-    int rc;
-
-    conn_handle = (intptr_t)arg;
-
-    ble_hci_sched_set_ack_cb(bletiny_on_rx_rssi, NULL);
-
-    rc = host_hci_cmd_read_rssi(conn_handle);
-    if (rc != 0) {
-        console_printf("failure to send rssi hci cmd; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-#endif
-
 int
 bletiny_show_rssi(uint16_t conn_handle)
 {
-#if 0
+    int8_t rssi;
     int rc;
 
-    rc = ble_hci_sched_enqueue(bletiny_tx_rssi_req,
-                               (void *)(intptr_t)conn_handle, NULL);
+    rc = ble_hci_util_read_rssi(conn_handle, &rssi);
     if (rc != 0) {
-        console_printf("failure to enqueue rssi hci cmd; rc=%d\n", rc);
+        console_printf("failure to read rssi; rc=%d\n", rc);
         return rc;
     }
 
-#endif
+    console_printf("rssi=%d\n", rssi);
+
     return 0;
 }
 
@@ -1327,20 +1257,21 @@ bletiny_sec_start(uint16_t conn_handle)
 static void
 bletiny_task_handler(void *arg)
 {
-    struct os_event *ev;
     struct os_callout_func *cf;
+    struct os_event *ev;
+    int rc;
+
+    rc = ble_hs_start();
+    assert(rc == 0);
 
     periph_init();
 
     ble_att_set_notify_cb(bletiny_on_notify, NULL);
 
-    /* Initialize eventq */
-    os_eventq_init(&g_bletiny_evq);
-
     bletiny_start_auto_advertise();
 
     while (1) {
-        ev = os_eventq_get(&g_bletiny_evq);
+        ev = os_eventq_get(&bletiny_evq);
         switch (ev->ev_type) {
         case OS_EVENT_T_TIMER:
             cf = (struct os_callout_func *)ev;
@@ -1435,6 +1366,7 @@ main(void)
     log_console_handler_init(&bletiny_log_console_handler);
     log_register("bletiny", &bletiny_log, &bletiny_log_console_handler);
 
+    os_eventq_init(&bletiny_evq);
     os_task_init(&bletiny_task, "bletiny", bletiny_task_handler,
                  NULL, BLETINY_TASK_PRIO, OS_WAIT_FOREVER,
                  bletiny_stack, BLETINY_STACK_SIZE);
@@ -1460,7 +1392,7 @@ main(void)
     cfg.max_l2cap_chans = 3;
     cfg.max_l2cap_sig_procs = 2;
 
-    rc = ble_hs_init(HOST_TASK_PRIO, &cfg);
+    rc = ble_hs_init(&bletiny_evq, &cfg);
     assert(rc == 0);
 
     /* Initialize the BLE LL */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7235e90a/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 1a15f01..1b8d61f 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -41,6 +41,7 @@ int host_hci_cmd_rd_local_version(void);
 int host_hci_cmd_rd_local_feat(void);
 int host_hci_cmd_rd_local_cmd(void);
 int host_hci_cmd_rd_bd_addr(void);
+void host_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, int dst_len);
 int host_hci_cmd_read_rssi(uint16_t handle);
 int host_hci_cmd_le_set_host_chan_class(uint8_t *new_chan_map);
 int host_hci_cmd_le_rd_chanmap(uint16_t handle);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7235e90a/net/nimble/host/src/ble_hci_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util.c b/net/nimble/host/src/ble_hci_util.c
index 2ff159d..9216377 100644
--- a/net/nimble/host/src/ble_hci_util.c
+++ b/net/nimble/host/src/ble_hci_util.c
@@ -76,3 +76,32 @@ ble_hci_util_rand(void *dst, int len)
 
     return 0;
 }
+
+int
+ble_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_READ_RSSI_LEN];
+    uint8_t params[BLE_HCI_READ_RSSI_ACK_PARAM_LEN];
+    uint16_t params_conn_handle;
+    uint8_t params_len;
+    int rc;
+
+    host_hci_cmd_build_read_rssi(conn_handle, buf, sizeof buf);
+    rc = ble_hci_tx_cmd(buf, params, 1, &params_len);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (params_len != BLE_HCI_READ_RSSI_ACK_PARAM_LEN) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    params_conn_handle = le16toh(params + 0);
+    if (params_conn_handle != conn_handle) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    *out_rssi = params[2];
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7235e90a/net/nimble/host/src/ble_hci_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util.h b/net/nimble/host/src/ble_hci_util.h
index c259d6d..f73dd47 100644
--- a/net/nimble/host/src/ble_hci_util.h
+++ b/net/nimble/host/src/ble_hci_util.h
@@ -22,5 +22,6 @@
 
 int ble_hci_util_read_adv_tx_pwr(int8_t *out_pwr);
 int ble_hci_util_rand(void *dst, int len);
+int ble_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7235e90a/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 180571d..8ed0395 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -1508,14 +1508,42 @@ host_hci_cmd_le_start_encrypt(struct hci_start_encrypt *cmd)
  *
  * @return int
  */
+static void
+host_hci_cmd_body_read_rssi(uint16_t handle, uint8_t *dst)
+{
+    htole16(dst, handle);
+}
+
+void
+host_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_READ_RSSI_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_STATUS_PARAMS, BLE_HCI_OCF_RD_RSSI,
+                       BLE_HCI_READ_RSSI_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    host_hci_cmd_body_read_rssi(handle, dst);
+}
+
+/**
+ * Read the RSSI for a given connection handle
+ *
+ * NOTE: OGF=0x05 OCF=0x0005
+ *
+ * @param handle
+ *
+ * @return int
+ */
 int
 host_hci_cmd_read_rssi(uint16_t handle)
 {
+    uint8_t cmd[BLE_HCI_READ_RSSI_LEN];
     int rc;
-    uint8_t cmd[sizeof(uint16_t)];
 
     htole16(cmd, handle);
     rc = host_hci_cmd_send(BLE_HCI_OGF_STATUS_PARAMS, BLE_HCI_OCF_RD_RSSI,
-                           sizeof(uint16_t), cmd);
+                           BLE_HCI_READ_RSSI_LEN, cmd);
     return rc;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7235e90a/net/nimble/include/nimble/hci_common.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h
index 2d43652..499a898 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -135,7 +135,8 @@
 #define BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN      (64)
 
 /* --- Read RSSI (OGF 0x05, OCF 0x0005) --- */
-#define BLE_HCI_READ_RSSI_ACK_PARAM_LEN     (4)  /* Includes status byte. */
+#define BLE_HCI_READ_RSSI_LEN               (2)
+#define BLE_HCI_READ_RSSI_ACK_PARAM_LEN     (3)  /* No status byte. */
 
 /* --- LE set event mask (OCF 0x0001) --- */
 #define BLE_HCI_SET_LE_EVENT_MASK_LEN       (8)


[46/50] [abbrv] incubator-mynewt-core git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-mynewt-core into develop

Posted by ma...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-mynewt-core into develop


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

Branch: refs/heads/master
Commit: c12dbb96baa8026cd43082ac6c4f3dfa8a9f9e17
Parents: 546cf5e bf35f3a
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Tue Apr 26 12:54:00 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Tue Apr 26 12:54:00 2016 -0700

----------------------------------------------------------------------
 README.md | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------



[21/50] [abbrv] incubator-mynewt-core git commit: This closes pull request #45.

Posted by ma...@apache.org.
This closes pull request #45.

Merge branch 'develop' of https://github.com/neelnatu/incubator-mynewt-larva into develop


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

Branch: refs/heads/master
Commit: d200094bca8c7c1c51c4585ba5769a1ac076ace3
Parents: 9abd8ce dc15948
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Tue Apr 19 21:13:23 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Tue Apr 19 21:13:23 2016 -0700

----------------------------------------------------------------------
 libs/os/src/arch/sim/os_arch_sim.c | 72 +++++++++++++++++++++++++--------
 1 file changed, 56 insertions(+), 16 deletions(-)
----------------------------------------------------------------------



[28/50] [abbrv] incubator-mynewt-core git commit: ble host - make priv header filenames consistent.

Posted by ma...@apache.org.
ble host - make priv header filenames consistent.


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

Branch: refs/heads/master
Commit: 832637dbb20a9d5c0bee09aa1dfab157beecce96
Parents: 99dc724
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 20 16:10:54 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 20 16:11:49 2016 -0700

----------------------------------------------------------------------
 apps/bletiny/src/main.c                   |   4 +-
 net/nimble/host/src/ble_att_cmd.h         | 390 -------------------------
 net/nimble/host/src/ble_att_cmd_priv.h    | 390 +++++++++++++++++++++++++
 net/nimble/host/src/ble_hci_cmd.c         |   2 +-
 net/nimble/host/src/ble_hci_util.h        |  27 --
 net/nimble/host/src/ble_hci_util_priv.h   |  27 ++
 net/nimble/host/src/ble_hs_atomic.h       |  30 --
 net/nimble/host/src/ble_hs_atomic_priv.h  |  30 ++
 net/nimble/host/src/ble_hs_conn.h         |  74 -----
 net/nimble/host/src/ble_hs_conn_priv.h    |  74 +++++
 net/nimble/host/src/ble_hs_endian.h       |  57 ----
 net/nimble/host/src/ble_hs_endian_priv.h  |  57 ++++
 net/nimble/host/src/ble_hs_priv.h         |  16 +-
 net/nimble/host/src/ble_hs_startup.h      |  25 --
 net/nimble/host/src/ble_hs_startup_priv.h |  25 ++
 net/nimble/host/src/ble_l2cap_priv.h      |  76 +----
 net/nimble/host/src/ble_l2cap_sig.h       |  27 --
 net/nimble/host/src/ble_l2cap_sig_priv.h  |  77 +++++
 net/nimble/host/src/ble_l2cap_sm.h        | 161 ----------
 net/nimble/host/src/ble_l2cap_sm_priv.h   | 161 ++++++++++
 net/nimble/host/src/host_dbg.h            |  25 --
 net/nimble/host/src/host_dbg_priv.h       |  25 ++
 net/nimble/host/src/host_hci.c            |   2 +-
 net/nimble/host/src/host_hci_cmd.c        |   2 +-
 24 files changed, 890 insertions(+), 894 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index 70193fc..bbbf171 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -46,8 +46,8 @@
 /* XXX: An app should not include private headers from a library.  The bletiny
  * app uses some of nimble's internal details for logging.
  */
-#include "../src/ble_hs_conn.h"
-#include "../src/ble_hci_util.h"
+#include "../src/ble_hs_conn_priv.h"
+#include "../src/ble_hci_util_priv.h"
 
 #define BSWAP16(x)  ((uint16_t)(((x) << 8) | (((x) & 0xff00) >> 8)))
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_att_cmd.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_cmd.h b/net/nimble/host/src/ble_att_cmd.h
deleted file mode 100644
index 0dd8f0c..0000000
--- a/net/nimble/host/src/ble_att_cmd.h
+++ /dev/null
@@ -1,390 +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_BLE_ATT_CMD_
-#define H_BLE_ATT_CMD_
-
-#include <inttypes.h>
-struct ble_l2cap_chan;
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Request Opcode In Error            | 1                 |
- * | Attribute Handle In Error          | 2                 |
- * | Error Code                         | 1                 |
- */
-#define BLE_ATT_ERROR_RSP_SZ             5
-struct ble_att_error_rsp {
-    uint8_t baep_req_op;
-    uint16_t baep_handle;
-    uint8_t baep_error_code;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Server Rx MTU                      | 2                 |
- */
-#define BLE_ATT_MTU_CMD_SZ               3
-struct ble_att_mtu_cmd {
-    uint16_t bamc_mtu;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Starting Handle                    | 2                 |
- * | Ending Handle                      | 2                 |
- */
-#define BLE_ATT_FIND_INFO_REQ_SZ         5
-struct ble_att_find_info_req {
-    uint16_t bafq_start_handle;
-    uint16_t bafq_end_handle;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Format                             | 1                 |
- * | Information Data                   | 4 to (ATT_MTU-2)  |
- */
-#define BLE_ATT_FIND_INFO_RSP_BASE_SZ       2
-struct ble_att_find_info_rsp {
-    uint8_t bafp_format;
-    /* Followed by information data. */
-} __attribute__((packed));
-
-#define BLE_ATT_FIND_INFO_RSP_FORMAT_16BIT   1
-#define BLE_ATT_FIND_INFO_RSP_FORMAT_128BIT  2
-
-#define BLE_ATT_FIND_INFO_IDATA_16_SZ           4
-#define BLE_ATT_FIND_INFO_IDATA_128_SZ          18
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Starting Handle                    | 2                 |
- * | Ending Handle                      | 2                 |
- * | Attribute Type                     | 2                 |
- * | Attribute Value                    | 0 to (ATT_MTU-7)  |
- */
-#define BLE_ATT_FIND_TYPE_VALUE_REQ_BASE_SZ   7
-struct ble_att_find_type_value_req {
-    uint16_t bavq_start_handle;
-    uint16_t bavq_end_handle;
-    uint16_t bavq_attr_type;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Information Data                   | 4 to (ATT_MTU-1)  |
- */
-#define BLE_ATT_FIND_TYPE_VALUE_RSP_BASE_SZ     1
-#define BLE_ATT_FIND_TYPE_VALUE_HINFO_BASE_SZ   4
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Starting Handle                    | 2                 |
- * | Ending Handle                      | 2                 |
- * | Attribute Type                     | 2 or 16           |
- */
-#define BLE_ATT_READ_TYPE_REQ_BASE_SZ   5
-#define BLE_ATT_READ_TYPE_REQ_SZ_16     7
-#define BLE_ATT_READ_TYPE_REQ_SZ_128    21
-struct ble_att_read_type_req {
-    uint16_t batq_start_handle;
-    uint16_t batq_end_handle;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Length                             | 1                 |
- * | Attribute Data List                | 2 to (ATT_MTU-2)  |
- */
-#define BLE_ATT_READ_TYPE_RSP_BASE_SZ       2
-struct ble_att_read_type_rsp {
-    uint8_t batp_length;
-} __attribute__((packed));
-
-#define BLE_ATT_READ_TYPE_ADATA_BASE_SZ     2
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Attribute Handle                   | 2                 |
- */
-#define BLE_ATT_READ_REQ_SZ              3
-struct ble_att_read_req {
-    uint16_t barq_handle;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Attribute Value                    | 0 to (ATT_MTU-1)  |
- */
-#define BLE_ATT_READ_RSP_BASE_SZ        1
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Attribute Handle                   | 2                 |
- * | Value Offset                       | 2                 |
- */
-#define BLE_ATT_READ_BLOB_REQ_SZ        5
-struct ble_att_read_blob_req {
-    uint16_t babq_handle;
-    uint16_t babq_offset;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Attribute Value                    | 0 to (ATT_MTU-1)  |
- */
-#define BLE_ATT_READ_BLOB_RSP_BASE_SZ   1
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Set Of Handles                     | 4 to (ATT_MTU-1)  |
- */
-#define BLE_ATT_READ_MULT_REQ_BASE_SZ   1
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Set Of Values                      | 4 to (ATT_MTU-1)  |
- */
-#define BLE_ATT_READ_MULT_RSP_BASE_SZ   1
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Starting Handle                    | 2                 |
- * | Ending Handle                      | 2                 |
- * | Attribute Group Type               | 2 or 16           |
- */
-#define BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ  5
-#define BLE_ATT_READ_GROUP_TYPE_REQ_SZ_16    7
-#define BLE_ATT_READ_GROUP_TYPE_REQ_SZ_128   21
-struct ble_att_read_group_type_req {
-    uint16_t bagq_start_handle;
-    uint16_t bagq_end_handle;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Length                             | 1                 |
- * | Attribute Data List                | 2 to (ATT_MTU-2)  |
- */
-#define BLE_ATT_READ_GROUP_TYPE_RSP_BASE_SZ  2
-struct ble_att_read_group_type_rsp {
-    uint8_t bagp_length;
-} __attribute__((packed));
-
-#define BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ   4
-#define BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_16     6
-#define BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_128    20
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Attribute Handle                   | 2                 |
- * | Attribute Value                    | 0 to (ATT_MTU-3)  |
- */
-#define BLE_ATT_WRITE_REQ_BASE_SZ       3
-struct ble_att_write_req {
-    uint16_t bawq_handle;
-} __attribute__((packed));
-
-#define BLE_ATT_WRITE_RSP_SZ            1
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Attribute Handle                   | 2                 |
- * | Value Offset                       | 2                 |
- * | Part Attribute Value               | 0 to (ATT_MTU-5)  |
- */
-#define BLE_ATT_PREP_WRITE_CMD_BASE_SZ  5
-struct ble_att_prep_write_cmd {
-    uint16_t bapc_handle;
-    uint16_t bapc_offset;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Flags                              | 1                 |
- */
-#define BLE_ATT_EXEC_WRITE_REQ_SZ       2
-struct ble_att_exec_write_req {
-    uint8_t baeq_flags;
-} __attribute__((packed));
-
-#define BLE_ATT_EXEC_WRITE_F_CONFIRM    0x01
-#define BLE_ATT_EXEC_WRITE_F_RESERVED   0xfe
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- */
-#define BLE_ATT_EXEC_WRITE_RSP_SZ       1
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Attribute Handle                   | 2                 |
- * | Attribute Value                    | 0 to (ATT_MTU-3)  |
- */
-#define BLE_ATT_NOTIFY_REQ_BASE_SZ      3
-struct ble_att_notify_req {
-    uint16_t banq_handle;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- * | Attribute Handle                   | 2                 |
- * | Attribute Value                    | 0 to (ATT_MTU-3)  |
- */
-#define BLE_ATT_INDICATE_REQ_BASE_SZ    3
-struct ble_att_indicate_req {
-    uint16_t baiq_handle;
-} __attribute__((packed));
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | Attribute Opcode                   | 1                 |
- */
-#define BLE_ATT_INDICATE_RSP_SZ         1
-
-void ble_att_error_rsp_parse(void *payload, int len,
-                              struct ble_att_error_rsp *rsp);
-void ble_att_error_rsp_write(void *payload, int len,
-                              struct ble_att_error_rsp *rsp);
-void ble_att_mtu_cmd_parse(void *payload, int len,
-                            struct ble_att_mtu_cmd *cmd);
-void ble_att_mtu_req_write(void *payload, int len,
-                            struct ble_att_mtu_cmd *cmd);
-void ble_att_mtu_rsp_write(void *payload, int len,
-                           struct ble_att_mtu_cmd *cmd);
-void ble_att_find_info_req_parse(void *payload, int len,
-                                 struct ble_att_find_info_req *req);
-void ble_att_find_info_req_write(void *payload, int len,
-                                 struct ble_att_find_info_req *req);
-void ble_att_find_info_rsp_parse(void *payload, int len,
-                                 struct ble_att_find_info_rsp *rsp);
-void ble_att_find_info_rsp_write(void *payload, int len,
-                                 struct ble_att_find_info_rsp *rsp);
-void ble_att_find_type_value_req_parse(void *payload, int len,
-                                       struct ble_att_find_type_value_req *req);
-void ble_att_find_type_value_req_write(void *payload, int len,
-                                       struct ble_att_find_type_value_req *req);
-void ble_att_read_type_req_parse(void *payload, int len,
-                                 struct ble_att_read_type_req *req);
-void ble_att_read_type_req_write(void *payload, int len,
-                                 struct ble_att_read_type_req *req);
-void ble_att_read_type_rsp_parse(void *payload, int len,
-                                 struct ble_att_read_type_rsp *rsp);
-void ble_att_read_type_rsp_write(void *payload, int len,
-                                 struct ble_att_read_type_rsp *rsp);
-void ble_att_read_req_parse(void *payload, int len,
-                            struct ble_att_read_req *req);
-void ble_att_read_req_write(void *payload, int len,
-                            struct ble_att_read_req *req);
-void ble_att_read_blob_req_parse(void *payload, int len,
-                                 struct ble_att_read_blob_req *req);
-void ble_att_read_blob_req_write(void *payload, int len,
-                                 struct ble_att_read_blob_req *req);
-void ble_att_read_mult_req_parse(void *payload, int len);
-void ble_att_read_mult_req_write(void *payload, int len);
-void ble_att_read_mult_rsp_parse(void *payload, int len);
-void ble_att_read_mult_rsp_write(void *payload, int len);
-void ble_att_read_group_type_req_parse(void *payload, int len,
-                                       struct ble_att_read_group_type_req *req);
-void ble_att_read_group_type_req_write(void *payload, int len,
-                                       struct ble_att_read_group_type_req *req);
-void ble_att_read_group_type_rsp_parse(void *payload, int len,
-                                       struct ble_att_read_group_type_rsp *rsp);
-void ble_att_read_group_type_rsp_write(void *payload, int len,
-                                       struct ble_att_read_group_type_rsp *rsp);
-void ble_att_write_req_parse(void *payload, int len,
-                             struct ble_att_write_req *req);
-void ble_att_write_req_write(void *payload, int len,
-                             struct ble_att_write_req *req);
-void ble_att_write_cmd_parse(void *payload, int len,
-                             struct ble_att_write_req *req);
-void ble_att_write_cmd_write(void *payload, int len,
-                             struct ble_att_write_req *req);
-void ble_att_prep_write_req_parse(void *payload, int len,
-                                  struct ble_att_prep_write_cmd *cmd);
-void ble_att_prep_write_req_write(void *payload, int len,
-                                  struct ble_att_prep_write_cmd *cmd);
-void ble_att_prep_write_rsp_parse(void *payload, int len,
-                                  struct ble_att_prep_write_cmd *cmd);
-void ble_att_prep_write_rsp_write(void *payload, int len,
-                                  struct ble_att_prep_write_cmd *cmd);
-void ble_att_exec_write_req_parse(void *payload, int len,
-                                  struct ble_att_exec_write_req *req);
-void ble_att_exec_write_req_write(void *payload, int len,
-                                  struct ble_att_exec_write_req *req);
-void ble_att_exec_write_rsp_parse(void *payload, int len);
-void ble_att_exec_write_rsp_write(void *payload, int len);
-void ble_att_notify_req_parse(void *payload, int len,
-                              struct ble_att_notify_req *req);
-void ble_att_notify_req_write(void *payload, int len,
-                              struct ble_att_notify_req *req);
-void ble_att_indicate_req_parse(void *payload, int len,
-                                struct ble_att_indicate_req *req);
-void ble_att_indicate_req_write(void *payload, int len,
-                                struct ble_att_indicate_req *req);
-void ble_att_indicate_rsp_parse(void *payload, int len);
-void ble_att_indicate_rsp_write(void *payload, int len);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_att_cmd_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_cmd_priv.h b/net/nimble/host/src/ble_att_cmd_priv.h
new file mode 100644
index 0000000..0dd8f0c
--- /dev/null
+++ b/net/nimble/host/src/ble_att_cmd_priv.h
@@ -0,0 +1,390 @@
+/**
+ * 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_BLE_ATT_CMD_
+#define H_BLE_ATT_CMD_
+
+#include <inttypes.h>
+struct ble_l2cap_chan;
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Request Opcode In Error            | 1                 |
+ * | Attribute Handle In Error          | 2                 |
+ * | Error Code                         | 1                 |
+ */
+#define BLE_ATT_ERROR_RSP_SZ             5
+struct ble_att_error_rsp {
+    uint8_t baep_req_op;
+    uint16_t baep_handle;
+    uint8_t baep_error_code;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Server Rx MTU                      | 2                 |
+ */
+#define BLE_ATT_MTU_CMD_SZ               3
+struct ble_att_mtu_cmd {
+    uint16_t bamc_mtu;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Starting Handle                    | 2                 |
+ * | Ending Handle                      | 2                 |
+ */
+#define BLE_ATT_FIND_INFO_REQ_SZ         5
+struct ble_att_find_info_req {
+    uint16_t bafq_start_handle;
+    uint16_t bafq_end_handle;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Format                             | 1                 |
+ * | Information Data                   | 4 to (ATT_MTU-2)  |
+ */
+#define BLE_ATT_FIND_INFO_RSP_BASE_SZ       2
+struct ble_att_find_info_rsp {
+    uint8_t bafp_format;
+    /* Followed by information data. */
+} __attribute__((packed));
+
+#define BLE_ATT_FIND_INFO_RSP_FORMAT_16BIT   1
+#define BLE_ATT_FIND_INFO_RSP_FORMAT_128BIT  2
+
+#define BLE_ATT_FIND_INFO_IDATA_16_SZ           4
+#define BLE_ATT_FIND_INFO_IDATA_128_SZ          18
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Starting Handle                    | 2                 |
+ * | Ending Handle                      | 2                 |
+ * | Attribute Type                     | 2                 |
+ * | Attribute Value                    | 0 to (ATT_MTU-7)  |
+ */
+#define BLE_ATT_FIND_TYPE_VALUE_REQ_BASE_SZ   7
+struct ble_att_find_type_value_req {
+    uint16_t bavq_start_handle;
+    uint16_t bavq_end_handle;
+    uint16_t bavq_attr_type;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Information Data                   | 4 to (ATT_MTU-1)  |
+ */
+#define BLE_ATT_FIND_TYPE_VALUE_RSP_BASE_SZ     1
+#define BLE_ATT_FIND_TYPE_VALUE_HINFO_BASE_SZ   4
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Starting Handle                    | 2                 |
+ * | Ending Handle                      | 2                 |
+ * | Attribute Type                     | 2 or 16           |
+ */
+#define BLE_ATT_READ_TYPE_REQ_BASE_SZ   5
+#define BLE_ATT_READ_TYPE_REQ_SZ_16     7
+#define BLE_ATT_READ_TYPE_REQ_SZ_128    21
+struct ble_att_read_type_req {
+    uint16_t batq_start_handle;
+    uint16_t batq_end_handle;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Length                             | 1                 |
+ * | Attribute Data List                | 2 to (ATT_MTU-2)  |
+ */
+#define BLE_ATT_READ_TYPE_RSP_BASE_SZ       2
+struct ble_att_read_type_rsp {
+    uint8_t batp_length;
+} __attribute__((packed));
+
+#define BLE_ATT_READ_TYPE_ADATA_BASE_SZ     2
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Attribute Handle                   | 2                 |
+ */
+#define BLE_ATT_READ_REQ_SZ              3
+struct ble_att_read_req {
+    uint16_t barq_handle;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Attribute Value                    | 0 to (ATT_MTU-1)  |
+ */
+#define BLE_ATT_READ_RSP_BASE_SZ        1
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Attribute Handle                   | 2                 |
+ * | Value Offset                       | 2                 |
+ */
+#define BLE_ATT_READ_BLOB_REQ_SZ        5
+struct ble_att_read_blob_req {
+    uint16_t babq_handle;
+    uint16_t babq_offset;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Attribute Value                    | 0 to (ATT_MTU-1)  |
+ */
+#define BLE_ATT_READ_BLOB_RSP_BASE_SZ   1
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Set Of Handles                     | 4 to (ATT_MTU-1)  |
+ */
+#define BLE_ATT_READ_MULT_REQ_BASE_SZ   1
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Set Of Values                      | 4 to (ATT_MTU-1)  |
+ */
+#define BLE_ATT_READ_MULT_RSP_BASE_SZ   1
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Starting Handle                    | 2                 |
+ * | Ending Handle                      | 2                 |
+ * | Attribute Group Type               | 2 or 16           |
+ */
+#define BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ  5
+#define BLE_ATT_READ_GROUP_TYPE_REQ_SZ_16    7
+#define BLE_ATT_READ_GROUP_TYPE_REQ_SZ_128   21
+struct ble_att_read_group_type_req {
+    uint16_t bagq_start_handle;
+    uint16_t bagq_end_handle;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Length                             | 1                 |
+ * | Attribute Data List                | 2 to (ATT_MTU-2)  |
+ */
+#define BLE_ATT_READ_GROUP_TYPE_RSP_BASE_SZ  2
+struct ble_att_read_group_type_rsp {
+    uint8_t bagp_length;
+} __attribute__((packed));
+
+#define BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ   4
+#define BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_16     6
+#define BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_128    20
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Attribute Handle                   | 2                 |
+ * | Attribute Value                    | 0 to (ATT_MTU-3)  |
+ */
+#define BLE_ATT_WRITE_REQ_BASE_SZ       3
+struct ble_att_write_req {
+    uint16_t bawq_handle;
+} __attribute__((packed));
+
+#define BLE_ATT_WRITE_RSP_SZ            1
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Attribute Handle                   | 2                 |
+ * | Value Offset                       | 2                 |
+ * | Part Attribute Value               | 0 to (ATT_MTU-5)  |
+ */
+#define BLE_ATT_PREP_WRITE_CMD_BASE_SZ  5
+struct ble_att_prep_write_cmd {
+    uint16_t bapc_handle;
+    uint16_t bapc_offset;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Flags                              | 1                 |
+ */
+#define BLE_ATT_EXEC_WRITE_REQ_SZ       2
+struct ble_att_exec_write_req {
+    uint8_t baeq_flags;
+} __attribute__((packed));
+
+#define BLE_ATT_EXEC_WRITE_F_CONFIRM    0x01
+#define BLE_ATT_EXEC_WRITE_F_RESERVED   0xfe
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ */
+#define BLE_ATT_EXEC_WRITE_RSP_SZ       1
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Attribute Handle                   | 2                 |
+ * | Attribute Value                    | 0 to (ATT_MTU-3)  |
+ */
+#define BLE_ATT_NOTIFY_REQ_BASE_SZ      3
+struct ble_att_notify_req {
+    uint16_t banq_handle;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ * | Attribute Handle                   | 2                 |
+ * | Attribute Value                    | 0 to (ATT_MTU-3)  |
+ */
+#define BLE_ATT_INDICATE_REQ_BASE_SZ    3
+struct ble_att_indicate_req {
+    uint16_t baiq_handle;
+} __attribute__((packed));
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | Attribute Opcode                   | 1                 |
+ */
+#define BLE_ATT_INDICATE_RSP_SZ         1
+
+void ble_att_error_rsp_parse(void *payload, int len,
+                              struct ble_att_error_rsp *rsp);
+void ble_att_error_rsp_write(void *payload, int len,
+                              struct ble_att_error_rsp *rsp);
+void ble_att_mtu_cmd_parse(void *payload, int len,
+                            struct ble_att_mtu_cmd *cmd);
+void ble_att_mtu_req_write(void *payload, int len,
+                            struct ble_att_mtu_cmd *cmd);
+void ble_att_mtu_rsp_write(void *payload, int len,
+                           struct ble_att_mtu_cmd *cmd);
+void ble_att_find_info_req_parse(void *payload, int len,
+                                 struct ble_att_find_info_req *req);
+void ble_att_find_info_req_write(void *payload, int len,
+                                 struct ble_att_find_info_req *req);
+void ble_att_find_info_rsp_parse(void *payload, int len,
+                                 struct ble_att_find_info_rsp *rsp);
+void ble_att_find_info_rsp_write(void *payload, int len,
+                                 struct ble_att_find_info_rsp *rsp);
+void ble_att_find_type_value_req_parse(void *payload, int len,
+                                       struct ble_att_find_type_value_req *req);
+void ble_att_find_type_value_req_write(void *payload, int len,
+                                       struct ble_att_find_type_value_req *req);
+void ble_att_read_type_req_parse(void *payload, int len,
+                                 struct ble_att_read_type_req *req);
+void ble_att_read_type_req_write(void *payload, int len,
+                                 struct ble_att_read_type_req *req);
+void ble_att_read_type_rsp_parse(void *payload, int len,
+                                 struct ble_att_read_type_rsp *rsp);
+void ble_att_read_type_rsp_write(void *payload, int len,
+                                 struct ble_att_read_type_rsp *rsp);
+void ble_att_read_req_parse(void *payload, int len,
+                            struct ble_att_read_req *req);
+void ble_att_read_req_write(void *payload, int len,
+                            struct ble_att_read_req *req);
+void ble_att_read_blob_req_parse(void *payload, int len,
+                                 struct ble_att_read_blob_req *req);
+void ble_att_read_blob_req_write(void *payload, int len,
+                                 struct ble_att_read_blob_req *req);
+void ble_att_read_mult_req_parse(void *payload, int len);
+void ble_att_read_mult_req_write(void *payload, int len);
+void ble_att_read_mult_rsp_parse(void *payload, int len);
+void ble_att_read_mult_rsp_write(void *payload, int len);
+void ble_att_read_group_type_req_parse(void *payload, int len,
+                                       struct ble_att_read_group_type_req *req);
+void ble_att_read_group_type_req_write(void *payload, int len,
+                                       struct ble_att_read_group_type_req *req);
+void ble_att_read_group_type_rsp_parse(void *payload, int len,
+                                       struct ble_att_read_group_type_rsp *rsp);
+void ble_att_read_group_type_rsp_write(void *payload, int len,
+                                       struct ble_att_read_group_type_rsp *rsp);
+void ble_att_write_req_parse(void *payload, int len,
+                             struct ble_att_write_req *req);
+void ble_att_write_req_write(void *payload, int len,
+                             struct ble_att_write_req *req);
+void ble_att_write_cmd_parse(void *payload, int len,
+                             struct ble_att_write_req *req);
+void ble_att_write_cmd_write(void *payload, int len,
+                             struct ble_att_write_req *req);
+void ble_att_prep_write_req_parse(void *payload, int len,
+                                  struct ble_att_prep_write_cmd *cmd);
+void ble_att_prep_write_req_write(void *payload, int len,
+                                  struct ble_att_prep_write_cmd *cmd);
+void ble_att_prep_write_rsp_parse(void *payload, int len,
+                                  struct ble_att_prep_write_cmd *cmd);
+void ble_att_prep_write_rsp_write(void *payload, int len,
+                                  struct ble_att_prep_write_cmd *cmd);
+void ble_att_exec_write_req_parse(void *payload, int len,
+                                  struct ble_att_exec_write_req *req);
+void ble_att_exec_write_req_write(void *payload, int len,
+                                  struct ble_att_exec_write_req *req);
+void ble_att_exec_write_rsp_parse(void *payload, int len);
+void ble_att_exec_write_rsp_write(void *payload, int len);
+void ble_att_notify_req_parse(void *payload, int len,
+                              struct ble_att_notify_req *req);
+void ble_att_notify_req_write(void *payload, int len,
+                              struct ble_att_notify_req *req);
+void ble_att_indicate_req_parse(void *payload, int len,
+                                struct ble_att_indicate_req *req);
+void ble_att_indicate_req_write(void *payload, int len,
+                                struct ble_att_indicate_req *req);
+void ble_att_indicate_rsp_parse(void *payload, int len);
+void ble_att_indicate_rsp_write(void *payload, int len);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/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 76b7b0e..f47e9f2 100644
--- a/net/nimble/host/src/ble_hci_cmd.c
+++ b/net/nimble/host/src/ble_hci_cmd.c
@@ -22,7 +22,7 @@
 #include <stdio.h>
 #include "os/os.h"
 #include "ble_hs_priv.h"
-#include "host_dbg.h"
+#include "host_dbg_priv.h"
 
 #define BLE_HCI_CMD_TIMEOUT     (OS_TICKS_PER_SEC)
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_hci_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util.h b/net/nimble/host/src/ble_hci_util.h
deleted file mode 100644
index f73dd47..0000000
--- a/net/nimble/host/src/ble_hci_util.h
+++ /dev/null
@@ -1,27 +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_BLE_HCI_UTIL_
-#define H_BLE_HCI_UTIL_
-
-int ble_hci_util_read_adv_tx_pwr(int8_t *out_pwr);
-int ble_hci_util_rand(void *dst, int len);
-int ble_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_hci_util_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util_priv.h b/net/nimble/host/src/ble_hci_util_priv.h
new file mode 100644
index 0000000..f73dd47
--- /dev/null
+++ b/net/nimble/host/src/ble_hci_util_priv.h
@@ -0,0 +1,27 @@
+/**
+ * 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_BLE_HCI_UTIL_
+#define H_BLE_HCI_UTIL_
+
+int ble_hci_util_read_adv_tx_pwr(int8_t *out_pwr);
+int ble_hci_util_rand(void *dst, int len);
+int ble_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_hs_atomic.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic.h b/net/nimble/host/src/ble_hs_atomic.h
deleted file mode 100644
index 29852f8..0000000
--- a/net/nimble/host/src/ble_hs_atomic.h
+++ /dev/null
@@ -1,30 +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_BLE_HS_ATOMIC_
-#define H_BLE_HS_ATOMIC_
-
-#include "ble_hs_conn.h"
-
-int ble_hs_atomic_conn_delete(uint16_t conn_handle);
-void ble_hs_atomic_conn_insert(struct ble_hs_conn *conn);
-int ble_hs_atomic_conn_flags(uint16_t conn_handle,
-                             ble_hs_conn_flags_t *out_flags);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/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
new file mode 100644
index 0000000..63a9a36
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_atomic_priv.h
@@ -0,0 +1,30 @@
+/**
+ * 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_BLE_HS_ATOMIC_
+#define H_BLE_HS_ATOMIC_
+
+#include "ble_hs_conn_priv.h"
+
+int ble_hs_atomic_conn_delete(uint16_t conn_handle);
+void ble_hs_atomic_conn_insert(struct ble_hs_conn *conn);
+int ble_hs_atomic_conn_flags(uint16_t conn_handle,
+                             ble_hs_conn_flags_t *out_flags);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_hs_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.h b/net/nimble/host/src/ble_hs_conn.h
deleted file mode 100644
index c470c3d..0000000
--- a/net/nimble/host/src/ble_hs_conn.h
+++ /dev/null
@@ -1,74 +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_BLE_HS_CONN_
-#define H_BLE_HS_CONN_
-
-#include "ble_l2cap_priv.h"
-#include "ble_gatt_priv.h"
-#include "ble_att_priv.h"
-struct hci_le_conn_complete;
-struct hci_create_conn;
-struct ble_l2cap_chan;
-
-typedef uint8_t ble_hs_conn_flags_t;
-
-#define BLE_HS_CONN_F_MASTER        0x01
-#define BLE_HS_CONN_F_UPDATE        0x02
-
-struct ble_hs_conn {
-    SLIST_ENTRY(ble_hs_conn) bhc_next;
-    uint16_t bhc_handle;
-    uint8_t bhc_addr_type;
-    uint8_t bhc_addr[6];
-
-    uint16_t bhc_itvl;
-    uint16_t bhc_latency;
-    uint16_t bhc_supervision_timeout;
-
-    ble_hs_conn_flags_t bhc_flags;
-
-    struct ble_l2cap_chan_list bhc_channels;
-    struct ble_l2cap_chan *bhc_rx_chan; /* Channel rxing current packet. */
-    uint16_t bhc_outstanding_pkts;
-
-    struct ble_att_svr_conn bhc_att_svr;
-    struct ble_gatts_conn bhc_gatt_svr;
-
-    struct ble_gap_sec_params bhc_sec_params;
-
-    ble_gap_conn_fn *bhc_cb;
-    void *bhc_cb_arg;
-};
-
-int ble_hs_conn_can_alloc(void);
-struct ble_hs_conn *ble_hs_conn_alloc(void);
-void ble_hs_conn_free(struct ble_hs_conn *conn);
-void ble_hs_conn_insert(struct ble_hs_conn *conn);
-void ble_hs_conn_remove(struct ble_hs_conn *conn);
-struct ble_hs_conn *ble_hs_conn_find(uint16_t conn_handle);
-int ble_hs_conn_exists(uint16_t conn_handle);
-struct ble_hs_conn *ble_hs_conn_first(void);
-struct ble_l2cap_chan *ble_hs_conn_chan_find(struct ble_hs_conn *conn,
-                                             uint16_t cid);
-int ble_hs_conn_chan_insert(struct ble_hs_conn *conn,
-                            struct ble_l2cap_chan *chan);
-int ble_hs_conn_init(void);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_hs_conn_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn_priv.h b/net/nimble/host/src/ble_hs_conn_priv.h
new file mode 100644
index 0000000..c470c3d
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_conn_priv.h
@@ -0,0 +1,74 @@
+/**
+ * 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_BLE_HS_CONN_
+#define H_BLE_HS_CONN_
+
+#include "ble_l2cap_priv.h"
+#include "ble_gatt_priv.h"
+#include "ble_att_priv.h"
+struct hci_le_conn_complete;
+struct hci_create_conn;
+struct ble_l2cap_chan;
+
+typedef uint8_t ble_hs_conn_flags_t;
+
+#define BLE_HS_CONN_F_MASTER        0x01
+#define BLE_HS_CONN_F_UPDATE        0x02
+
+struct ble_hs_conn {
+    SLIST_ENTRY(ble_hs_conn) bhc_next;
+    uint16_t bhc_handle;
+    uint8_t bhc_addr_type;
+    uint8_t bhc_addr[6];
+
+    uint16_t bhc_itvl;
+    uint16_t bhc_latency;
+    uint16_t bhc_supervision_timeout;
+
+    ble_hs_conn_flags_t bhc_flags;
+
+    struct ble_l2cap_chan_list bhc_channels;
+    struct ble_l2cap_chan *bhc_rx_chan; /* Channel rxing current packet. */
+    uint16_t bhc_outstanding_pkts;
+
+    struct ble_att_svr_conn bhc_att_svr;
+    struct ble_gatts_conn bhc_gatt_svr;
+
+    struct ble_gap_sec_params bhc_sec_params;
+
+    ble_gap_conn_fn *bhc_cb;
+    void *bhc_cb_arg;
+};
+
+int ble_hs_conn_can_alloc(void);
+struct ble_hs_conn *ble_hs_conn_alloc(void);
+void ble_hs_conn_free(struct ble_hs_conn *conn);
+void ble_hs_conn_insert(struct ble_hs_conn *conn);
+void ble_hs_conn_remove(struct ble_hs_conn *conn);
+struct ble_hs_conn *ble_hs_conn_find(uint16_t conn_handle);
+int ble_hs_conn_exists(uint16_t conn_handle);
+struct ble_hs_conn *ble_hs_conn_first(void);
+struct ble_l2cap_chan *ble_hs_conn_chan_find(struct ble_hs_conn *conn,
+                                             uint16_t cid);
+int ble_hs_conn_chan_insert(struct ble_hs_conn *conn,
+                            struct ble_l2cap_chan *chan);
+int ble_hs_conn_init(void);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_hs_endian.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_endian.h b/net/nimble/host/src/ble_hs_endian.h
deleted file mode 100644
index c2342ff..0000000
--- a/net/nimble/host/src/ble_hs_endian.h
+++ /dev/null
@@ -1,57 +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_BLE_HS_ENDIAN_
-#define H_BLE_HS_ENDIAN_
-
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-
-#define TOFROMLE16(x)   ((uint16_t) (x))
-#define TOFROMLE32(x)   ((uint32_t) (x))
-#define TOFROMLE64(x)   ((uint64_t) (x))
-
-#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-
-#define TOFROMLE16(x)   ((uint16_t)                                 \
-                         ((((x) & 0xff00) >> 8) |                   \
-                          (((x) & 0x00ff) << 8)))
-
-#define TOFROMLE32(x)  ((uint32_t)                                  \
-                         ((((x) & 0xff000000) >> 24) |              \
-                          (((x) & 0x00ff0000) >>  8) |              \
-                          (((x) & 0x0000ff00) <<  8) |              \
-                          (((x) & 0x000000ff) << 24)))
-
-#define TOFROMLE64(x)  ((uint64_t)                                  \
-                         ((((x) & 0xff00000000000000ull) >> 56) |   \
-                          (((x) & 0x00ff000000000000ull) >> 40) |   \
-                          (((x) & 0x0000ff0000000000ull) >> 24) |   \
-                          (((x) & 0x000000ff00000000ull) >>  8) |   \
-                          (((x) & 0x00000000ff000000ull) <<  8) |   \
-                          (((x) & 0x0000000000ff0000ull) << 24) |   \
-                          (((x) & 0x000000000000ff00ull) << 40) |   \
-                          (((x) & 0x00000000000000ffull) << 56)))
-
-#else
-
-#error Unsupported endianness.
-
-#endif
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_hs_endian_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_endian_priv.h b/net/nimble/host/src/ble_hs_endian_priv.h
new file mode 100644
index 0000000..c2342ff
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_endian_priv.h
@@ -0,0 +1,57 @@
+/**
+ * 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_BLE_HS_ENDIAN_
+#define H_BLE_HS_ENDIAN_
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+
+#define TOFROMLE16(x)   ((uint16_t) (x))
+#define TOFROMLE32(x)   ((uint32_t) (x))
+#define TOFROMLE64(x)   ((uint64_t) (x))
+
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+
+#define TOFROMLE16(x)   ((uint16_t)                                 \
+                         ((((x) & 0xff00) >> 8) |                   \
+                          (((x) & 0x00ff) << 8)))
+
+#define TOFROMLE32(x)  ((uint32_t)                                  \
+                         ((((x) & 0xff000000) >> 24) |              \
+                          (((x) & 0x00ff0000) >>  8) |              \
+                          (((x) & 0x0000ff00) <<  8) |              \
+                          (((x) & 0x000000ff) << 24)))
+
+#define TOFROMLE64(x)  ((uint64_t)                                  \
+                         ((((x) & 0xff00000000000000ull) >> 56) |   \
+                          (((x) & 0x00ff000000000000ull) >> 40) |   \
+                          (((x) & 0x0000ff0000000000ull) >> 24) |   \
+                          (((x) & 0x000000ff00000000ull) >>  8) |   \
+                          (((x) & 0x00000000ff000000ull) <<  8) |   \
+                          (((x) & 0x0000000000ff0000ull) << 24) |   \
+                          (((x) & 0x000000000000ff00ull) << 40) |   \
+                          (((x) & 0x00000000000000ffull) << 56)))
+
+#else
+
+#error Unsupported endianness.
+
+#endif
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/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 cf77b9e..024b964 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -22,19 +22,19 @@
 
 #include <assert.h>
 #include <inttypes.h>
-#include "ble_att_cmd.h"
+#include "ble_att_cmd_priv.h"
 #include "ble_att_priv.h"
 #include "ble_gap_priv.h"
 #include "ble_gatt_priv.h"
-#include "ble_hci_util.h"
+#include "ble_hci_util_priv.h"
 #include "ble_hs_adv_priv.h"
-#include "ble_hs_atomic.h"
-#include "ble_hs_conn.h"
-#include "ble_hs_endian.h"
-#include "ble_hs_startup.h"
+#include "ble_hs_atomic_priv.h"
+#include "ble_hs_conn_priv.h"
+#include "ble_hs_endian_priv.h"
+#include "ble_hs_startup_priv.h"
 #include "ble_l2cap_priv.h"
-#include "ble_l2cap_sig.h"
-#include "ble_l2cap_sm.h"
+#include "ble_l2cap_sig_priv.h"
+#include "ble_l2cap_sm_priv.h"
 #include "host/ble_hs.h"
 #include "log/log.h"
 #include "nimble/nimble_opt.h"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_hs_startup.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_startup.h b/net/nimble/host/src/ble_hs_startup.h
deleted file mode 100644
index 2a5867e..0000000
--- a/net/nimble/host/src/ble_hs_startup.h
+++ /dev/null
@@ -1,25 +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_BLE_HS_STARTUP_
-#define H_BLE_HS_STARTUP_
-
-int ble_hs_startup_go(void);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_hs_startup_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_startup_priv.h b/net/nimble/host/src/ble_hs_startup_priv.h
new file mode 100644
index 0000000..2a5867e
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_startup_priv.h
@@ -0,0 +1,25 @@
+/**
+ * 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_BLE_HS_STARTUP_
+#define H_BLE_HS_STARTUP_
+
+int ble_hs_startup_go(void);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_l2cap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_priv.h b/net/nimble/host/src/ble_l2cap_priv.h
index 2a728fc..ecf7d17 100644
--- a/net/nimble/host/src/ble_l2cap_priv.h
+++ b/net/nimble/host/src/ble_l2cap_priv.h
@@ -42,59 +42,18 @@ STATS_SECT_START(ble_l2cap_stats)
 STATS_SECT_END
 extern STATS_SECT_DECL(ble_l2cap_stats) ble_l2cap_stats;
 
-#define BLE_L2CAP_SIG_HDR_SZ                4
-struct ble_l2cap_sig_hdr {
-    uint8_t op;
-    uint8_t identifier;
-    uint16_t length;
-} __attribute__((packed));
-
-#define BLE_L2CAP_SIG_REJECT_MIN_SZ         2
-struct ble_l2cap_sig_reject {
-    uint16_t reason;
-} __attribute__((packed));
-
-#define BLE_L2CAP_SIG_UPDATE_REQ_SZ         8
-struct ble_l2cap_sig_update_req {
-    uint16_t itvl_min;
-    uint16_t itvl_max;
-    uint16_t slave_latency;
-    uint16_t timeout_multiplier;
-} __attribute__((packed));
-
-#define BLE_L2CAP_SIG_UPDATE_RSP_SZ         2
-struct ble_l2cap_sig_update_rsp {
-    uint16_t result;
-} __attribute__((packed));
-
-#define BLE_L2CAP_SIG_UPDATE_RSP_RESULT_ACCEPT  0x0000
-#define BLE_L2CAP_SIG_UPDATE_RSP_RESULT_REJECT  0x0001
-
 #define BLE_L2CAP_CID_ATT   4
 #define BLE_L2CAP_CID_SIG   5
 #define BLE_L2CAP_CID_SM    6
 
 #define BLE_L2CAP_HDR_SZ    4
 
-struct ble_l2cap_hdr
-{
-    uint16_t blh_len;
-    uint16_t blh_cid;
-};
-
-struct ble_l2cap_chan;
+typedef uint8_t ble_l2cap_chan_flags;
 
 typedef int ble_l2cap_rx_fn(uint16_t conn_handle,
                             struct os_mbuf **om);
 
-typedef int ble_l2cap_tx_fn(struct ble_hs_conn *conn,
-                            struct ble_l2cap_chan *chan);
-
-typedef uint8_t ble_l2cap_chan_flags;
-#define BLE_L2CAP_CHAN_F_TXED_MTU       0x01    /* We have sent our MTU. */
-
-struct ble_l2cap_chan
-{
+struct ble_l2cap_chan {
     SLIST_ENTRY(ble_l2cap_chan) blc_next;
     uint16_t blc_cid;
     uint16_t blc_my_mtu;
@@ -108,6 +67,15 @@ struct ble_l2cap_chan
     ble_l2cap_rx_fn *blc_rx_fn;
 };
 
+struct ble_l2cap_hdr {
+    uint16_t blh_len;
+    uint16_t blh_cid;
+};
+
+typedef int ble_l2cap_tx_fn(struct ble_hs_conn *conn,
+                            struct ble_l2cap_chan *chan);
+
+#define BLE_L2CAP_CHAN_F_TXED_MTU       0x01    /* We have sent our MTU. */
 
 SLIST_HEAD(ble_l2cap_chan_list, ble_l2cap_chan);
 
@@ -116,26 +84,6 @@ int ble_l2cap_parse_hdr(struct os_mbuf *om, int off,
 struct os_mbuf *ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid,
                                       uint16_t len);
 
-int ble_l2cap_sig_init_cmd(uint8_t op, uint8_t id, uint8_t payload_len,
-                           struct os_mbuf **out_om, void **out_payload_buf);
-void ble_l2cap_sig_hdr_parse(void *payload, uint16_t len,
-                             struct ble_l2cap_sig_hdr *hdr);
-void ble_l2cap_sig_hdr_write(void *payload, uint16_t len,
-                             struct ble_l2cap_sig_hdr *hdr);
-int ble_l2cap_sig_reject_tx(uint16_t conn_handle, uint8_t id, uint16_t reason);
-void ble_l2cap_sig_update_req_parse(void *payload, int len,
-                                    struct ble_l2cap_sig_update_req *req);
-void ble_l2cap_sig_update_req_write(void *payload, int len,
-                                    struct ble_l2cap_sig_update_req *src);
-int ble_l2cap_sig_update_req_tx(uint16_t conn_handle, uint8_t id,
-                                struct ble_l2cap_sig_update_req *req);
-void ble_l2cap_sig_update_rsp_parse(void *payload, int len,
-                                    struct ble_l2cap_sig_update_rsp *cmd);
-void ble_l2cap_sig_update_rsp_write(void *payload, int len,
-                                    struct ble_l2cap_sig_update_rsp *src);
-int ble_l2cap_sig_update_rsp_tx(uint16_t conn_handle, uint8_t id,
-                                uint16_t result);
-
 struct ble_l2cap_chan *ble_l2cap_chan_alloc(void);
 void ble_l2cap_chan_free(struct ble_l2cap_chan *chan);
 
@@ -150,8 +98,6 @@ int ble_l2cap_rx(struct ble_hs_conn *conn,
 int ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                  struct os_mbuf *om);
 
-void ble_l2cap_sig_heartbeat(void);
-int ble_l2cap_sig_init(void);
 int ble_l2cap_init(void);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_l2cap_sig.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig.h b/net/nimble/host/src/ble_l2cap_sig.h
deleted file mode 100644
index b46f17a..0000000
--- a/net/nimble/host/src/ble_l2cap_sig.h
+++ /dev/null
@@ -1,27 +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_BLE_L2CAP_SIG_
-#define H_BLE_L2CAP_SIG_
-
-#define BLE_L2CAP_SIG_MTU           100  /* This is our own default. */
-
-struct ble_l2cap_chan *ble_l2cap_sig_create_chan(void);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_l2cap_sig_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_priv.h b/net/nimble/host/src/ble_l2cap_sig_priv.h
new file mode 100644
index 0000000..da6d3b4
--- /dev/null
+++ b/net/nimble/host/src/ble_l2cap_sig_priv.h
@@ -0,0 +1,77 @@
+/**
+ * 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_BLE_L2CAP_SIG_
+#define H_BLE_L2CAP_SIG_
+
+#define BLE_L2CAP_SIG_MTU           100  /* This is our own default. */
+
+#define BLE_L2CAP_SIG_HDR_SZ                4
+struct ble_l2cap_sig_hdr {
+    uint8_t op;
+    uint8_t identifier;
+    uint16_t length;
+} __attribute__((packed));
+
+#define BLE_L2CAP_SIG_REJECT_MIN_SZ         2
+struct ble_l2cap_sig_reject {
+    uint16_t reason;
+} __attribute__((packed));
+
+#define BLE_L2CAP_SIG_UPDATE_REQ_SZ         8
+struct ble_l2cap_sig_update_req {
+    uint16_t itvl_min;
+    uint16_t itvl_max;
+    uint16_t slave_latency;
+    uint16_t timeout_multiplier;
+} __attribute__((packed));
+
+#define BLE_L2CAP_SIG_UPDATE_RSP_SZ         2
+struct ble_l2cap_sig_update_rsp {
+    uint16_t result;
+} __attribute__((packed));
+
+#define BLE_L2CAP_SIG_UPDATE_RSP_RESULT_ACCEPT  0x0000
+#define BLE_L2CAP_SIG_UPDATE_RSP_RESULT_REJECT  0x0001
+
+int ble_l2cap_sig_init_cmd(uint8_t op, uint8_t id, uint8_t payload_len,
+                           struct os_mbuf **out_om, void **out_payload_buf);
+void ble_l2cap_sig_hdr_parse(void *payload, uint16_t len,
+                             struct ble_l2cap_sig_hdr *hdr);
+void ble_l2cap_sig_hdr_write(void *payload, uint16_t len,
+                             struct ble_l2cap_sig_hdr *hdr);
+int ble_l2cap_sig_reject_tx(uint16_t conn_handle, uint8_t id, uint16_t reason);
+void ble_l2cap_sig_update_req_parse(void *payload, int len,
+                                    struct ble_l2cap_sig_update_req *req);
+void ble_l2cap_sig_update_req_write(void *payload, int len,
+                                    struct ble_l2cap_sig_update_req *src);
+int ble_l2cap_sig_update_req_tx(uint16_t conn_handle, uint8_t id,
+                                struct ble_l2cap_sig_update_req *req);
+void ble_l2cap_sig_update_rsp_parse(void *payload, int len,
+                                    struct ble_l2cap_sig_update_rsp *cmd);
+void ble_l2cap_sig_update_rsp_write(void *payload, int len,
+                                    struct ble_l2cap_sig_update_rsp *src);
+int ble_l2cap_sig_update_rsp_tx(uint16_t conn_handle, uint8_t id,
+                                uint16_t result);
+
+void ble_l2cap_sig_heartbeat(void);
+struct ble_l2cap_chan *ble_l2cap_sig_create_chan(void);
+int ble_l2cap_sig_init(void);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_l2cap_sm.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.h b/net/nimble/host/src/ble_l2cap_sm.h
deleted file mode 100644
index 9ecbeaf..0000000
--- a/net/nimble/host/src/ble_l2cap_sm.h
+++ /dev/null
@@ -1,161 +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_BLE_L2CAP_SM_
-#define H_BLE_L2CAP_SM_
-
-struct ble_gap_sec_params;
-struct hci_le_lt_key_req;
-
-#define BLE_L2CAP_SM_MTU            65
-
-#define BLE_L2CAP_SM_HDR_SZ         1
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | (Code=0x01/0x02 [req/rsp])         | 1                 |
- * | IO Capability                      | 1                 |
- * | OOB data flag                      | 1                 |
- * | AuthReq                            | 1                 |
- * | Maximum Encryption Key Size        | 1                 |
- * | Initiator Key Distribution         | 1                 |
- * | Responder Key Distribution         | 1                 |
- */
-#define BLE_L2CAP_SM_PAIR_CMD_SZ        6
-struct ble_l2cap_sm_pair_cmd {
-    uint8_t io_cap;
-    uint8_t oob_data_flag;
-    uint8_t authreq;
-    uint8_t max_enc_key_size;
-    uint8_t init_key_dist;
-    uint8_t resp_key_dist;
-};
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | (Code=0x03)                        | 1                 |
- * | Confirm Value                      | 16                |
- */
-#define BLE_L2CAP_SM_PAIR_CONFIRM_SZ    16
-struct ble_l2cap_sm_pair_confirm {
-    uint8_t value[16];
-};
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | (Code=0x04)                        | 1                 |
- * | Random Value                       | 16                |
- */
-#define BLE_L2CAP_SM_PAIR_RANDOM_SZ     16
-struct ble_l2cap_sm_pair_random {
-    uint8_t value[16];
-};
-
-/**
- * | Parameter                          | Size (octets)     |
- * +------------------------------------+-------------------+
- * | (Code=0x05)                        | 1                 |
- * | Reason                             | 1                 |
- */
-#define BLE_L2CAP_SM_PAIR_FAIL_SZ       1
-struct ble_l2cap_sm_pair_fail {
-    uint8_t reason;
-};
-
-#if NIMBLE_OPT_SM
-
-#ifdef BLE_HS_DEBUG
-void ble_l2cap_sm_dbg_set_next_pair_rand(uint8_t *next_pair_rand);
-void ble_l2cap_sm_dbg_set_next_ediv(uint16_t next_ediv);
-void ble_l2cap_sm_dbg_set_next_start_rand(uint64_t next_start_rand);
-int ble_l2cap_sm_dbg_num_procs(void);
-#endif
-
-struct ble_l2cap_chan *ble_l2cap_sm_create_chan(void);
-
-void ble_l2cap_sm_pair_cmd_parse(void *payload, int len,
-                                 struct ble_l2cap_sm_pair_cmd *cmd);
-void ble_l2cap_sm_pair_cmd_write(void *payload, int len, int is_req,
-                                 struct ble_l2cap_sm_pair_cmd *cmd);
-int ble_l2cap_sm_pair_cmd_tx(uint16_t conn_handle, int is_req,
-                             struct ble_l2cap_sm_pair_cmd *cmd);
-void ble_l2cap_sm_pair_confirm_parse(void *payload, int len,
-                                     struct ble_l2cap_sm_pair_confirm *cmd);
-void ble_l2cap_sm_pair_confirm_write(void *payload, int len,
-                                     struct ble_l2cap_sm_pair_confirm *cmd);
-int ble_l2cap_sm_pair_confirm_tx(uint16_t conn_handle,
-                                 struct ble_l2cap_sm_pair_confirm *cmd);
-void ble_l2cap_sm_pair_random_parse(void *payload, int len,
-                                    struct ble_l2cap_sm_pair_random *cmd);
-void ble_l2cap_sm_pair_random_write(void *payload, int len,
-                                    struct ble_l2cap_sm_pair_random *cmd);
-int ble_l2cap_sm_pair_random_tx(uint16_t conn_handle,
-                                struct ble_l2cap_sm_pair_random *cmd);
-void ble_l2cap_sm_pair_fail_parse(void *payload, int len,
-                                  struct ble_l2cap_sm_pair_fail *cmd);
-void ble_l2cap_sm_pair_fail_write(void *payload, int len,
-                                  struct ble_l2cap_sm_pair_fail *cmd);
-int ble_l2cap_sm_pair_fail_tx(uint16_t conn_handle, uint8_t reason);
-
-int ble_l2cap_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out);
-int ble_l2cap_sm_alg_c1(uint8_t *k, uint8_t *r,
-                        uint8_t *preq, uint8_t *pres,
-                        uint8_t iat, uint8_t rat,
-                        uint8_t *ia, uint8_t *ra,
-                        uint8_t *out_enc_data);
-
-void ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt);
-int ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt);
-
-void ble_l2cap_sm_heartbeat(void);
-int ble_l2cap_sm_initiate(uint16_t conn_handle);
-int ble_l2cap_sm_init(void);
-
-#else
-
-#ifdef BLE_HS_DEBUG
-#define ble_l2cap_sm_dbg_set_next_rand(next_rand)
-#define ble_l2cap_sm_dbg_num_procs() 0
-#endif
-
-#define ble_l2cap_sm_create_chan() NULL
-
-#define ble_l2cap_sm_pair_cmd_tx(conn_handle, is_req, cmd) BLE_HS_ENOTSUP
-#define ble_l2cap_sm_pair_confirm_tx(conn_handle, cmd) BLE_HS_ENOTSUP
-#define ble_l2cap_sm_pair_random_tx(conn_handle, cmd) BLE_HS_ENOTSUP
-#define ble_l2cap_sm_pair_fail_tx(conn_handle, cmd) BLE_HS_ENOTSUP
-
-#define ble_l2cap_sm_alg_s1(k, r1, r2, out) BLE_HS_ENOTSUP
-#define ble_l2cap_sm_alg_c1(k, r, preq, pres, iat, rat, ia, ra, out_enc_data) \
-    BLE_HS_ENOTSUP
-
-#define ble_l2cap_sm_rx_encryption_change(evt) ((void)(evt))
-#define ble_l2cap_sm_rx_lt_key_req(evt) ((void)(evt))
-
-#define ble_l2cap_sm_connection_broken(conn_handle)
-
-#define ble_l2cap_sm_heartbeat()
-#define ble_l2cap_sm_init() 0
-
-#endif
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/ble_l2cap_sm_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm_priv.h b/net/nimble/host/src/ble_l2cap_sm_priv.h
new file mode 100644
index 0000000..9ecbeaf
--- /dev/null
+++ b/net/nimble/host/src/ble_l2cap_sm_priv.h
@@ -0,0 +1,161 @@
+/**
+ * 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_BLE_L2CAP_SM_
+#define H_BLE_L2CAP_SM_
+
+struct ble_gap_sec_params;
+struct hci_le_lt_key_req;
+
+#define BLE_L2CAP_SM_MTU            65
+
+#define BLE_L2CAP_SM_HDR_SZ         1
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | (Code=0x01/0x02 [req/rsp])         | 1                 |
+ * | IO Capability                      | 1                 |
+ * | OOB data flag                      | 1                 |
+ * | AuthReq                            | 1                 |
+ * | Maximum Encryption Key Size        | 1                 |
+ * | Initiator Key Distribution         | 1                 |
+ * | Responder Key Distribution         | 1                 |
+ */
+#define BLE_L2CAP_SM_PAIR_CMD_SZ        6
+struct ble_l2cap_sm_pair_cmd {
+    uint8_t io_cap;
+    uint8_t oob_data_flag;
+    uint8_t authreq;
+    uint8_t max_enc_key_size;
+    uint8_t init_key_dist;
+    uint8_t resp_key_dist;
+};
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | (Code=0x03)                        | 1                 |
+ * | Confirm Value                      | 16                |
+ */
+#define BLE_L2CAP_SM_PAIR_CONFIRM_SZ    16
+struct ble_l2cap_sm_pair_confirm {
+    uint8_t value[16];
+};
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | (Code=0x04)                        | 1                 |
+ * | Random Value                       | 16                |
+ */
+#define BLE_L2CAP_SM_PAIR_RANDOM_SZ     16
+struct ble_l2cap_sm_pair_random {
+    uint8_t value[16];
+};
+
+/**
+ * | Parameter                          | Size (octets)     |
+ * +------------------------------------+-------------------+
+ * | (Code=0x05)                        | 1                 |
+ * | Reason                             | 1                 |
+ */
+#define BLE_L2CAP_SM_PAIR_FAIL_SZ       1
+struct ble_l2cap_sm_pair_fail {
+    uint8_t reason;
+};
+
+#if NIMBLE_OPT_SM
+
+#ifdef BLE_HS_DEBUG
+void ble_l2cap_sm_dbg_set_next_pair_rand(uint8_t *next_pair_rand);
+void ble_l2cap_sm_dbg_set_next_ediv(uint16_t next_ediv);
+void ble_l2cap_sm_dbg_set_next_start_rand(uint64_t next_start_rand);
+int ble_l2cap_sm_dbg_num_procs(void);
+#endif
+
+struct ble_l2cap_chan *ble_l2cap_sm_create_chan(void);
+
+void ble_l2cap_sm_pair_cmd_parse(void *payload, int len,
+                                 struct ble_l2cap_sm_pair_cmd *cmd);
+void ble_l2cap_sm_pair_cmd_write(void *payload, int len, int is_req,
+                                 struct ble_l2cap_sm_pair_cmd *cmd);
+int ble_l2cap_sm_pair_cmd_tx(uint16_t conn_handle, int is_req,
+                             struct ble_l2cap_sm_pair_cmd *cmd);
+void ble_l2cap_sm_pair_confirm_parse(void *payload, int len,
+                                     struct ble_l2cap_sm_pair_confirm *cmd);
+void ble_l2cap_sm_pair_confirm_write(void *payload, int len,
+                                     struct ble_l2cap_sm_pair_confirm *cmd);
+int ble_l2cap_sm_pair_confirm_tx(uint16_t conn_handle,
+                                 struct ble_l2cap_sm_pair_confirm *cmd);
+void ble_l2cap_sm_pair_random_parse(void *payload, int len,
+                                    struct ble_l2cap_sm_pair_random *cmd);
+void ble_l2cap_sm_pair_random_write(void *payload, int len,
+                                    struct ble_l2cap_sm_pair_random *cmd);
+int ble_l2cap_sm_pair_random_tx(uint16_t conn_handle,
+                                struct ble_l2cap_sm_pair_random *cmd);
+void ble_l2cap_sm_pair_fail_parse(void *payload, int len,
+                                  struct ble_l2cap_sm_pair_fail *cmd);
+void ble_l2cap_sm_pair_fail_write(void *payload, int len,
+                                  struct ble_l2cap_sm_pair_fail *cmd);
+int ble_l2cap_sm_pair_fail_tx(uint16_t conn_handle, uint8_t reason);
+
+int ble_l2cap_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out);
+int ble_l2cap_sm_alg_c1(uint8_t *k, uint8_t *r,
+                        uint8_t *preq, uint8_t *pres,
+                        uint8_t iat, uint8_t rat,
+                        uint8_t *ia, uint8_t *ra,
+                        uint8_t *out_enc_data);
+
+void ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt);
+int ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt);
+
+void ble_l2cap_sm_heartbeat(void);
+int ble_l2cap_sm_initiate(uint16_t conn_handle);
+int ble_l2cap_sm_init(void);
+
+#else
+
+#ifdef BLE_HS_DEBUG
+#define ble_l2cap_sm_dbg_set_next_rand(next_rand)
+#define ble_l2cap_sm_dbg_num_procs() 0
+#endif
+
+#define ble_l2cap_sm_create_chan() NULL
+
+#define ble_l2cap_sm_pair_cmd_tx(conn_handle, is_req, cmd) BLE_HS_ENOTSUP
+#define ble_l2cap_sm_pair_confirm_tx(conn_handle, cmd) BLE_HS_ENOTSUP
+#define ble_l2cap_sm_pair_random_tx(conn_handle, cmd) BLE_HS_ENOTSUP
+#define ble_l2cap_sm_pair_fail_tx(conn_handle, cmd) BLE_HS_ENOTSUP
+
+#define ble_l2cap_sm_alg_s1(k, r1, r2, out) BLE_HS_ENOTSUP
+#define ble_l2cap_sm_alg_c1(k, r, preq, pres, iat, rat, ia, ra, out_enc_data) \
+    BLE_HS_ENOTSUP
+
+#define ble_l2cap_sm_rx_encryption_change(evt) ((void)(evt))
+#define ble_l2cap_sm_rx_lt_key_req(evt) ((void)(evt))
+
+#define ble_l2cap_sm_connection_broken(conn_handle)
+
+#define ble_l2cap_sm_heartbeat()
+#define ble_l2cap_sm_init() 0
+
+#endif
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/host_dbg.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_dbg.h b/net/nimble/host/src/host_dbg.h
deleted file mode 100644
index 8d548ca..0000000
--- a/net/nimble/host/src/host_dbg.h
+++ /dev/null
@@ -1,25 +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_HOST_DBG_
-#define H_HOST_DBG_
-
-void host_hci_dbg_event_disp(uint8_t *evbuf);
-
-#endif /* H_HOST_DBG_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/net/nimble/host/src/host_dbg_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_dbg_priv.h b/net/nimble/host/src/host_dbg_priv.h
new file mode 100644
index 0000000..8d548ca
--- /dev/null
+++ b/net/nimble/host/src/host_dbg_priv.h
@@ -0,0 +1,25 @@
+/**
+ * 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_HOST_DBG_
+#define H_HOST_DBG_
+
+void host_hci_dbg_event_disp(uint8_t *evbuf);
+
+#endif /* H_HOST_DBG_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/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 4994cb6..a030c89 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -26,7 +26,7 @@
 #include "nimble/hci_transport.h"
 #include "host/host_hci.h"
 #include "ble_hs_priv.h"
-#include "host_dbg.h"
+#include "host_dbg_priv.h"
 
 _Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ,
                "struct hci_data_hdr must be 4 bytes");

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/832637db/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 8ed0395..c8c79f1 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -26,7 +26,7 @@
 #include "nimble/hci_common.h"
 #include "nimble/hci_transport.h"
 #include "host/host_hci.h"
-#include "host_dbg.h"
+#include "host_dbg_priv.h"
 #include "ble_hs_priv.h"
 #ifdef PHONY_TRANSPORT
 #include "host/ble_hs_test.h"


[31/50] [abbrv] incubator-mynewt-core git commit: changes to support APi review by Greg. Also changed the start/stop API to begin/end to differentiate from the i2c bus start/stop conditions

Posted by ma...@apache.org.
changes to support APi review by Greg.  Also changed the start/stop API
to begin/end to differentiate from the i2c bus start/stop conditions


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

Branch: refs/heads/master
Commit: 0892fd98e40a9cdf295fa99b1041822cc9a89519
Parents: 4d0a387
Author: Paul Dietrich <pa...@yahoo.com>
Authored: Thu Apr 21 10:30:31 2016 -0700
Committer: Paul Dietrich <pa...@yahoo.com>
Committed: Thu Apr 21 10:32:32 2016 -0700

----------------------------------------------------------------------
 hw/hal/include/hal/hal_i2c.h | 86 ++++++++++++++++++++++++++-------------
 hw/hal/src/hal_i2c.c         |  5 +--
 2 files changed, 59 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0892fd98/hw/hal/include/hal/hal_i2c.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_i2c.h b/hw/hal/include/hal/hal_i2c.h
index 82546d4..20b697d 100644
--- a/hw/hal/include/hal/hal_i2c.h
+++ b/hw/hal/include/hal/hal_i2c.h
@@ -20,64 +20,92 @@
 #ifndef HAL_I2C_H
 #define HAL_I2C_H
 
+#include <inttypes.h>
+#include <bsp/bsp_sysid.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#include <inttypes.h>
-#include <bsp/bsp_sysid.h>
-
-/* This is the API for an i2c bus.  I tried to make this a simple API */
+/* This is the API for an i2c bus.  Currently, this is a master API
+ * allowing the mynewt device to function as an I2C master.
+ *
+ * A slave API is pending for future release
+ * 
+ * Typical usage of this API is as follows:
+ * 
+ * Initialize an i2c device with 
+ *      hal_i2c_init()
+ * 
+ * When you with to perform an i2c transaction, issue
+ *      hal_i2c_master_begin()l
+ * followed by the transaction.  For example, in an I2C memory access access
+ * you might write and address and then read back data
+ *      hal_i2c_write(); -- write amemory ddress to device
+ *      hal_i2c_read(); --- read back data
+ * then end the transaction 
+ *      hal_i2c_end();
+ */
 
 struct hal_i2c;
 
 /* when sending a packet, use this structure to pass the arguments */
 struct hal_i2c_master_data {
     uint8_t  address;   /* destination address */
-            /* NOTE: Write addresses are even and read addresses are odd
-             * but in this API, you must enter a single address that is the
-             * write address divide by 2.  For example, for address 
-             * 80, you would enter a 40 */
+            /* a I2C address has 7 bits. In the protocol these 
+             * 7 bits are combined with a 1 bit R/W bit to specify read
+             * or write operation in an 8-bit address field sent to 
+             * the remote device .  This API accepts the 7-bit
+             * address as its argument in the 7 LSBs of the 
+             * address field above.  For example if I2C was 
+             * writing a 0x81 in its protocol, you would pass
+             * only the top 7-bits to this function as 0x40 */
+    uint16_t len;       /* number of buffer bytes to transmit or receive */
     uint8_t *buffer;    /* buffer space to hold the transmit or receive */
-    uint16_t len;       /* length of buffer to transmit or receive */
 };
 
 /* Initialize a new i2c device with the given system id.
- * Returns negative on error, 0 on success. */
+ * Returns a pointer to the i2c device or NULL on error  */
 struct hal_i2c*
 hal_i2c_init(enum system_device_id sysid);
 
-/* Sends <len> bytes of data on the i2c.  This API assumes that you 
- * issued a successful start condition.  It will fail if you
- * have not. This API does NOT issue a stop condition.  You must stop the 
- * bus after successful or unsuccessful write attempts.  Returns 0 on 
- * success, negative on failure */
+/* Sends a start condition and writes <len> bytes of data on the i2c.  
+ * This API assumes that you have already called hal_i2c_master_begin
+ *  It will fail if you have not. This API does NOT issue a stop condition.  
+ * You must stop the bus after successful or unsuccessful write attempts.  
+ * This API is blocking until an error or NaK occurs. Timeout is platform
+ * dependent
+ * Returns 0 on success, negative on failure */
 int
 hal_i2c_master_write(struct hal_i2c*, struct hal_i2c_master_data *pdata);
 
-/* Reads <len> bytes of data on the i2c.  This API assumes that you 
- * issued a successful start condition.  It will fail if you
- * have not. This API does NOT issue a stop condition.  You must stop the 
- * bus after successful or unsuccessful write attempts.  Returns 0 on 
- * success, negative on failure */
+/* Sends a start condition and reads <len> bytes of data on the i2c.  
+ * This API assumes that you have already called hal_i2c_master_begin
+ *  It will fail if you have not. This API does NOT issue a stop condition.  
+ * You must stop the bus after successful or unsuccessful write attempts.  
+ * This API is blocking until an error or NaK occurs. Timeout is platform
+ * dependent
+ * Returns 0 on success, negative on failure */
 int
 hal_i2c_master_read(struct hal_i2c*, struct hal_i2c_master_data *pdata);
 
-/* issues a start condition and address on the SPI bus. Returns 0 
- * on success, negative on error.
+/* 
+ * Starts an I2C transaction with the driver. This API does not send
+ * anything over the bus itself
  */
 int 
-hal_i2c_master_start(struct hal_i2c*);
+hal_i2c_master_begin(struct hal_i2c*);
 
-/* issues a stop condition on the bus.  You must issue a stop condition for
- * every successful start condition on the bus */
+/* issues a stop condition on the bus and ends the I2C transaction.
+ * You must call i2c_master_end for every hal_i2c_master_begin
+ * API call that succeeds  */
 int 
-hal_i2c_master_stop(struct hal_i2c*);
-
+hal_i2c_master_end(struct hal_i2c*);
 
 /* Probes the i2c bus for a device with this address.  THIS API 
- * issues a start condition, probes the address and issues a stop
- * condition.  
+ * issues a start condition, probes the address using a read 
+ * command and issues a stop condition.   There is no need to call
+ * hal_i2c_master_begin/end with this method
  */
 int 
 hal_i2c_master_probe(struct hal_i2c*, uint8_t address);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0892fd98/hw/hal/src/hal_i2c.c
----------------------------------------------------------------------
diff --git a/hw/hal/src/hal_i2c.c b/hw/hal/src/hal_i2c.c
index bd20620..c383fe5 100644
--- a/hw/hal/src/hal_i2c.c
+++ b/hw/hal/src/hal_i2c.c
@@ -57,7 +57,7 @@ hal_i2c_master_probe(struct hal_i2c *pi2c, uint8_t address)
 }
 
 int
-hal_i2c_master_start(struct hal_i2c *pi2c)
+hal_i2c_master_begin(struct hal_i2c *pi2c)
 {
     if (pi2c && pi2c->driver_api && pi2c->driver_api->hi2cm_start )
     {
@@ -66,9 +66,8 @@ hal_i2c_master_start(struct hal_i2c *pi2c)
     return -1;
 }
 
-
 int
-hal_i2c_master_stop(struct hal_i2c *pi2c)
+hal_i2c_master_end(struct hal_i2c *pi2c)
 {
     if (pi2c && pi2c->driver_api && pi2c->driver_api->hi2cm_stop )
     {


[43/50] [abbrv] incubator-mynewt-core git commit: Fix bug in data length extension procedure

Posted by ma...@apache.org.
Fix bug in data length extension procedure

Changes were made to make sure that the hosts suggested data
sizes were never greater than the supported controller size.
That check was wrong (should have been less than or equal to) so
the controller would not perform the data length extension
procedure in some cases (when the maximum supported size was
requested).


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

Branch: refs/heads/master
Commit: 4ad86e91ab5be6693aa13668e7f9f6ef50d72f4c
Parents: 4f9a1f8
Author: William San Filippo <wi...@runtime.io>
Authored: Mon Apr 25 19:24:52 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Mon Apr 25 20:11:39 2016 -0700

----------------------------------------------------------------------
 net/nimble/controller/src/ble_ll_hci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4ad86e91/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 8149bf4..1d3b22e 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -311,8 +311,8 @@ ble_ll_hci_le_wr_sugg_data_len(uint8_t *cmdbuf)
         g_ble_ll_conn_params.sugg_tx_octets = (uint8_t)tx_oct;
         g_ble_ll_conn_params.sugg_tx_time = tx_time;
 
-        if ((tx_time < g_ble_ll_conn_params.supp_max_tx_time) &&
-            (tx_oct < g_ble_ll_conn_params.supp_max_tx_octets)) {
+        if ((tx_time <= g_ble_ll_conn_params.supp_max_tx_time) &&
+            (tx_oct <= g_ble_ll_conn_params.supp_max_tx_octets)) {
             g_ble_ll_conn_params.conn_init_max_tx_octets = tx_oct;
             g_ble_ll_conn_params.conn_init_max_tx_time = tx_time;
         }


[48/50] [abbrv] incubator-mynewt-core git commit: LICENSE; list new linker files added for nrf52 based boards.

Posted by ma...@apache.org.
LICENSE; list new linker files added for nrf52 based boards.


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

Branch: refs/heads/master
Commit: f04731b0626c4e78404b18ff80b94eab110f5c9a
Parents: 0970df8
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Wed Apr 27 11:26:13 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Wed Apr 27 11:28:35 2016 -0700

----------------------------------------------------------------------
 .rat-excludes | 8 ++++++++
 LICENSE       | 8 ++++++++
 2 files changed, 16 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f04731b0/.rat-excludes
----------------------------------------------------------------------
diff --git a/.rat-excludes b/.rat-excludes
index 03513c9..96e6239 100644
--- a/.rat-excludes
+++ b/.rat-excludes
@@ -32,6 +32,14 @@ system_nrf51.h
 
 # Nordic nRF52 SDK - BSD License.
 nrf52pdk.ld
+boot-nrf52pdk.ld
+nrf52pdk_no_boot.ld
+nrf52dk.ld
+boot-nrf52dk.ld
+nrf52dk_no_boot.ld
+bmd300eval.ld
+boot-bmd300eval.ld
+bmd300eval_no_boot.ld
 system_nrf52.c
 gcc_startup_nrf52.s
 nrf51_to_nrf52.h

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f04731b0/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 3d2ce33..cb4462f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -237,7 +237,15 @@ which are available under a BSD style license.  Relevant files are:
 
 This product bundles and partly derives from parts of the Nordic nRF52 SDK,
 which are available under a BSD style license.  Relevant files are:
+    * hw/bsp/bmd300eval/bmd300eval.ld
+    * hw/bsp/bmd300eval/bmd300eval_no_boot.ld
+    * hw/bsp/bmd300eval/boot-bmd300eval.ld
+    * hw/bsp/nrf52dk/boot-nrf52dk.ld
+    * hw/bsp/nrf52dk/nrf52dk.ld
+    * hw/bsp/nrf52dk/nrf52dk_no_boot.ld
+    * hw/bsp/nrf52dk/boot-nrf52dk.ld
     * hw/bsp/nrf52pdk/nrf52pdk.ld
+    * hw/bsp/nrf52pdk/nrf52pdk_no_boot.ld
 
 This product bundles Gary S. Brown's CRC32 implementation, which is available under the following license:
     COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or


[16/50] [abbrv] incubator-mynewt-core git commit: Merge branch 'develop' of https://github.com/neelnatu/incubator-mynewt-larva into develop

Posted by ma...@apache.org.
Merge branch 'develop' of https://github.com/neelnatu/incubator-mynewt-larva into develop


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

Branch: refs/heads/master
Commit: 3eb0cfbacdea19e7e3dd8ef11b13405bdaf46e12
Parents: dd96f36 f6bc99f
Author: Neel Natu <ne...@nahannisys.com>
Authored: Tue Apr 19 18:27:36 2016 -0700
Committer: Neel Natu <ne...@nahannisys.com>
Committed: Tue Apr 19 18:27:36 2016 -0700

----------------------------------------------------------------------
 fs/nffs/src/nffs_cache.c              |  85 ++++++++++++++---
 fs/nffs/src/nffs_gc.c                 |  34 +++++++
 fs/nffs/src/nffs_priv.h               |   6 +-
 fs/nffs/src/nffs_restore.c            | 141 +++++++++++++++++------------
 fs/nffs/src/nffs_write.c              |  32 ++++++-
 fs/nffs/src/test/arch/sim/nffs_test.c |   1 -
 libs/os/src/arch/sim/os_arch_sim.c    |  45 +++++----
 7 files changed, 242 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3eb0cfba/libs/os/src/arch/sim/os_arch_sim.c
----------------------------------------------------------------------
diff --cc libs/os/src/arch/sim/os_arch_sim.c
index 7bcca4d,1d43ab2..50b6663
--- a/libs/os/src/arch/sim/os_arch_sim.c
+++ b/libs/os/src/arch/sim/os_arch_sim.c
@@@ -325,20 -297,8 +325,20 @@@ timer_handler(int sig
      int ticks;
  
      static struct timeval time_last;
-     static int time_inited; 
+     static int time_inited;
  
 +    OS_ASSERT_CRITICAL();
 +
 +    /*
 +     * Just record that this handler was called when the process was blocked.
 +     * The handler will be called after sigsuspend() returns in the proper
 +     * order.
 +     */
 +    if (suspended) {
 +        sigaddset(&suspsigs, sig);
 +        return;
 +    }
 +
      if (!time_inited) {
          gettimeofday(&time_last, NULL);
          time_inited = 1;
@@@ -357,15 -323,9 +363,8 @@@
          time_diff.tv_sec = 0;
          time_diff.tv_usec %= OS_USEC_PER_TICK;
          timersub(&time_now, &time_diff, &time_last);
-     } else {
-         /*
-          * XXX time went backwards so just start afresh.
-          */
-         time_last = time_now;
-         ticks = 0;
 -
+         os_time_advance(ticks);
      }
- 
-     os_time_advance(ticks);
  }
  
  static void


[02/50] [abbrv] incubator-mynewt-core git commit: Modify write suggested default data length command in controller

Posted by ma...@apache.org.
Modify write suggested default data length command in controller

The prior implementation of this command allowed the host to set
the initial max tx octets/time for a device to a value that it
did not support. The controller will now ignore the host request
if it is not in the supported range.


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

Branch: refs/heads/master
Commit: 73ee5e8b0b0913280637af866d41c54a633aef25
Parents: b0a8c8e
Author: William San Filippo <wi...@runtime.io>
Authored: Mon Apr 18 23:12:10 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Mon Apr 18 23:30:06 2016 -0700

----------------------------------------------------------------------
 net/nimble/controller/src/ble_ll_hci.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/73ee5e8b/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 14a6b52..8149bf4 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -281,8 +281,14 @@ ble_ll_hci_le_read_bufsize(uint8_t *rspbuf, uint8_t *rsplen)
 
 #ifdef BLE_LL_CFG_FEAT_DATA_LEN_EXT
 /**
- * HCI write suggested default data length command. Returns the controllers
- * initial max tx octet/time.
+ * HCI write suggested default data length command.
+ *
+ * This command is used by the host to change the initial max tx octets/time
+ * for all connections. Note that if the controller does not support the
+ * requested times no error is returned; the controller simply ignores the
+ * request (but remembers what the host requested for the read suggested
+ * default data length command). The spec allows for the controller to
+ * disregard the host.
  *
  * @param rspbuf Pointer to response buffer
  * @param rsplen Length of response buffer
@@ -304,8 +310,12 @@ ble_ll_hci_le_wr_sugg_data_len(uint8_t *cmdbuf)
     if (ble_ll_chk_txrx_octets(tx_oct) && ble_ll_chk_txrx_time(tx_time)) {
         g_ble_ll_conn_params.sugg_tx_octets = (uint8_t)tx_oct;
         g_ble_ll_conn_params.sugg_tx_time = tx_time;
-        g_ble_ll_conn_params.conn_init_max_tx_octets = tx_oct;
-        g_ble_ll_conn_params.conn_init_max_tx_time = tx_time;
+
+        if ((tx_time < g_ble_ll_conn_params.supp_max_tx_time) &&
+            (tx_oct < g_ble_ll_conn_params.supp_max_tx_octets)) {
+            g_ble_ll_conn_params.conn_init_max_tx_octets = tx_oct;
+            g_ble_ll_conn_params.conn_init_max_tx_time = tx_time;
+        }
         rc = BLE_ERR_SUCCESS;
     } else {
         rc = BLE_ERR_INV_HCI_CMD_PARMS;


[26/50] [abbrv] incubator-mynewt-core git commit: ble host - rename "app task" to "parent task"

Posted by ma...@apache.org.
ble host - rename "app task" to "parent task"


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

Branch: refs/heads/master
Commit: 99dc724ab938b69fa7ac18a2725398164621fb0c
Parents: e4669ed
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 20 15:30:23 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 20 16:11:48 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_att.c     |  2 +-
 net/nimble/host/src/ble_hs.c      | 27 ++++++++++++++++-----------
 net/nimble/host/src/ble_hs_priv.h |  2 +-
 3 files changed, 18 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/99dc724a/net/nimble/host/src/ble_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att.c b/net/nimble/host/src/ble_att.c
index 379ed48..b06a83f 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -397,7 +397,7 @@ ble_att_inc_rx_stat(uint8_t att_op)
 uint8_t *
 ble_att_get_flat_buf(void)
 {
-    BLE_HS_DBG_ASSERT(ble_hs_is_app_task());
+    BLE_HS_DBG_ASSERT(ble_hs_is_parent_task());
     return ble_att_flat_buf;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/99dc724a/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 4d62a94..c3f1f65 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -64,10 +64,12 @@ static void *ble_hs_hci_os_event_buf;
 static struct os_callout_func ble_hs_heartbeat_timer;
 static struct os_callout_func ble_hs_event_co;
 
-/* Host HCI Task Events */
+/* Queue for host-specific OS events. */
 static struct os_eventq ble_hs_evq;
-static struct os_eventq *ble_hs_app_evq;
-static struct os_task *ble_hs_app_task;
+
+/* Task structures for the host's parent task. */
+static struct os_eventq *ble_hs_parent_evq;
+static struct os_task *ble_hs_parent_task;
 
 static struct os_mqueue ble_hs_rx_q;
 static struct os_mqueue ble_hs_tx_q;
@@ -105,10 +107,13 @@ ble_hs_thread_safe(void)
     return !os_started() || ble_hs_locked_by_cur_task();
 }
 
+/**
+ * Indicates whether the host's parent task is currently running.
+ */
 int
-ble_hs_is_app_task(void)
+ble_hs_is_parent_task(void)
 {
-    return os_sched_get_current_task() == ble_hs_app_task;
+    return os_sched_get_current_task() == ble_hs_parent_task;
 }
 
 void
@@ -225,7 +230,7 @@ void
 ble_hs_event_enqueue(struct os_event *ev)
 {
     os_eventq_put(&ble_hs_evq, ev);
-    os_eventq_put(ble_hs_app_evq, &ble_hs_event_co.cf_c.c_ev);
+    os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev);
 }
 
 int
@@ -233,7 +238,7 @@ ble_hs_start(void)
 {
     int rc;
 
-    ble_hs_app_task = os_sched_get_current_task();
+    ble_hs_parent_task = os_sched_get_current_task();
 
     ble_hs_heartbeat_timer_reset();
 
@@ -259,7 +264,7 @@ ble_hs_rx_data(struct os_mbuf *om)
     if (rc != 0) {
         return BLE_HS_EOS;
     }
-    os_eventq_put(ble_hs_app_evq, &ble_hs_event_co.cf_c.c_ev);
+    os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev);
 
     return 0;
 }
@@ -273,7 +278,7 @@ ble_hs_tx_data(struct os_mbuf *om)
     if (rc != 0) {
         return BLE_HS_EOS;
     }
-    os_eventq_put(ble_hs_app_evq, &ble_hs_event_co.cf_c.c_ev);
+    os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev);
 
     return 0;
 }
@@ -302,7 +307,7 @@ ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg)
         rc = BLE_HS_EINVAL;
         goto err;
     }
-    ble_hs_app_evq = app_evq;
+    ble_hs_parent_evq = app_evq;
 
     ble_hs_cfg_init(cfg);
 
@@ -394,7 +399,7 @@ ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg)
         goto err;
     }
 
-    os_callout_func_init(&ble_hs_heartbeat_timer, ble_hs_app_evq,
+    os_callout_func_init(&ble_hs_heartbeat_timer, ble_hs_parent_evq,
                          ble_hs_heartbeat, NULL);
     os_callout_func_init(&ble_hs_event_co, &ble_hs_evq,
                          ble_hs_event_handle, NULL);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/99dc724a/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 23df932..cf77b9e 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -98,7 +98,7 @@ void ble_hs_cfg_init(struct ble_hs_cfg *cfg);
 int ble_hs_locked(void);
 int ble_hs_locked_by_cur_task(void);
 int ble_hs_thread_safe(void);
-int ble_hs_is_app_task(void);
+int ble_hs_is_parent_task(void);
 void ble_hs_lock(void);
 void ble_hs_unlock(void);
 


[38/50] [abbrv] incubator-mynewt-core git commit: Modify bletest for new host

Posted by ma...@apache.org.
Modify bletest for new host


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

Branch: refs/heads/master
Commit: 6d8a3a76f173913e6ab5cd442d130abab644cea5
Parents: ddcd177
Author: William San Filippo <wi...@runtime.io>
Authored: Fri Apr 22 13:56:59 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Fri Apr 22 13:57:08 2016 -0700

----------------------------------------------------------------------
 apps/bletest/src/bletest_hci.c          | 543 ++++++++++++++++++++++++++
 apps/bletest/src/bletest_priv.h         |  62 +++
 apps/bletest/src/main.c                 | 151 +++-----
 net/nimble/host/include/host/host_hci.h |  32 --
 net/nimble/host/src/host_hci_cmd.c      | 559 +--------------------------
 net/nimble/include/nimble/hci_common.h  |   1 +
 6 files changed, 667 insertions(+), 681 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d8a3a76/apps/bletest/src/bletest_hci.c
----------------------------------------------------------------------
diff --git a/apps/bletest/src/bletest_hci.c b/apps/bletest/src/bletest_hci.c
new file mode 100755
index 0000000..785edd9
--- /dev/null
+++ b/apps/bletest/src/bletest_hci.c
@@ -0,0 +1,543 @@
+/**
+ * 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.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "os/os.h"
+#include "bsp/bsp.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "nimble/hci_transport.h"
+#include "nimble/hci_common.h"
+#include "host/host_hci.h"
+#include "host/ble_hs.h"
+#include "controller/ble_ll.h"
+#include "controller/ble_ll_hci.h"
+#include "controller/ble_ll_conn.h"
+#include "controller/ble_ll_scan.h"
+#include "controller/ble_ll_adv.h"
+
+/* XXX: An app should not include private headers from a library.  The bletest
+ * app uses some of nimble's internal details for logging.
+ */
+#include "../src/ble_hci_util_priv.h"
+#include "../src/ble_hs_priv.h"
+#include "bletest_priv.h"
+
+void
+bletest_send_conn_update(uint16_t handle)
+{
+    int rc;
+    struct hci_conn_update hcu;
+
+    hcu.conn_latency = 4;
+    hcu.supervision_timeout = 2000;
+    hcu.conn_itvl_min = 1000;
+    hcu.conn_itvl_max = 1000;
+    hcu.handle = handle;
+    hcu.min_ce_len = 4;
+    hcu.max_ce_len = 4;
+
+    rc = host_hci_cmd_le_conn_update(&hcu);
+    assert(rc == 0);
+}
+
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+void
+bletest_ltk_req_reply(uint16_t handle)
+{
+    g_bletest_ltk_reply_handle = handle;
+}
+
+void
+bletest_send_ltk_req_neg_reply(uint16_t handle)
+{
+    host_hci_cmd_le_lt_key_req_neg_reply(handle);
+}
+
+void
+bletest_send_ltk_req_reply(uint16_t handle)
+{
+    struct hci_lt_key_req_reply hkr;
+
+    hkr.conn_handle = handle;
+    swap_buf(hkr.long_term_key, (uint8_t *)g_bletest_LTK, 16);
+    host_hci_cmd_le_lt_key_req_reply(&hkr);
+}
+#endif
+
+int
+bletest_hci_reset_ctlr(void)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+
+    host_hci_write_hdr(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_RESET, 0, buf);
+    return ble_hci_cmd_tx(buf, NULL, 0, NULL);
+}
+
+int
+bletest_hci_rd_bd_addr(void)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t rspbuf[BLE_DEV_ADDR_LEN];
+    uint8_t rsplen;
+
+    host_hci_write_hdr(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BD_ADDR, 0,
+                       buf);
+    rc = ble_hci_cmd_tx(buf, rspbuf, BLE_DEV_ADDR_LEN, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != BLE_DEV_ADDR_LEN) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    return rc;
+}
+
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+int
+bletest_hci_le_encrypt(uint8_t *key, uint8_t *pt)
+{
+    int rc;
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_ENCRYPT_LEN];
+    uint8_t rspbuf[16];
+    uint8_t rsplen;
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_ENCRYPT,
+                       BLE_HCI_LE_ENCRYPT_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    swap_buf(dst, key, BLE_ENC_BLOCK_SIZE);
+    swap_buf(dst + BLE_ENC_BLOCK_SIZE, pt, BLE_ENC_BLOCK_SIZE);
+    rc = ble_hci_cmd_tx(buf, rspbuf, 16, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != 16) {
+        return BLE_HS_ECONTROLLER;
+    }
+    return rc;
+}
+#endif
+
+int
+bletest_hci_le_set_datalen(uint16_t handle, uint16_t txoctets, uint16_t txtime)
+{
+    int rc;
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_DATALEN_LEN];
+    uint8_t rspbuf[2];
+    uint8_t rsplen;
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DATA_LEN,
+                       BLE_HCI_SET_DATALEN_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    htole16(dst, handle);
+    htole16(dst + 2, txoctets);
+    htole16(dst + 4, txtime);
+    rc = ble_hci_cmd_tx(buf, rspbuf, 2, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != 2) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    return rc;
+}
+
+int
+bletest_hci_le_write_sugg_datalen(uint16_t txoctets, uint16_t txtime)
+{
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_WR_SUGG_DATALEN_LEN];
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_WR_SUGG_DEF_DATA_LEN,
+                       BLE_HCI_WR_SUGG_DATALEN_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    htole16(dst, txoctets);
+    htole16(dst + 2, txtime);
+    return ble_hci_cmd_tx(buf, NULL, 0, NULL);
+}
+
+int
+bletest_hci_le_rd_sugg_datalen(void)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t rspbuf[BLE_HCI_RD_SUGG_DATALEN_RSPLEN];
+    uint8_t rsplen;
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN, 0,
+                       buf);
+
+    rc = ble_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_SUGG_DATALEN_RSPLEN, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != BLE_HCI_RD_SUGG_DATALEN_RSPLEN) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    return 0;
+}
+
+int
+bletest_hci_rd_local_version(void)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t rspbuf[BLE_HCI_RD_LOC_VER_INFO_RSPLEN];
+    uint8_t rsplen;
+
+    host_hci_write_hdr(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOCAL_VER, 0,
+                       buf);
+    rc = ble_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_LOC_VER_INFO_RSPLEN, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != BLE_HCI_RD_LOC_VER_INFO_RSPLEN) {
+        return BLE_HS_ECONTROLLER;
+    }
+    return rc;
+}
+
+int
+bletest_hci_rd_local_feat(void)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t rspbuf[BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN];
+    uint8_t rsplen;
+
+    host_hci_write_hdr(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT,
+                       0, buf);
+    rc = ble_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) {
+        return BLE_HS_ECONTROLLER;
+    }
+    return rc;
+}
+
+int
+bletest_hci_rd_local_supp_cmd(void)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t rspbuf[BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN];
+    uint8_t rsplen;
+
+    host_hci_write_hdr(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD,
+                       0, buf);
+    rc = ble_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN) {
+        return BLE_HS_ECONTROLLER;
+    }
+    return rc;
+}
+
+/**
+ * Read supported states
+ *
+ * OGF = 0x08 (LE)
+ * OCF = 0x001C
+ *
+ * @return int
+ */
+int
+bletest_hci_le_read_supp_states(void)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t rspbuf[BLE_HCI_RD_SUPP_STATES_RSPLEN];
+    uint8_t rsplen;
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_SUPP_STATES, 0, buf);
+    rc = ble_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_SUPP_STATES_RSPLEN, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != BLE_HCI_RD_SUPP_STATES_RSPLEN) {
+        return BLE_HS_ECONTROLLER;
+    }
+    return rc;
+}
+
+int
+bletest_hci_le_rd_max_datalen(void)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t rspbuf[BLE_HCI_RD_MAX_DATALEN_RSPLEN];
+    uint8_t rsplen;
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_MAX_DATA_LEN, 0, buf);
+    rc = ble_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_MAX_DATALEN_RSPLEN, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != BLE_HCI_RD_MAX_DATALEN_RSPLEN) {
+        return BLE_HS_ECONTROLLER;
+    }
+    return rc;
+}
+
+int
+bletest_hci_le_set_adv_data(uint8_t *data, uint8_t len)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADV_DATA_LEN];
+
+    rc = host_hci_cmd_build_le_set_adv_data(data, len, buf, sizeof buf);
+    assert(rc == 0);
+    return ble_hci_cmd_tx_empty_ack(buf);
+}
+
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+int
+bletest_hci_le_start_encrypt(struct hci_start_encrypt *cmd)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_START_ENCRYPT_LEN];
+
+    host_hci_cmd_build_le_start_encrypt(cmd, buf, sizeof buf);
+    return ble_hci_cmd_tx_empty_ack(buf);
+}
+#endif
+
+int
+bletest_hci_le_read_rem_used_feat(uint16_t handle)
+{
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_CONN_RD_REM_FEAT_LEN];
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_REM_FEAT,
+                       BLE_HCI_CONN_RD_REM_FEAT_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    htole16(dst, handle);
+    return ble_hci_cmd_tx(buf, NULL, 0, NULL);
+}
+
+int
+bletest_hci_le_set_adv_params(struct hci_adv_params *adv)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADV_PARAM_LEN];
+
+    rc = host_hci_cmd_build_le_set_adv_params(adv, buf, sizeof buf);
+    if (!rc) {
+        rc = ble_hci_cmd_tx_empty_ack(buf);
+    }
+    return rc;
+}
+
+int
+bletest_hci_le_set_rand_addr(uint8_t *addr)
+{
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_DATALEN_LEN];
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_RAND_ADDR,
+                       BLE_DEV_ADDR_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    memcpy(dst, addr, BLE_DEV_ADDR_LEN);
+    return ble_hci_cmd_tx(buf, NULL, 0, NULL);
+}
+
+int
+bletest_hci_rd_rem_version(uint16_t handle)
+{
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + sizeof(uint16_t)];
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LINK_CTRL, BLE_HCI_OCF_RD_REM_VER_INFO,
+                       sizeof(uint16_t), dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    htole16(dst, handle);
+    return ble_hci_cmd_tx(buf, NULL, 0, NULL);
+}
+
+int
+bletest_hci_le_set_host_chan_class(uint8_t *chanmap)
+{
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_HOST_CHAN_CLASS_LEN];
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS,
+                       BLE_HCI_SET_HOST_CHAN_CLASS_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    memcpy(dst, chanmap, BLE_HCI_SET_HOST_CHAN_CLASS_LEN);
+    return ble_hci_cmd_tx(buf, NULL, 0, NULL);
+}
+
+int
+bletest_hci_le_rd_chanmap(uint16_t handle)
+{
+    int rc;
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_RD_CHANMAP_LEN];
+    uint8_t rspbuf[BLE_HCI_RD_CHANMAP_RSP_LEN];
+    uint8_t rsplen;
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_CHAN_MAP,
+                       BLE_HCI_RD_CHANMAP_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    htole16(dst, handle);
+    rc = ble_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_CHANMAP_RSP_LEN, &rsplen);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (rsplen != BLE_HCI_RD_CHANMAP_RSP_LEN) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    return rc;
+}
+
+int
+bletest_hci_le_set_adv_enable(uint8_t enable)
+{
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADV_ENABLE_LEN];
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_ENABLE,
+                       BLE_HCI_SET_ADV_ENABLE_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    dst[0] = enable;
+    return ble_hci_cmd_tx(buf, NULL, 0, NULL);
+}
+
+int
+bletest_hci_le_set_event_mask(uint64_t event_mask)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_LE_EVENT_MASK_LEN];
+
+    host_hci_cmd_build_le_set_event_mask(event_mask, buf, sizeof buf);
+    return ble_hci_cmd_tx_empty_ack(buf);
+}
+
+int
+bletest_hci_set_event_mask(uint64_t event_mask)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_EVENT_MASK_LEN];
+
+    host_hci_cmd_build_set_event_mask(event_mask, buf, sizeof buf);
+    return ble_hci_cmd_tx_empty_ack(buf);
+}
+
+int
+bletest_hci_le_set_scan_rsp_data(uint8_t *data, uint8_t len)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_RSP_DATA_LEN];
+
+    rc = host_hci_cmd_build_le_set_scan_rsp_data(data, len, buf, sizeof buf);
+    assert(rc == 0);
+    return ble_hci_cmd_tx_empty_ack(buf);
+}
+
+int
+bletest_hci_cmd_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl,
+                                   uint16_t scan_window, uint8_t own_addr_type,
+                                   uint8_t filter_policy) {
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_PARAM_LEN];
+
+    rc = host_hci_cmd_build_le_set_scan_params(scan_type, scan_itvl,
+                                               scan_window, own_addr_type,
+                                               filter_policy, buf, sizeof buf);
+    if (!rc) {
+        rc = ble_hci_cmd_tx_empty_ack(buf);
+    }
+    return rc;
+}
+
+int
+bletest_hci_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_PARAM_LEN];
+
+    rc = host_hci_cmd_build_le_add_to_whitelist(addr, addr_type, buf,
+                                                sizeof buf);
+    if (!rc) {
+        rc = ble_hci_cmd_tx_empty_ack(buf);
+    }
+    return rc;
+}
+
+int
+bletest_hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dups)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_ENABLE_LEN];
+
+    host_hci_cmd_build_le_set_scan_enable(enable, filter_dups, buf, sizeof buf);
+    return ble_hci_cmd_tx_empty_ack(buf);
+}
+
+int
+bletest_hci_le_create_connection(struct hci_create_conn *hcc)
+{
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_CREATE_CONN_LEN];
+
+    rc = host_hci_cmd_build_le_create_connection(hcc, buf, sizeof buf);
+    if (!rc) {
+        rc = ble_hci_cmd_tx_empty_ack(buf);
+    }
+    return rc;
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d8a3a76/apps/bletest/src/bletest_priv.h
----------------------------------------------------------------------
diff --git a/apps/bletest/src/bletest_priv.h b/apps/bletest/src/bletest_priv.h
new file mode 100644
index 0000000..d44dcfe
--- /dev/null
+++ b/apps/bletest/src/bletest_priv.h
@@ -0,0 +1,62 @@
+/**
+ * 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_BLETEST_PRIV_
+#define H_BLETEST_PRIV_
+
+void bletest_send_conn_update(uint16_t handle);
+
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+void bletest_ltk_req_reply(uint16_t handle);
+void bletest_send_ltk_req_neg_reply(uint16_t handle);
+void bletest_send_ltk_req_reply(uint16_t handle);
+int bletest_hci_le_start_encrypt(struct hci_start_encrypt *cmd);
+int bletest_hci_le_encrypt(uint8_t *key, uint8_t *pt);
+#endif
+
+int bletest_hci_reset_ctlr(void);
+int bletest_hci_rd_bd_addr(void);
+int bletest_hci_le_set_datalen(uint16_t handle, uint16_t txoctets,
+                               uint16_t txtime);
+int bletest_hci_le_write_sugg_datalen(uint16_t txoctets, uint16_t txtime);
+int bletest_hci_le_rd_sugg_datalen(void);
+int bletest_hci_rd_local_version(void);
+int bletest_hci_rd_local_feat(void);
+int bletest_hci_rd_local_supp_cmd(void);
+int bletest_hci_le_read_supp_states(void);
+int bletest_hci_le_rd_max_datalen(void);
+int bletest_hci_le_set_adv_data(uint8_t *data, uint8_t len);
+int bletest_hci_le_set_adv_params(struct hci_adv_params *adv);
+int bletest_hci_le_read_rem_used_feat(uint16_t handle);
+int bletest_hci_le_set_rand_addr(uint8_t *addr);
+int bletest_hci_rd_rem_version(uint16_t handle);
+int bletest_hci_le_set_host_chan_class(uint8_t *chanmap);
+int bletest_hci_le_rd_chanmap(uint16_t handle);
+int bletest_hci_le_set_adv_enable(uint8_t enable);
+int bletest_hci_le_set_event_mask(uint64_t event_mask);
+int bletest_hci_set_event_mask(uint64_t event_mask);
+int bletest_hci_le_set_scan_rsp_data(uint8_t *data, uint8_t len);
+int bletest_hci_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type);
+int bletest_hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dups);
+int bletest_hci_le_create_connection(struct hci_create_conn *hcc);
+int bletest_hci_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl,
+                                   uint16_t scan_window, uint8_t own_addr_type,
+                                   uint8_t filter_policy);
+
+#endif  /* H_BLETEST_PRIV_*/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d8a3a76/apps/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c
index d66a91a..aa713ac 100755
--- a/apps/bletest/src/main.c
+++ b/apps/bletest/src/main.c
@@ -45,6 +45,13 @@
 #include "controller/ble_ll_scan.h"
 #include "controller/ble_ll_adv.h"
 
+/* XXX: An app should not include private headers from a library.  The bletest
+ * app uses some of nimble's internal details for logging.
+ */
+#include "../src/ble_hci_util_priv.h"
+#include "../src/ble_hs_priv.h"
+#include "bletest_priv.h"
+
 /* Task priorities */
 #define BLE_LL_TASK_PRI     (OS_TASK_PRI_HIGHEST)
 #define HOST_TASK_PRIO      (OS_TASK_PRI_HIGHEST + 1)
@@ -221,54 +228,12 @@ bletest_inc_adv_pkt_num(void)
             }
         }
 
-        rc = host_hci_cmd_le_set_adv_data(g_host_adv_data, g_host_adv_len);
+        rc = bletest_hci_le_set_adv_data(g_host_adv_data, g_host_adv_len);
         assert(rc == 0);
     }
 }
 #endif
 
-void
-bletest_send_conn_update(uint16_t handle)
-{
-    int rc;
-    struct hci_conn_update hcu;
-
-    hcu.conn_latency = 4;
-    hcu.supervision_timeout = 2000;
-    hcu.conn_itvl_min = 1000;
-    hcu.conn_itvl_max = 1000;
-    hcu.handle = handle;
-    hcu.min_ce_len = 4;
-    hcu.max_ce_len = 4;
-
-    rc = host_hci_cmd_le_conn_update(&hcu);
-    assert(rc == 0);
-}
-
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-void
-bletest_ltk_req_reply(uint16_t handle)
-{
-    g_bletest_ltk_reply_handle = handle;
-}
-
-void
-bletest_send_ltk_req_neg_reply(uint16_t handle)
-{
-    host_hci_cmd_le_lt_key_req_neg_reply(handle);
-}
-
-void
-bletest_send_ltk_req_reply(uint16_t handle)
-{
-    struct hci_lt_key_req_reply hkr;
-
-    hkr.conn_handle = handle;
-    swap_buf(hkr.long_term_key, (uint8_t *)g_bletest_LTK, 16);
-    host_hci_cmd_le_lt_key_req_reply(&hkr);
-}
-#endif
-
 /**
  * Sets the advertising data to be sent in advertising pdu's which contain
  * advertising data.
@@ -362,24 +327,24 @@ bletest_init_advertising(void)
     }
 
     /* Set the advertising parameters */
-    rc = host_hci_cmd_le_set_adv_params(&adv);
+    rc = bletest_hci_le_set_adv_params(&adv);
     assert(rc == 0);
 
     /* If we are using a random address, we need to set it */
     if (adv.own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
         memcpy(rand_addr, g_dev_addr, BLE_DEV_ADDR_LEN);
         rand_addr[5] |= 0xc0;
-        rc = host_hci_cmd_le_set_rand_addr(rand_addr);
+        rc = bletest_hci_le_set_rand_addr(rand_addr);
         assert(rc == 0);
     }
 
     /* Set advertising data */
     if (adv_len != 0) {
-        rc = host_hci_cmd_le_set_adv_data(&g_host_adv_data[0], adv_len);
+        rc = bletest_hci_le_set_adv_data(&g_host_adv_data[0], adv_len);
         assert(rc == 0);
 
         /* Set scan response data */
-        rc = host_hci_cmd_le_set_scan_rsp_data(&g_host_adv_data[0], adv_len);
+        rc = bletest_hci_le_set_scan_rsp_data(&g_host_adv_data[0], adv_len);
         assert(rc == 0);
     }
 }
@@ -394,11 +359,11 @@ bletest_init_scanner(void)
     uint8_t filter_policy;
 
     /* Set scanning parameters */
-    rc = host_hci_cmd_le_set_scan_params(BLETEST_CFG_SCAN_TYPE,
-                                         BLETEST_CFG_SCAN_ITVL,
-                                         BLETEST_CFG_SCAN_WINDOW,
-                                         BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-                                         BLETEST_CFG_SCAN_FILT_POLICY);
+    rc = bletest_hci_le_set_scan_params(BLETEST_CFG_SCAN_TYPE,
+                                        BLETEST_CFG_SCAN_ITVL,
+                                        BLETEST_CFG_SCAN_WINDOW,
+                                        BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+                                        BLETEST_CFG_SCAN_FILT_POLICY);
     assert(rc == 0);
 
     filter_policy = BLETEST_CFG_SCAN_FILT_POLICY;
@@ -410,7 +375,7 @@ bletest_init_scanner(void)
         dev_addr[3] = 0x88;
         dev_addr[4] = 0x88;
         dev_addr[5] = 0x08;
-        rc = host_hci_cmd_le_add_to_whitelist(dev_addr, BLE_ADDR_TYPE_PUBLIC);
+        rc = bletest_hci_le_add_to_whitelist(dev_addr, BLE_ADDR_TYPE_PUBLIC);
         assert(rc == 0);
     }
 }
@@ -423,11 +388,11 @@ bletest_execute_scanner(void)
     /* Enable scanning */
     if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
         if (g_bletest_state) {
-            rc = host_hci_cmd_le_set_scan_enable(0, BLETEST_CFG_FILT_DUP_ADV);
+            rc = bletest_hci_le_set_scan_enable(0, BLETEST_CFG_FILT_DUP_ADV);
             assert(rc == 0);
             g_bletest_state = 0;
         } else {
-            rc = host_hci_cmd_le_set_scan_enable(1, BLETEST_CFG_FILT_DUP_ADV);
+            rc = bletest_hci_le_set_scan_enable(1, BLETEST_CFG_FILT_DUP_ADV);
             assert(rc == 0);
             g_bletest_state = 1;
         }
@@ -471,11 +436,11 @@ bletest_init_initiator(void)
     if (hcc->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
         memcpy(rand_addr, g_dev_addr, BLE_DEV_ADDR_LEN);
         rand_addr[5] |= 0xc0;
-        rc = host_hci_cmd_le_set_rand_addr(rand_addr);
+        rc = bletest_hci_le_set_rand_addr(rand_addr);
         assert(rc == 0);
     }
 
-    rc = host_hci_cmd_le_create_connection(hcc);
+    rc = bletest_hci_le_create_connection(hcc);
     assert(rc == 0);
 }
 
@@ -484,6 +449,7 @@ bletest_execute_initiator(void)
 {
     int i;
     int rc;
+    int8_t rssi;
     uint16_t handle;
     uint8_t new_chan_map[5];
 
@@ -498,10 +464,10 @@ bletest_execute_initiator(void)
             g_bletest_led_rate = OS_TICKS_PER_SEC;
 
             /* Ask for version information */
-            rc = host_hci_cmd_rd_rem_version(handle);
+            rc = bletest_hci_rd_rem_version(handle);
 
             /* Ask for remote used features */
-            rc = host_hci_cmd_le_read_rem_used_feat(handle);
+            rc = bletest_hci_le_read_rem_used_feat(handle);
 
             /* Scanning better be stopped! */
             assert(ble_ll_scan_enabled() == 0);
@@ -524,7 +490,7 @@ bletest_execute_initiator(void)
             if ((g_bletest_state == 1) || (g_bletest_state == 3)) {
                 for (i = 0; i < g_bletest_current_conns; ++i) {
                     if (ble_ll_conn_find_active_conn(i + 1)) {
-                        host_hci_cmd_le_rd_chanmap(i+1);
+                        bletest_hci_le_rd_chanmap(i+1);
                     }
                 }
             } else if (g_bletest_state == 2) {
@@ -533,7 +499,7 @@ bletest_execute_initiator(void)
                 new_chan_map[2] = 0;
                 new_chan_map[3] = 0x1F;
                 new_chan_map[4] = 0;
-                host_hci_cmd_le_set_host_chan_class(new_chan_map);
+                bletest_hci_le_set_host_chan_class(new_chan_map);
             } else if (g_bletest_state == 4) {
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
                 struct hci_start_encrypt hsle;
@@ -544,20 +510,19 @@ bletest_execute_initiator(void)
                         hsle.random_number = g_bletest_RAND;
                         swap_buf(hsle.long_term_key, (uint8_t *)g_bletest_LTK,
                                  16);
-                        host_hci_cmd_le_start_encrypt(&hsle);
+                        bletest_hci_le_start_encrypt(&hsle);
                     }
                 }
 #endif
             } else {
                 for (i = 0; i < g_bletest_current_conns; ++i) {
                     if (ble_ll_conn_find_active_conn(i + 1)) {
-                        host_hci_cmd_read_rssi(i+1);
+                        ble_hci_util_read_rssi(i+1, &rssi);
                     }
                 }
             }
             if (g_bletest_state < 5) {
                 ++g_bletest_state;
-            } else {
             }
             g_next_os_time = os_time_get() + OS_TICKS_PER_SEC * 3;
         }
@@ -618,13 +583,13 @@ bletest_execute_advertiser(void)
             assert(ble_ll_adv_enabled() == 0);
 
             /* Send the remote used features command */
-            rc = host_hci_cmd_le_read_rem_used_feat(handle);
+            rc = bletest_hci_le_read_rem_used_feat(handle);
             if (rc) {
                 return;
             }
 
             /* Send the remote read version command */
-            rc = host_hci_cmd_rd_rem_version(handle);
+            rc = bletest_hci_rd_rem_version(handle);
             if (rc) {
                 return;
             }
@@ -642,7 +607,7 @@ bletest_execute_advertiser(void)
                 g_bletest_cur_peer_addr[5] += 1;
                 g_dev_addr[5] += 1;
                 bletest_init_advertising();
-                rc = host_hci_cmd_le_set_adv_enable(1);
+                rc = bletest_hci_le_set_adv_enable(1);
             }
         }
     }
@@ -816,6 +781,7 @@ void
 bletest_task_handler(void *arg)
 {
     int rc;
+    uint64_t rand64;
     uint64_t event_mask;
     struct os_event *ev;
     struct os_callout_func *cf;
@@ -826,16 +792,12 @@ bletest_task_handler(void *arg)
     /* Wait one second before starting test task */
     os_time_delay(OS_TICKS_PER_SEC);
 
-    /* Initialize eventq */
-    os_eventq_init(&g_bletest_evq);
-
     /* Initialize the host timer */
     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);
+    rc = bletest_hci_reset_ctlr();
     assert(rc == 0);
 
 #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
@@ -858,65 +820,65 @@ bletest_task_handler(void *arg)
 
     /* Set the event mask we want to display */
     event_mask = 0x7FF;
-    rc = host_hci_cmd_le_set_event_mask(event_mask);
+    rc = bletest_hci_le_set_event_mask(event_mask);
     assert(rc == 0);
 
     /* Turn on all events */
     event_mask = 0xffffffffffffffff;
-    rc = host_hci_cmd_set_event_mask(event_mask);
+    rc = bletest_hci_set_event_mask(event_mask);
     assert(rc == 0);
 
     /* Read device address */
-    rc = host_hci_cmd_rd_bd_addr();
+    rc = bletest_hci_rd_bd_addr();
     assert(rc == 0);
 
     /* Read local features */
-    rc = host_hci_cmd_rd_local_feat();
+    rc = bletest_hci_rd_local_feat();
     assert(rc == 0);
 
     /* Read local commands */
-    rc = host_hci_cmd_rd_local_cmd();
+    rc = bletest_hci_rd_local_supp_cmd();
     assert(rc == 0);
 
     /* Read version */
-    rc = host_hci_cmd_rd_local_version();
+    rc = bletest_hci_rd_local_version();
     assert(rc == 0);
 
     /* Read supported states */
-    rc = host_hci_cmd_le_read_supp_states();
+    rc = bletest_hci_le_read_supp_states();
     assert(rc == 0);
 
     /* Read maximum data length */
-    rc = host_hci_cmd_le_read_max_datalen();
+    rc = bletest_hci_le_rd_max_datalen();
     assert(rc == 0);
 
     /* Read suggested data length */
-    rc = host_hci_cmd_le_read_sugg_datalen();
+    rc = bletest_hci_le_rd_sugg_datalen();
     assert(rc == 0);
 
     /* write suggested default data length */
-    rc = host_hci_cmd_le_write_sugg_datalen(BLETEST_CFG_SUGG_DEF_TXOCTETS,
-                                            BLETEST_CFG_SUGG_DEF_TXTIME);
+    rc = bletest_hci_le_write_sugg_datalen(BLETEST_CFG_SUGG_DEF_TXOCTETS,
+                                           BLETEST_CFG_SUGG_DEF_TXTIME);
     assert(rc == 0);
 
     /* Read suggested data length */
-    rc = host_hci_cmd_le_read_sugg_datalen();
+    rc = bletest_hci_le_rd_sugg_datalen();
     assert(rc == 0);
 
     /* Set data length (note: we know there is no connection; just a test) */
-    rc = host_hci_cmd_le_set_datalen(0x1234,
-                                     BLETEST_CFG_SUGG_DEF_TXOCTETS,
-                                     BLETEST_CFG_SUGG_DEF_TXTIME);
-    assert(rc == 0);
-
+    rc = bletest_hci_le_set_datalen(0x1234, BLETEST_CFG_SUGG_DEF_TXOCTETS,
+                                    BLETEST_CFG_SUGG_DEF_TXTIME);
+    assert(rc != 0);
 
     /* Encrypt a block */
-    rc = host_hci_cmd_le_encrypt((uint8_t *)g_ble_ll_encrypt_test_key,
-                                 (uint8_t *)g_ble_ll_encrypt_test_plain_text);
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    rc = bletest_hci_le_encrypt((uint8_t *)g_ble_ll_encrypt_test_key,
+                                (uint8_t *)g_ble_ll_encrypt_test_plain_text);
     assert(rc == 0);
+#endif
 
     /* Get a random number */
-    rc = host_hci_cmd_le_rand();
+    rc = ble_hci_util_rand(&rand64, 8);
     assert(rc == 0);
 
     /* Wait some time before starting */
@@ -927,7 +889,7 @@ bletest_task_handler(void *arg)
 
     /* Begin advertising if we are an advertiser */
 #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
-    rc = host_hci_cmd_le_set_adv_enable(1);
+    rc = bletest_hci_le_set_adv_enable(1);
     assert(rc == 0);
 #endif
 
@@ -1072,6 +1034,9 @@ main(void)
     rc = stats_module_init();
     assert(rc == 0);
 
+    /* Initialize eventq for bletest task */
+    os_eventq_init(&g_bletest_evq);
+
     /* Initialize the BLE LL */
     rc = ble_ll_init(BLE_LL_TASK_PRI, MBUF_NUM_MBUFS, BLE_MBUF_PAYLOAD_SIZE);
     assert(rc == 0);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d8a3a76/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 8011f79..e8fab80 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -32,37 +32,22 @@ int host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, void *cmddata);
 int host_hci_cmd_send_buf(void *cmddata);
 void host_hci_cmd_build_set_event_mask(uint64_t event_mask,
                                        uint8_t *dst, int dst_len);
-int host_hci_cmd_set_event_mask(uint64_t event_mask);
 void host_hci_cmd_build_disconnect(uint16_t handle, uint8_t reason,
                                    uint8_t *dst, int dst_len);
 int host_hci_cmd_disconnect(uint16_t handle, uint8_t reason);
-int host_hci_cmd_rd_rem_version(uint16_t handle);
-int host_hci_cmd_rd_local_version(void);
-int host_hci_cmd_rd_local_feat(void);
-int host_hci_cmd_rd_local_cmd(void);
-int host_hci_cmd_rd_bd_addr(void);
 void host_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, int dst_len);
 int host_hci_cmd_read_rssi(uint16_t handle);
-int host_hci_cmd_le_set_host_chan_class(uint8_t *new_chan_map);
-int host_hci_cmd_le_rd_chanmap(uint16_t handle);
 int host_hci_cmd_build_le_set_scan_rsp_data(uint8_t *data, uint8_t len,
                                             uint8_t *dst, int dst_len);
-int host_hci_cmd_le_set_scan_rsp_data(uint8_t *data, uint8_t len);
 int host_hci_cmd_build_le_set_adv_data(uint8_t *data, uint8_t len,
                                        uint8_t *dst, int dst_len);
-int host_hci_cmd_le_set_adv_data(uint8_t *data, uint8_t len);
 int host_hci_cmd_build_le_set_adv_params(struct hci_adv_params *adv,
                                          uint8_t *dst, int dst_len);
-int host_hci_cmd_le_set_adv_params(struct hci_adv_params *adv);
-int host_hci_cmd_le_set_rand_addr(uint8_t *addr);
 void host_hci_cmd_build_le_set_event_mask(uint64_t event_mask,
                                           uint8_t *dst, int dst_len);
-int host_hci_cmd_le_set_event_mask(uint64_t event_mask);
 void host_hci_cmd_build_le_read_buffer_size(uint8_t *dst, int dst_len);
 int host_hci_cmd_le_read_buffer_size(void);
 void host_hci_cmd_build_le_read_loc_supp_feat(uint8_t *dst, uint8_t dst_len);
-int host_hci_cmd_le_read_loc_supp_feat(void);
-int host_hci_cmd_le_read_rem_used_feat(uint16_t handle);
 void host_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst,
                                           int dst_len);
 int host_hci_cmd_le_set_adv_enable(uint8_t enable);
@@ -72,10 +57,6 @@ int host_hci_cmd_build_le_set_scan_params(uint8_t scan_type,
                                           uint8_t own_addr_type,
                                           uint8_t filter_policy,
                                           uint8_t *cmd, int cmd_len);
-int host_hci_cmd_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl,
-                                    uint16_t scan_window,
-                                    uint8_t own_addr_type,
-                                    uint8_t filter_policy);
 void host_hci_cmd_build_le_set_scan_enable(uint8_t enable,
                                            uint8_t filter_dups,
                                            uint8_t *dst, uint8_t dst_len);
@@ -84,12 +65,8 @@ int host_hci_cmd_build_le_create_connection(struct hci_create_conn *hcc,
                                             uint8_t *cmd, int cmd_len);
 int host_hci_cmd_le_create_connection(struct hci_create_conn *hcc);
 void host_hci_cmd_build_le_clear_whitelist(uint8_t *dst, int dst_len);
-int host_hci_cmd_le_clear_whitelist(void);
-int host_hci_cmd_le_read_whitelist(void);
 int host_hci_cmd_build_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type,
                                            uint8_t *dst, int dst_len);
-int host_hci_cmd_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type);
-int host_hci_cmd_le_rmv_from_whitelist(uint8_t *addr, uint8_t addr_type);
 void host_hci_cmd_build_reset(uint8_t *dst, int dst_len);
 int host_hci_cmd_reset(void);
 void host_hci_cmd_build_read_adv_pwr(uint8_t *dst, int dst_len);
@@ -109,18 +86,9 @@ int host_hci_cmd_le_conn_param_reply(struct hci_conn_param_reply *hcr);
 void host_hci_cmd_build_le_conn_param_neg_reply(
     struct hci_conn_param_neg_reply *hcn, uint8_t *dst, int dst_len);
 int host_hci_cmd_le_conn_param_neg_reply(struct hci_conn_param_neg_reply *hcn);
-int host_hci_cmd_le_read_supp_states(void);
-int host_hci_cmd_le_read_max_datalen(void);
-int host_hci_cmd_le_read_sugg_datalen(void);
-int host_hci_cmd_le_write_sugg_datalen(uint16_t txoctets, uint16_t txtime);
-int host_hci_cmd_le_set_datalen(uint16_t handle, uint16_t txoctets,
-                                uint16_t txtime);
-int host_hci_cmd_le_encrypt(uint8_t *key, uint8_t *pt);
 void host_hci_cmd_build_le_rand(uint8_t *dst, int dst_len);
-int host_hci_cmd_le_rand(void);
 void host_hci_cmd_build_le_start_encrypt(struct hci_start_encrypt *cmd,
                                          uint8_t *dst, int dst_len);
-int host_hci_cmd_le_start_encrypt(struct hci_start_encrypt *cmd);
 int host_hci_set_buf_size(uint16_t pktlen, uint8_t max_pkts);
 
 uint16_t host_hci_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d8a3a76/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 c8c79f1..8a923ae 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -137,25 +137,6 @@ host_hci_cmd_body_le_whitelist_chg(uint8_t *addr, uint8_t addr_type,
 }
 
 static int
-host_hci_cmd_le_whitelist_chg(uint8_t *addr, uint8_t addr_type, uint8_t ocf)
-{
-    uint8_t cmd[BLE_HCI_CHG_WHITE_LIST_LEN];
-    int rc;
-
-    rc = host_hci_cmd_body_le_whitelist_chg(addr, addr_type, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = host_hci_le_cmd_send(ocf, BLE_HCI_CHG_WHITE_LIST_LEN, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-static int
 host_hci_cmd_body_le_set_adv_params(struct hci_adv_params *adv, uint8_t *dst)
 {
     uint16_t itvl;
@@ -223,26 +204,6 @@ host_hci_cmd_build_le_set_adv_params(struct hci_adv_params *adv, uint8_t *dst,
     return 0;
 }
 
-int
-host_hci_cmd_le_set_adv_params(struct hci_adv_params *adv)
-{
-    int rc;
-    uint8_t cmd[BLE_HCI_SET_ADV_PARAM_LEN];
-
-    rc = host_hci_cmd_body_le_set_adv_params(adv, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_ADV_PARAMS,
-                              BLE_HCI_SET_ADV_PARAM_LEN, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
 /**
  * Set advertising data
  *
@@ -303,37 +264,6 @@ host_hci_cmd_build_le_set_adv_data(uint8_t *data, uint8_t len, uint8_t *dst,
     return 0;
 }
 
-/**
- * Set advertising data
- *
- * OGF = 0x08 (LE)
- * OCF = 0x0008
- *
- * @param data
- * @param len
- *
- * @return int
- */
-int
-host_hci_cmd_le_set_adv_data(uint8_t *data, uint8_t len)
-{
-    uint8_t cmd[BLE_HCI_SET_ADV_DATA_LEN];
-    int rc;
-
-    rc = host_hci_cmd_body_le_set_adv_data(data, len, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_ADV_DATA,
-                              BLE_HCI_SET_ADV_DATA_LEN, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
 static int
 host_hci_cmd_body_le_set_scan_rsp_data(uint8_t *data, uint8_t len,
                                        uint8_t *dst)
@@ -372,90 +302,6 @@ host_hci_cmd_build_le_set_scan_rsp_data(uint8_t *data, uint8_t len,
     return 0;
 }
 
-int
-host_hci_cmd_le_set_scan_rsp_data(uint8_t *data, uint8_t len)
-{
-    int rc;
-    uint8_t cmd[BLE_HCI_SET_SCAN_RSP_DATA_LEN];
-
-    rc = host_hci_cmd_body_le_set_scan_rsp_data(data, len, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA,
-                              BLE_HCI_SET_SCAN_RSP_DATA_LEN, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/**
- * ble host hci cmd le set rand addr
- *
- * Sets the random address to be used in advertisements.
- *
- * @param addr Pointer to the random address to send to device
- *
- * @return int
- */
-int
-host_hci_cmd_le_set_rand_addr(uint8_t *addr)
-{
-    int rc;
-
-    /* Check for valid parameters */
-    rc = -1;
-    if (addr) {
-        rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_RAND_ADDR,
-                                  BLE_DEV_ADDR_LEN, addr);
-    }
-
-    return rc;
-}
-
-int
-host_hci_cmd_rd_local_version(void)
-{
-    int rc;
-
-    rc = host_hci_cmd_send(BLE_HCI_OGF_INFO_PARAMS,
-                           BLE_HCI_OCF_IP_RD_LOCAL_VER, 0, NULL);
-    return rc;
-}
-
-int
-host_hci_cmd_rd_local_feat(void)
-{
-    int rc;
-
-    rc = host_hci_cmd_send(BLE_HCI_OGF_INFO_PARAMS,
-                           BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT, 0, NULL);
-    return rc;
-}
-
-int
-host_hci_cmd_rd_local_cmd(void)
-{
-    int rc;
-
-    rc = host_hci_cmd_send(BLE_HCI_OGF_INFO_PARAMS,
-                           BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD, 0, NULL);
-    return rc;
-}
-
-int
-host_hci_cmd_rd_bd_addr(void)
-{
-    int rc;
-
-    rc = host_hci_cmd_send(BLE_HCI_OGF_INFO_PARAMS,
-                           BLE_HCI_OCF_IP_RD_BD_ADDR, 0, NULL);
-    return rc;
-}
-
 static void
 host_hci_cmd_body_set_event_mask(uint64_t event_mask, uint8_t *dst)
 {
@@ -477,20 +323,6 @@ host_hci_cmd_build_set_event_mask(uint64_t event_mask,
     host_hci_cmd_body_set_event_mask(event_mask, dst);
 }
 
-int
-host_hci_cmd_set_event_mask(uint64_t event_mask)
-{
-    int rc;
-    uint8_t cmd[BLE_HCI_SET_EVENT_MASK_LEN];
-
-    host_hci_cmd_body_set_event_mask(event_mask, cmd);
-    rc = host_hci_cmd_send(BLE_HCI_OGF_CTLR_BASEBAND,
-                           BLE_HCI_OCF_CB_SET_EVENT_MASK,
-                           BLE_HCI_SET_EVENT_MASK_LEN,
-                           cmd);
-    return rc;
-}
-
 static void
 host_hci_cmd_body_disconnect(uint16_t handle, uint8_t reason, uint8_t *dst)
 {
@@ -526,18 +358,6 @@ host_hci_cmd_disconnect(uint16_t handle, uint8_t reason)
     return rc;
 }
 
-int
-host_hci_cmd_rd_rem_version(uint16_t handle)
-{
-    int rc;
-    uint8_t cmd[sizeof(uint16_t)];
-
-    htole16(cmd, handle);
-    rc = host_hci_cmd_send(BLE_HCI_OGF_LINK_CTRL,
-                           BLE_HCI_OCF_RD_REM_VER_INFO, sizeof(uint16_t), cmd);
-    return rc;
-}
-
 static void
 host_hci_cmd_body_le_set_event_mask(uint64_t event_mask, uint8_t *dst)
 {
@@ -559,20 +379,6 @@ host_hci_cmd_build_le_set_event_mask(uint64_t event_mask,
     host_hci_cmd_body_le_set_event_mask(event_mask, dst);
 }
 
-int
-host_hci_cmd_le_set_event_mask(uint64_t event_mask)
-{
-    uint8_t cmd[BLE_HCI_SET_LE_EVENT_MASK_LEN];
-
-    int rc;
-
-    host_hci_cmd_body_le_set_event_mask(event_mask, cmd);
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_EVENT_MASK, sizeof(uint64_t),
-                              cmd);
-
-    return rc;
-}
-
 /**
  * LE Read buffer size
  *
@@ -590,103 +396,18 @@ host_hci_cmd_build_le_read_buffer_size(uint8_t *dst, int dst_len)
 
 /**
  * LE Read buffer size
- *  
- * OGF = 0x08 (LE) 
- * OCF = 0x0002 
- * 
- * @return int 
- */
-int
-host_hci_cmd_le_read_buffer_size(void)
-{
-    int rc;
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_BUF_SIZE, 0, NULL);
-    return rc;
-}
-
-/**
- * Read supported states
- *
- * OGF = 0x08 (LE)
- * OCF = 0x001C
- *
- * @return int
- */
-int
-host_hci_cmd_le_read_supp_states(void)
-{
-    return host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_SUPP_STATES, 0, NULL);
-}
-
-/**
- * Read maximum data length
- *
- * OGF = 0x08 (LE)
- * OCF = 0x002F
- *
- * @return int
- */
-int
-host_hci_cmd_le_read_max_datalen(void)
-{
-    return host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_MAX_DATA_LEN, 0, NULL);
-}
-
-/**
- * Set data length command
- *
- * OGF = 0x08 (LE)
- * OCF = 0x0022
- *
- * @return int
- */
-int
-host_hci_cmd_le_set_datalen(uint16_t handle, uint16_t txoctets, uint16_t txtime)
-{
-    int rc;
-    uint8_t cmd[BLE_HCI_SET_DATALEN_LEN];
-
-    htole16(cmd, handle);
-    htole16(cmd + 2, txoctets);
-    htole16(cmd + 4, txtime);
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_DATA_LEN,
-                              BLE_HCI_SET_DATALEN_LEN, cmd);
-    return rc;
-}
-
-/**
- * Read suggested default data length
- *
- * OGF = 0x08 (LE)
- * OCF = 0x0023
- *
- * @return int
- */
-int
-host_hci_cmd_le_read_sugg_datalen(void)
-{
-    return host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN, 0, NULL);
-}
-
-/**
- * write suggested default data length
  *
  * OGF = 0x08 (LE)
- * OCF = 0x0024
+ * OCF = 0x0002
  *
  * @return int
  */
 int
-host_hci_cmd_le_write_sugg_datalen(uint16_t txoctets, uint16_t txtime)
+host_hci_cmd_le_read_buffer_size(void)
 {
     int rc;
-    uint8_t cmd[BLE_HCI_WR_SUGG_DATALEN_LEN];
 
-    htole16(cmd, txoctets);
-    htole16(cmd + 2, txtime);
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_WR_SUGG_DEF_DATA_LEN,
-                              BLE_HCI_WR_SUGG_DATALEN_LEN, cmd);
+    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_BUF_SIZE, 0, NULL);
     return rc;
 }
 
@@ -701,34 +422,6 @@ host_hci_cmd_build_le_read_loc_supp_feat(uint8_t *dst, uint8_t dst_len)
                        0, dst);
 }
 
-/**
- * OGF=LE, OCF=0x0003
- */
-int
-host_hci_cmd_le_read_loc_supp_feat(void)
-{
-    int rc;
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT, 0, NULL);
-    return rc;
-}
-
-/**
- * OGF=LE, OCF=0x0016
- */
-int
-host_hci_cmd_le_read_rem_used_feat(uint16_t handle)
-{
-    int rc;
-    uint8_t cmd[BLE_HCI_CONN_RD_REM_FEAT_LEN];
-
-    htole16(cmd, handle);
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_REM_FEAT,
-                              BLE_HCI_CONN_RD_REM_FEAT_LEN,
-                              cmd);
-    return rc;
-}
-
 static void
 host_hci_cmd_body_le_set_adv_enable(uint8_t enable, uint8_t *dst)
 {
@@ -749,19 +442,6 @@ host_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst,
     host_hci_cmd_body_le_set_adv_enable(enable, dst);
 }
 
-int
-host_hci_cmd_le_set_adv_enable(uint8_t enable)
-{
-    int rc;
-    uint8_t cmd[BLE_HCI_SET_ADV_ENABLE_LEN];
-
-    host_hci_cmd_body_le_set_adv_enable(enable, cmd);
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_ADV_ENABLE,
-                              BLE_HCI_SET_ADV_ENABLE_LEN, cmd);
-
-    return rc;
-}
-
 static int
 host_hci_cmd_body_le_set_scan_params(
     uint8_t scan_type, uint16_t scan_itvl, uint16_t scan_window,
@@ -827,26 +507,6 @@ host_hci_cmd_build_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl,
     return 0;
 }
 
-int
-host_hci_cmd_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl,
-                                uint16_t scan_window, uint8_t own_addr_type,
-                                uint8_t filter_policy) {
-    int rc;
-    uint8_t cmd[BLE_HCI_SET_SCAN_PARAM_LEN];
-
-    rc = host_hci_cmd_body_le_set_scan_params(scan_type, scan_itvl,
-                                              scan_window, own_addr_type,
-                                              filter_policy, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_SCAN_PARAMS,
-                              BLE_HCI_SET_SCAN_PARAM_LEN, cmd);
-
-    return rc;
-}
-
 static void
 host_hci_cmd_body_le_set_scan_enable(uint8_t enable, uint8_t filter_dups,
                                      uint8_t *dst)
@@ -869,19 +529,6 @@ host_hci_cmd_build_le_set_scan_enable(uint8_t enable, uint8_t filter_dups,
                                          dst + BLE_HCI_CMD_HDR_LEN);
 }
 
-int
-host_hci_cmd_le_set_scan_enable(uint8_t enable, uint8_t filter_dups)
-{
-    int rc;
-    uint8_t cmd[BLE_HCI_SET_SCAN_ENABLE_LEN];
-
-    host_hci_cmd_body_le_set_scan_enable(enable, filter_dups, cmd);
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_SCAN_ENABLE,
-                              BLE_HCI_SET_SCAN_ENABLE_LEN, cmd);
-    return rc;
-}
-
 static int
 host_hci_cmd_body_le_create_connection(struct hci_create_conn *hcc,
                                        uint8_t *cmd)
@@ -977,26 +624,6 @@ host_hci_cmd_build_le_create_connection(struct hci_create_conn *hcc,
     return 0;
 }
 
-int
-host_hci_cmd_le_create_connection(struct hci_create_conn *hcc)
-{
-    uint8_t cmd[BLE_HCI_CREATE_CONN_LEN];
-    int rc;
-
-    rc = host_hci_cmd_body_le_create_connection(hcc, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_CREATE_CONN,
-                              BLE_HCI_CREATE_CONN_LEN, cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
 void
 host_hci_cmd_build_le_clear_whitelist(uint8_t *dst, int dst_len)
 {
@@ -1005,36 +632,6 @@ host_hci_cmd_build_le_clear_whitelist(uint8_t *dst, int dst_len)
                        0, dst);
 }
 
-/**
- * Clear the whitelist.
- *
- * @return int
- */
-int
-host_hci_cmd_le_clear_whitelist(void)
-{
-    int rc;
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_CLEAR_WHITE_LIST, 0, NULL);
-    return rc;
-}
-
-/**
- * Read the whitelist size. Note that this is not how many elements have
- * been added to the whitelist; rather it is the number of whitelist entries
- * allowed by the controller.
- *
- * @return int
- */
-int
-host_hci_cmd_le_read_whitelist(void)
-{
-    int rc;
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_WHITE_LIST_SIZE, 0, NULL);
-    return rc;
-}
-
 int
 host_hci_cmd_build_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type,
                                        uint8_t *dst, int dst_len)
@@ -1056,43 +653,6 @@ host_hci_cmd_build_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type,
     return 0;
 }
 
-/**
- * Add a device to the whitelist.
- *
- * @param addr
- * @param addr_type
- *
- * @return int
- */
-int
-host_hci_cmd_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type)
-{
-    int rc;
-
-    rc = host_hci_cmd_le_whitelist_chg(addr, addr_type,
-                                       BLE_HCI_OCF_LE_ADD_WHITE_LIST);
-
-    return rc;
-}
-
-/**
- * Remove a device from the whitelist.
- *
- * @param addr
- * @param addr_type
- *
- * @return int
- */
-int
-host_hci_cmd_le_rmv_from_whitelist(uint8_t *addr, uint8_t addr_type)
-{
-    int rc;
-
-    rc = host_hci_cmd_le_whitelist_chg(addr, addr_type,
-                                       BLE_HCI_OCF_LE_RMV_WHITE_LIST);
-    return rc;
-}
-
 void
 host_hci_cmd_build_reset(uint8_t *dst, int dst_len)
 {
@@ -1370,66 +930,6 @@ host_hci_cmd_le_conn_param_neg_reply(struct hci_conn_param_neg_reply *hcn)
 }
 
 /**
- * Read the channel map for a given connection.
- *
- * @param handle
- *
- * @return int
- */
-int
-host_hci_cmd_le_rd_chanmap(uint16_t handle)
-{
-    int rc;
-    uint8_t cmd[BLE_HCI_RD_CHANMAP_LEN];
-
-    htole16(cmd, handle);
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_CHAN_MAP,
-                              BLE_HCI_RD_CHANMAP_LEN, cmd);
-    return rc;
-}
-
-/**
- * Set the channel map in the controller
- *
- * @param chanmap
- *
- * @return int
- */
-int
-host_hci_cmd_le_set_host_chan_class(uint8_t *chanmap)
-{
-    int rc;
-
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS,
-                              BLE_HCI_SET_HOST_CHAN_CLASS_LEN, chanmap);
-    return rc;
-}
-
-/**
- * Encrypt a block.
- *
- * OGF = 0x08 (LE)
- * OCF = 0x0017
- *
- * @param key
- * @param pt
- *
- * @return int
- */
-int
-host_hci_cmd_le_encrypt(uint8_t *key, uint8_t *pt)
-{
-    int rc;
-    uint8_t cmd[BLE_HCI_LE_ENCRYPT_LEN];
-
-    swap_buf(cmd, key, BLE_ENC_BLOCK_SIZE);
-    swap_buf(cmd + BLE_ENC_BLOCK_SIZE, pt, BLE_ENC_BLOCK_SIZE);
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_ENCRYPT, BLE_HCI_LE_ENCRYPT_LEN,
-                              cmd);
-    return rc;
-}
-
-/**
  * Get random data
  *
  * OGF = 0x08 (LE)
@@ -1444,20 +944,6 @@ host_hci_cmd_build_le_rand(uint8_t *dst, int dst_len)
     host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RAND, 0, dst);
 }
 
-/**
- * Get random data
- *  
- * OGF = 0x08 (LE) 
- * OCF = 0x0018
- *
- * @return int
- */
-int
-host_hci_cmd_le_rand(void)
-{
-    return host_hci_le_cmd_send(BLE_HCI_OCF_LE_RAND, 0, NULL);
-}
-
 static void
 host_hci_cmd_body_le_start_encrypt(struct hci_start_encrypt *cmd, uint8_t *dst)
 {
@@ -1482,24 +968,6 @@ host_hci_cmd_build_le_start_encrypt(struct hci_start_encrypt *cmd,
 }
 
 /**
- * Enables encryption on a connection.
- *
- * OGF = 0x08 (LE)
- * OCF = 0x0019
- *
- * @return int
- */
-int
-host_hci_cmd_le_start_encrypt(struct hci_start_encrypt *cmd)
-{
-    uint8_t buf[BLE_HCI_LE_START_ENCRYPT_LEN];
-
-    host_hci_cmd_body_le_start_encrypt(cmd, buf);
-
-    return host_hci_le_cmd_send(BLE_HCI_OCF_LE_START_ENCRYPT, sizeof buf, buf);
-}
-
-/**
  * Read the RSSI for a given connection handle
  *
  * NOTE: OGF=0x05 OCF=0x0005
@@ -1526,24 +994,3 @@ host_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, int dst_len)
 
     host_hci_cmd_body_read_rssi(handle, dst);
 }
-
-/**
- * Read the RSSI for a given connection handle
- *
- * NOTE: OGF=0x05 OCF=0x0005
- *
- * @param handle
- *
- * @return int
- */
-int
-host_hci_cmd_read_rssi(uint16_t handle)
-{
-    uint8_t cmd[BLE_HCI_READ_RSSI_LEN];
-    int rc;
-
-    htole16(cmd, handle);
-    rc = host_hci_cmd_send(BLE_HCI_OGF_STATUS_PARAMS, BLE_HCI_OCF_RD_RSSI,
-                           BLE_HCI_READ_RSSI_LEN, cmd);
-    return rc;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6d8a3a76/net/nimble/include/nimble/hci_common.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h
index 499a898..50d6142 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -294,6 +294,7 @@
 
 /* --- LE read channel map command (OCF 0x0015) */
 #define BLE_HCI_RD_CHANMAP_LEN              (2)
+#define BLE_HCI_RD_CHANMAP_RSP_LEN          (7)
 
 /* --- LE read remote features (OCF 0x0016) */
 #define BLE_HCI_CONN_RD_REM_FEAT_LEN        (2)


[42/50] [abbrv] incubator-mynewt-core git commit: MYNEWT-99: implement encryption pause procedure

Posted by ma...@apache.org.
MYNEWT-99: implement encryption pause procedure

This allows keys to be changed on an already encrypted connection.
The code was tested on a bmd300, nrf52dk and also a nrf51. The
nrf51 with encryption enabled was disconnecting and/or getting
MIC failures with large frames; was working fine for small
frames. We are investigating similar issues on the nrf51 so I
do not necessarily believe these to be encryption related which
is why I am committing the changes.


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

Branch: refs/heads/master
Commit: 470262a29a9bccfbffbd27b83c139cc109e5c2af
Parents: 4ad86e9
Author: William San Filippo <wi...@runtime.io>
Authored: Mon Apr 25 20:06:00 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Mon Apr 25 20:11:39 2016 -0700

----------------------------------------------------------------------
 apps/bletest/src/bletest_hci.c                  |  48 ++++++-
 apps/bletest/src/bletest_priv.h                 |   4 +-
 apps/bletest/src/main.c                         |  20 ++-
 .../controller/include/controller/ble_ll_conn.h |   3 +
 .../controller/include/controller/ble_ll_ctrl.h |   4 -
 net/nimble/controller/src/ble_ll_conn.c         | 101 +++++++++++++-
 net/nimble/controller/src/ble_ll_conn_hci.c     |   8 +-
 net/nimble/controller/src/ble_ll_ctrl.c         | 138 ++++++++++++++-----
 net/nimble/controller/src/ble_ll_hci_ev.c       |  27 +++-
 net/nimble/host/include/host/host_hci.h         |   1 -
 net/nimble/host/src/host_dbg.c                  |  25 +++-
 net/nimble/host/src/host_hci_cmd.c              |  38 -----
 net/nimble/include/nimble/hci_common.h          |   1 +
 13 files changed, 319 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/apps/bletest/src/bletest_hci.c
----------------------------------------------------------------------
diff --git a/apps/bletest/src/bletest_hci.c b/apps/bletest/src/bletest_hci.c
index 785edd9..b4dcd8b 100755
--- a/apps/bletest/src/bletest_hci.c
+++ b/apps/bletest/src/bletest_hci.c
@@ -41,6 +41,8 @@
 #include "../src/ble_hs_priv.h"
 #include "bletest_priv.h"
 
+extern uint16_t g_bletest_ltk_reply_handle;
+
 void
 bletest_send_conn_update(uint16_t handle)
 {
@@ -66,20 +68,58 @@ bletest_ltk_req_reply(uint16_t handle)
     g_bletest_ltk_reply_handle = handle;
 }
 
-void
+int
 bletest_send_ltk_req_neg_reply(uint16_t handle)
 {
-    host_hci_cmd_le_lt_key_req_neg_reply(handle);
+    int rc;
+    uint8_t *dst;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + sizeof(uint16_t)];
+    uint16_t ack_conn_handle;
+    uint8_t rsplen;
+
+    dst = buf;
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY,
+                       sizeof(uint16_t), dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    htole16(dst, handle);
+    rc = ble_hci_cmd_tx(buf, &ack_conn_handle, 2, &rsplen);
+    if (rc == 0) {
+        if (rsplen != 2) {
+            rc = -1;
+        }
+    }
+
+    return rc;
 }
 
-void
+int
 bletest_send_ltk_req_reply(uint16_t handle)
 {
     struct hci_lt_key_req_reply hkr;
+    uint16_t ack_conn_handle;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LT_KEY_REQ_REPLY_LEN];
+    uint8_t ack_params_len;
+    int rc;
 
     hkr.conn_handle = handle;
     swap_buf(hkr.long_term_key, (uint8_t *)g_bletest_LTK, 16);
-    host_hci_cmd_le_lt_key_req_reply(&hkr);
+
+    host_hci_cmd_build_le_lt_key_req_reply(&hkr, buf, sizeof buf);
+    rc = ble_hci_cmd_tx(buf, &ack_conn_handle, sizeof ack_conn_handle,
+                        &ack_params_len);
+    if (rc != 0) {
+        return rc;
+    }
+    if (ack_params_len != BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN - 1) {
+        return -1;
+    }
+
+    ack_conn_handle = TOFROMLE16(ack_conn_handle);
+    if (ack_conn_handle != handle) {
+        return -1;
+    }
+    return 0;
 }
 #endif
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/apps/bletest/src/bletest_priv.h
----------------------------------------------------------------------
diff --git a/apps/bletest/src/bletest_priv.h b/apps/bletest/src/bletest_priv.h
index d44dcfe..db4d4b9 100644
--- a/apps/bletest/src/bletest_priv.h
+++ b/apps/bletest/src/bletest_priv.h
@@ -24,8 +24,8 @@ void bletest_send_conn_update(uint16_t handle);
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
 void bletest_ltk_req_reply(uint16_t handle);
-void bletest_send_ltk_req_neg_reply(uint16_t handle);
-void bletest_send_ltk_req_reply(uint16_t handle);
+int bletest_send_ltk_req_neg_reply(uint16_t handle);
+int bletest_send_ltk_req_reply(uint16_t handle);
 int bletest_hci_le_start_encrypt(struct hci_start_encrypt *cmd);
 int bletest_hci_le_encrypt(uint8_t *key, uint8_t *pt);
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/apps/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c
index aa713ac..9510641 100755
--- a/apps/bletest/src/main.c
+++ b/apps/bletest/src/main.c
@@ -514,6 +514,20 @@ bletest_execute_initiator(void)
                     }
                 }
 #endif
+            } else if (g_bletest_state == 8) {
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+                struct hci_start_encrypt hsle;
+                for (i = 0; i < g_bletest_current_conns; ++i) {
+                    if (ble_ll_conn_find_active_conn(i + 1)) {
+                        hsle.connection_handle = i + 1;
+                        hsle.encrypted_diversifier = g_bletest_EDIV;
+                        hsle.random_number = ~g_bletest_RAND;
+                        swap_buf(hsle.long_term_key, (uint8_t *)g_bletest_LTK,
+                                 16);
+                        bletest_hci_le_start_encrypt(&hsle);
+                    }
+                }
+#endif
             } else {
                 for (i = 0; i < g_bletest_current_conns; ++i) {
                     if (ble_ll_conn_find_active_conn(i + 1)) {
@@ -521,8 +535,10 @@ bletest_execute_initiator(void)
                     }
                 }
             }
-            if (g_bletest_state < 5) {
-                ++g_bletest_state;
+
+            ++g_bletest_state;
+            if (g_bletest_state > 9) {
+                g_bletest_state = 9;
             }
             g_next_os_time = os_time_get() + OS_TICKS_PER_SEC * 3;
         }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/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 f9937aa..36079c8 100644
--- a/net/nimble/controller/include/controller/ble_ll_conn.h
+++ b/net/nimble/controller/include/controller/ble_ll_conn.h
@@ -67,6 +67,7 @@ enum conn_enc_state {
     CONN_ENC_S_ENC_RSP_WAIT,
     CONN_ENC_S_START_ENC_REQ_WAIT,
     CONN_ENC_S_START_ENC_RSP_WAIT,
+    CONN_ENC_S_PAUSE_ENC_RSP_WAIT,
     CONN_ENC_S_LTK_REQ_WAIT,
     CONN_ENC_S_LTK_NEG_REPLY
 };
@@ -108,6 +109,7 @@ union ble_ll_conn_sm_flags {
         uint32_t conn_req_txd:1;
         uint32_t send_ltk_req:1;
         uint32_t encrypted:1;
+        uint32_t encrypt_chg_sent;
     } cfbit;
     uint32_t conn_flags;
 } __attribute__((packed));
@@ -255,6 +257,7 @@ struct ble_ll_conn_sm
 #define CONN_F_LAST_TXD_MD(csm)     ((csm)->csmflags.cfbit.last_txd_md)
 #define CONN_F_CONN_REQ_TXD(csm)    ((csm)->csmflags.cfbit.conn_req_txd)
 #define CONN_F_ENCRYPTED(csm)       ((csm)->csmflags.cfbit.encrypted)
+#define CONN_F_ENC_CHANGE_SENT(csm) ((csm)->csmflags.cfbit.encrypt_chg_sent)
 
 /* Role */
 #define CONN_IS_MASTER(csm)         (csm->conn_role == BLE_LL_CONN_ROLE_MASTER)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/net/nimble/controller/include/controller/ble_ll_ctrl.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_ctrl.h b/net/nimble/controller/include/controller/ble_ll_ctrl.h
index 4a9b1df..a5cd99b 100644
--- a/net/nimble/controller/include/controller/ble_ll_ctrl.h
+++ b/net/nimble/controller/include/controller/ble_ll_ctrl.h
@@ -139,9 +139,6 @@ struct ble_ll_enc_rsp
  */
 #define BLE_LL_CTRL_FEATURE_LEN             (8)
 
-/* LL control pause enc req and pause enc rsp have no data */
-#define BLE_LL_CTRL_PAUSE_ENC_LEN           (0)
-
 /*
  * LL control version ind
  *  -> version (1 byte):
@@ -237,7 +234,6 @@ int ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm, uint8_t opcode);
 int ble_ll_ctrl_enc_allowed_pdu(struct os_mbuf_pkthdr *pkthdr);
 int ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm);
 int ble_ll_ctrl_is_start_enc_rsp(struct os_mbuf *txpdu);
-int ble_ll_ctrl_is_start_enc_req(struct os_mbuf *txpdu);
 
 void ble_ll_hci_ev_datalen_chg(struct ble_ll_conn_sm *connsm);
 void ble_ll_hci_ev_rem_conn_parm_req(struct ble_ll_conn_sm *connsm,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/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 da9acb4..05b2c6c 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -609,6 +609,16 @@ ble_ll_conn_start_rx_encrypt(void *arg)
 }
 
 static void
+ble_ll_conn_start_rx_unencrypt(void *arg)
+{
+    struct ble_ll_conn_sm *connsm;
+
+    connsm = (struct ble_ll_conn_sm *)arg;
+    CONN_F_ENCRYPTED(connsm) = 0;
+    ble_phy_encrypt_disable();
+}
+
+static void
 ble_ll_conn_txend_encrypt(void *arg)
 {
     struct ble_ll_conn_sm *connsm;
@@ -620,6 +630,17 @@ ble_ll_conn_txend_encrypt(void *arg)
 }
 
 static void
+ble_ll_conn_rxend_unencrypt(void *arg)
+{
+    struct ble_ll_conn_sm *connsm;
+
+    connsm = (struct ble_ll_conn_sm *)arg;
+    CONN_F_ENCRYPTED(connsm) = 0;
+    ble_ll_conn_current_sm_over();
+    ble_ll_event_send(&connsm->conn_ev_end);
+}
+
+static void
 ble_ll_conn_continue_rx_encrypt(void *arg)
 {
     struct ble_ll_conn_sm *connsm;
@@ -953,14 +974,34 @@ conn_tx_pdu:
     }
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-    if (ble_ll_ctrl_is_start_enc_rsp(m)) {
+    int is_ctrl;
+    uint8_t llid;
+    uint8_t opcode;
+
+    llid = ble_hdr->txinfo.hdr_byte & BLE_LL_DATA_HDR_LLID_MASK;
+    if (llid == BLE_LL_LLID_CTRL) {
+        is_ctrl = 1;
+        opcode = m->om_data[0];
+    } else {
+        is_ctrl = 0;
+    }
+
+    if (is_ctrl && (opcode == BLE_LL_CTRL_START_ENC_RSP)) {
+        /*
+         * Both master and slave send the START_ENC_RSP encrypted and receive
+         * encrypted
+         */
         CONN_F_ENCRYPTED(connsm) = 1;
         connsm->enc_data.tx_encrypted = 1;
         ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr,
                                connsm->enc_data.iv,
                                connsm->enc_data.enc_block.cipher_text,
                                CONN_IS_MASTER(connsm));
-    } else if (ble_ll_ctrl_is_start_enc_req(m)) {
+    } else if (is_ctrl && (opcode == BLE_LL_CTRL_START_ENC_REQ)) {
+        /*
+         * Only the slave sends this and it gets sent unencrypted but
+         * we receive encrypted
+         */
         CONN_F_ENCRYPTED(connsm) = 0;
         connsm->enc_data.enc_state = CONN_ENC_S_START_ENC_RSP_WAIT;
         connsm->enc_data.tx_encrypted = 0;
@@ -970,6 +1011,29 @@ conn_tx_pdu:
         } else {
             txend_func = ble_ll_conn_txend_encrypt;
         }
+    } else if (is_ctrl && (opcode == BLE_LL_CTRL_PAUSE_ENC_RSP)) {
+        /*
+         * The slave sends the PAUSE_ENC_RSP encrypted. The master sends
+         * it unencrypted (note that link was already set unencrypted).
+         */
+        if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
+            CONN_F_ENCRYPTED(connsm) = 1;
+            connsm->enc_data.tx_encrypted = 1;
+            ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr,
+                                   connsm->enc_data.iv,
+                                   connsm->enc_data.enc_block.cipher_text,
+                                   CONN_IS_MASTER(connsm));
+            if (txend_func == NULL) {
+                txend_func = ble_ll_conn_start_rx_unencrypt;
+            } else {
+                txend_func = ble_ll_conn_rxend_unencrypt;
+            }
+        } else {
+            CONN_F_ENCRYPTED(connsm) = 0;
+            connsm->enc_data.enc_state = CONN_ENC_S_UNENCRYPTED;
+            connsm->enc_data.tx_encrypted = 0;
+            ble_phy_encrypt_disable();
+        }
     } else {
         /* If encrypted set packet counter */
         if (CONN_F_ENCRYPTED(connsm)) {
@@ -1043,8 +1107,8 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
     ble_ll_state_set(BLE_LL_STATE_CONNECTION);
 
     /* Log connection event start */
-    ble_ll_log(BLE_LL_LOG_ID_CONN_EV_START, connsm->data_chan_index,
-               connsm->conn_handle, connsm->ce_end_time);
+    ble_ll_log(BLE_LL_LOG_ID_CONN_EV_START, (uint8_t)connsm->conn_handle,
+               (uint16_t)connsm->ce_end_time, connsm->csmflags.conn_flags);
 
     /* Set channel */
     ble_phy_setchan(connsm->data_chan_index, connsm->access_addr,
@@ -2208,7 +2272,6 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
                  */
                 if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) {
                     STATS_INC(ble_ll_conn_stats, mic_failures);
-                    /* Control procedure has timed out. Kill the connection */
                     ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
                     goto conn_rx_data_pdu_end;
                 }
@@ -2267,6 +2330,7 @@ int
 ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu, uint32_t aa)
 {
     int rc;
+    int is_ctrl;
     uint8_t hdr_byte;
     uint8_t hdr_sn;
     uint8_t hdr_nesn;
@@ -2274,6 +2338,7 @@ ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu, uint32_t aa)
     uint8_t conn_nesn;
     uint8_t reply;
     uint8_t rem_bytes;
+    uint8_t opcode;
     uint32_t ticks;
     struct os_mbuf *txpdu;
     struct ble_ll_conn_sm *connsm;
@@ -2443,7 +2508,14 @@ ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu, uint32_t aa)
         /* Should we continue connection event? */
         /* If this is a TERMINATE_IND, we have to reply */
 chk_rx_terminate_ind:
-        if (ble_ll_ctrl_is_terminate_ind(rxpdu->om_data[0],rxpdu->om_data[2])) {
+        is_ctrl = 0;
+        if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) {
+            is_ctrl = 1;
+            opcode = rxpdu->om_data[2];
+        }
+
+        /* If we received a terminate IND, we must set some flags */
+        if (is_ctrl && (opcode == BLE_LL_CTRL_TERMINATE_IND)) {
             connsm->csmflags.cfbit.terminate_ind_rxd = 1;
             connsm->rxd_disconnect_reason = rxpdu->om_data[3];
             reply = 1;
@@ -2452,6 +2524,11 @@ chk_rx_terminate_ind:
         } else {
             /* A slave always replies */
             reply = 1;
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+            if (is_ctrl && (opcode == BLE_LL_CTRL_PAUSE_ENC_RSP)) {
+                connsm->enc_data.enc_state = CONN_ENC_S_UNENCRYPTED;
+            }
+#endif
         }
     }
 
@@ -2463,6 +2540,8 @@ chk_rx_terminate_ind:
          * terminate timer will expire within two packet times. If it will,
          * no use sending the terminate ind. We need to get an ACK for the
          * terminate ind (master and/or slave) so that is why it is two packets.
+         *
+         *  XXX: should we just skip this check?
          */
         if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_TERMINATE)) {
             ticks = BLE_TX_DUR_USECS_M(0) +
@@ -2535,12 +2614,15 @@ ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om,
     lifo = 0;
 #if defined(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
     if (connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) {
+        uint8_t llid;
+
         /*
          * If this is one of the following types we need to insert it at
          * head of queue.
          */
         ble_hdr = BLE_MBUF_HDR_PTR(om);
-        if ((ble_hdr->txinfo.hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) {
+        llid = ble_hdr->txinfo.hdr_byte & BLE_LL_DATA_HDR_LLID_MASK;
+        if (llid == BLE_LL_LLID_CTRL) {
             switch (om->om_data[0]) {
             case BLE_LL_CTRL_TERMINATE_IND:
             case BLE_LL_CTRL_REJECT_IND:
@@ -2549,6 +2631,11 @@ ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om,
             case BLE_LL_CTRL_START_ENC_RSP:
                 lifo = 1;
                 break;
+            case BLE_LL_CTRL_PAUSE_ENC_RSP:
+                if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
+                    lifo = 1;
+                }
+                break;
             default:
                 break;
             }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/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 2802866..791fe4a 100644
--- a/net/nimble/controller/src/ble_ll_conn_hci.c
+++ b/net/nimble/controller/src/ble_ll_conn_hci.c
@@ -936,8 +936,14 @@ ble_ll_conn_hci_le_start_encrypt(uint8_t *cmdbuf)
         rc = BLE_ERR_UNK_CONN_ID;
     } else if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
         rc = BLE_ERR_UNSPECIFIED;
+    } else if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_ENCRYPT) {
+        /*
+         * The specification does not say what to do here but the host should
+         * not be telling us to start encryption while we are in the process
+         * of honoring a previous start encrypt.
+         */
+        rc = BLE_ERR_CMD_DISALLOWED;
     } else {
-        /* XXX: implement pause procedure */
         /* Start the control procedure */
         connsm->enc_data.host_rand_num = le64toh(cmdbuf + 2);
         connsm->enc_data.enc_div = le16toh(cmdbuf + 10);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/net/nimble/controller/src/ble_ll_ctrl.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_ctrl.c b/net/nimble/controller/src/ble_ll_ctrl.c
index 63b4c98..e72e0f9 100644
--- a/net/nimble/controller/src/ble_ll_ctrl.c
+++ b/net/nimble/controller/src/ble_ll_ctrl.c
@@ -367,6 +367,19 @@ ble_ll_calc_session_key(struct ble_ll_conn_sm *connsm)
 #endif
 }
 
+/**
+ * Called to determine if this is a control PDU we are allowed to send. This
+ * is called when a link is being encrypted, as only certain control PDU's
+ * area lowed to be sent.
+ *
+ * XXX: the current code may actually allow some control pdu's to be sent
+ * in states where they shouldnt. I dont expect those states to occur so I
+ * dont try to check for them but we could do more...
+ *
+ * @param pkthdr
+ *
+ * @return int
+ */
 int
 ble_ll_ctrl_enc_allowed_pdu(struct os_mbuf_pkthdr *pkthdr)
 {
@@ -390,6 +403,8 @@ ble_ll_ctrl_enc_allowed_pdu(struct os_mbuf_pkthdr *pkthdr)
         case BLE_LL_CTRL_START_ENC_REQ:
         case BLE_LL_CTRL_ENC_REQ:
         case BLE_LL_CTRL_ENC_RSP:
+        case BLE_LL_CTRL_PAUSE_ENC_REQ:
+        case BLE_LL_CTRL_PAUSE_ENC_RSP:
         case BLE_LL_CTRL_TERMINATE_IND:
             allowed = 1;
             break;
@@ -423,28 +438,6 @@ ble_ll_ctrl_is_start_enc_rsp(struct os_mbuf *txpdu)
     return is_start_enc_rsp;
 }
 
-int
-ble_ll_ctrl_is_start_enc_req(struct os_mbuf *txpdu)
-{
-    int is_start_enc_req;
-    uint8_t opcode;
-    uint8_t llid;
-    struct ble_mbuf_hdr *ble_hdr;
-
-    is_start_enc_req = 0;
-    ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
-
-    llid = ble_hdr->txinfo.hdr_byte & BLE_LL_DATA_HDR_LLID_MASK;
-    if (llid == BLE_LL_LLID_CTRL) {
-        opcode = txpdu->om_data[0];
-        if (opcode == BLE_LL_CTRL_START_ENC_REQ) {
-            is_start_enc_req = 1;
-        }
-    }
-
-    return is_start_enc_req;
-}
-
 /**
  * Called to create and send a LL_START_ENC_REQ or LL_START_ENC_RSP
  *
@@ -532,6 +525,11 @@ ble_ll_ctrl_rx_enc_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
 {
     /* Calculate session key now that we have received the ENC_RSP */
     if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_ENCRYPT) {
+        /* In case we were already encrypted we need to reset packet counters */
+        connsm->enc_data.rx_pkt_cntr = 0;
+        connsm->enc_data.tx_pkt_cntr = 0;
+        connsm->enc_data.tx_encrypted = 0;
+
         swap_buf(connsm->enc_data.enc_block.plain_text, dptr, 8);
         memcpy(connsm->enc_data.iv + 4, dptr + 8, 4);
         ble_ll_calc_session_key(connsm);
@@ -568,6 +566,11 @@ ble_ll_ctrl_rx_enc_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
         return BLE_ERR_MAX;
     }
 
+    /* In case we were already encrypted we need to reset packet counters */
+    connsm->enc_data.rx_pkt_cntr = 0;
+    connsm->enc_data.tx_pkt_cntr = 0;
+    connsm->enc_data.tx_encrypted = 0;
+
     /* Extract information from request */
     connsm->enc_data.host_rand_num = le64toh(dptr);
     connsm->enc_data.enc_div = le16toh(dptr + 8);
@@ -612,6 +615,46 @@ ble_ll_ctrl_rx_start_enc_req(struct ble_ll_conn_sm *connsm)
     return rc;
 }
 
+static uint8_t
+ble_ll_ctrl_rx_pause_enc_req(struct ble_ll_conn_sm *connsm)
+{
+    int rc;
+
+    /*
+     * The spec does not say what to do here, but if we receive a pause
+     * encryption request and we are not encrypted, what do we do? We
+     * ignore it...
+     */
+    rc = BLE_ERR_MAX;
+    if ((connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) &&
+        (connsm->enc_data.enc_state == CONN_ENC_S_ENCRYPTED)) {
+        rc = BLE_LL_CTRL_PAUSE_ENC_RSP;
+    }
+
+    return rc;
+}
+
+/**
+ * Called when a LL control pdu with opcode PAUSE_ENC_RSP is received.
+ *
+ *
+ * @param connsm
+ *
+ * @return uint8_t
+ */
+static uint8_t
+ble_ll_ctrl_rx_pause_enc_rsp(struct ble_ll_conn_sm *connsm)
+{
+    int rc;
+
+    rc = BLE_ERR_MAX;
+    if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
+        rc = BLE_LL_CTRL_PAUSE_ENC_RSP;
+    }
+
+    return rc;
+}
+
 /**
  * Called when we have received a LL_CTRL_START_ENC_RSP.
  *
@@ -1238,8 +1281,13 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc)
 #if defined(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
         /* XXX: deal with already encrypted connection.*/
         case BLE_LL_CTRL_PROC_ENCRYPT:
-            opcode = BLE_LL_CTRL_ENC_REQ;
-            ble_ll_ctrl_enc_req_make(connsm, ctrdata);
+            /* If we are already encrypted we do pause procedure */
+            if (connsm->enc_data.enc_state == CONN_ENC_S_ENCRYPTED) {
+                opcode = BLE_LL_CTRL_PAUSE_ENC_REQ;
+            } else {
+                opcode = BLE_LL_CTRL_ENC_REQ;
+                ble_ll_ctrl_enc_req_make(connsm, ctrdata);
+            }
             break;
 #endif
         default:
@@ -1427,6 +1475,8 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm)
  * NOTE: this function uses the received PDU for the response in some cases. If
  * the received PDU is not used it needs to be freed here.
  *
+ * XXX: may want to check, for both master and slave, whether the control
+ * pdu should be received by that role. Might make for less code...
  * Context: Link Layer
  *
  * @param om
@@ -1443,6 +1493,9 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
     uint8_t *dptr;
     uint8_t *rspbuf;
     uint8_t *rspdata;
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    int restart_encryption;
+#endif
 
     /* XXX: where do we validate length received and packet header length?
      * do this in LL task when received. Someplace!!! What I mean
@@ -1477,13 +1530,17 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
      */
     --len;
 
+    ble_ll_log(BLE_LL_LOG_ID_LL_CTRL_RX, opcode, len, 0);
+
     /* opcode must be good */
     if ((opcode >= BLE_LL_CTRL_OPCODES) ||
         (len != g_ble_ll_ctrl_pkt_lengths[opcode])) {
         goto rx_malformed_ctrl;
     }
 
-    ble_ll_log(BLE_LL_LOG_ID_LL_CTRL_RX, opcode, len, 0);
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    restart_encryption = 0;
+#endif
 
     /* Check if the feature is supported. */
     switch (opcode) {
@@ -1529,7 +1586,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
     }
 
     /* Process opcode */
-    rsp_opcode = 255;
+    rsp_opcode = BLE_ERR_MAX;
     switch (opcode) {
     case BLE_LL_CTRL_CONN_UPDATE_REQ:
         rsp_opcode = ble_ll_ctrl_rx_conn_update(connsm, dptr, rspbuf);
@@ -1589,7 +1646,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
     case BLE_LL_CTRL_SLAVE_FEATURE_REQ:
         rsp_opcode = ble_ll_ctrl_rx_feature_req(connsm, dptr, rspbuf, opcode);
         break;
-#if defined(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
     case BLE_LL_CTRL_ENC_REQ:
         rsp_opcode = ble_ll_ctrl_rx_enc_req(connsm, dptr, rspdata);
         break;
@@ -1599,13 +1656,17 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
     case BLE_LL_CTRL_START_ENC_REQ:
         rsp_opcode = ble_ll_ctrl_rx_start_enc_req(connsm);
         break;
-
     case BLE_LL_CTRL_START_ENC_RSP:
         rsp_opcode = ble_ll_ctrl_rx_start_enc_rsp(connsm);
         break;
-
     case BLE_LL_CTRL_PAUSE_ENC_REQ:
-        /* XXX: implement */
+        rsp_opcode = ble_ll_ctrl_rx_pause_enc_req(connsm);
+        break;
+    case BLE_LL_CTRL_PAUSE_ENC_RSP:
+        rsp_opcode = ble_ll_ctrl_rx_pause_enc_rsp(connsm);
+        if (rsp_opcode == BLE_LL_CTRL_PAUSE_ENC_RSP) {
+            restart_encryption = 1;
+        }
         break;
 #endif
     case BLE_LL_CTRL_PING_REQ:
@@ -1643,6 +1704,13 @@ ll_ctrl_send_rsp:
         }
         len = g_ble_ll_ctrl_pkt_lengths[rsp_opcode] + 1;
         ble_ll_conn_enqueue_pkt(connsm, om, BLE_LL_LLID_CTRL, len);
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+        if (restart_encryption) {
+            /* XXX: what happens if this fails? Meaning we cant allocate
+               mbuf? */
+            ble_ll_ctrl_proc_init(connsm, BLE_LL_CTRL_PROC_ENCRYPT);
+        }
+#endif
     }
     return 0;
 
@@ -1732,11 +1800,13 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm)
 #endif
         break;
     case BLE_LL_CTRL_REJECT_IND:
-#if defined (BLE_LL_CFG_FEAT_LE_ENCRYPTION)
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
         connsm->enc_data.enc_state = CONN_ENC_S_UNENCRYPTED;
 #endif
         break;
 #if defined (BLE_LL_CFG_FEAT_LE_ENCRYPTION)
+    case BLE_LL_CTRL_PAUSE_ENC_REQ:
+        /* note: fall-through intentional */
     case BLE_LL_CTRL_ENC_REQ:
         connsm->enc_data.enc_state = CONN_ENC_S_ENC_RSP_WAIT;
         break;
@@ -1745,11 +1815,15 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm)
         connsm->csmflags.cfbit.send_ltk_req = 1;
         break;
     case BLE_LL_CTRL_START_ENC_RSP:
-        /* We are encrypted */
         if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
             connsm->enc_data.enc_state = CONN_ENC_S_ENCRYPTED;
         }
         break;
+    case BLE_LL_CTRL_PAUSE_ENC_RSP:
+        if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
+            connsm->enc_data.enc_state = CONN_ENC_S_PAUSE_ENC_RSP_WAIT;
+        }
+        break;
 #endif
     default:
         break;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/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 d35d59b..ed0f1ba 100644
--- a/net/nimble/controller/src/ble_ll_hci_ev.c
+++ b/net/nimble/controller/src/ble_ll_hci_ev.c
@@ -114,23 +114,36 @@ ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm *connsm, uint8_t status)
 void
 ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status)
 {
+    uint8_t evcode;
     uint8_t *evbuf;
+    uint8_t evlen;
 
-    if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_ENCRYPT_CHG)) {
+    if (CONN_F_ENC_CHANGE_SENT(connsm) == 0) {
+        evcode = BLE_HCI_EVCODE_ENCRYPT_CHG;
+        evlen = BLE_HCI_EVENT_ENCRYPT_CHG_LEN;
+    } else {
+        evcode = BLE_HCI_EVCODE_ENC_KEY_REFRESH;
+        evlen = BLE_HCI_EVENT_ENC_KEY_REFRESH_LEN;
+    }
+
+    if (ble_ll_hci_is_event_enabled(evcode)) {
         evbuf = os_memblock_get(&g_hci_cmd_pool);
         if (evbuf) {
-            evbuf[0] = BLE_HCI_EVCODE_ENCRYPT_CHG;
-            evbuf[1] = BLE_HCI_EVENT_ENCRYPT_CHG_LEN;
+            evbuf[0] = evcode;
+            evbuf[1] = evlen;
             evbuf[2] = status;
             htole16(evbuf + 3, connsm->conn_handle);
-            if (status == BLE_ERR_SUCCESS) {
-                evbuf[5] = 0x01;
-            } else {
-                evbuf[5] = 0;
+            if (evcode == BLE_HCI_EVCODE_ENCRYPT_CHG) {
+                if (status == BLE_ERR_SUCCESS) {
+                    evbuf[5] = 0x01;
+                } else {
+                    evbuf[5] = 0;
+                }
             }
             ble_ll_hci_event_send(evbuf);
         }
     }
+    CONN_F_ENC_CHANGE_SENT(connsm) = 1;
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/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 e8fab80..c7d1222 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -78,7 +78,6 @@ int host_hci_cmd_build_le_conn_update(struct hci_conn_update *hcu,
 int host_hci_cmd_le_conn_update(struct hci_conn_update *hcu);
 void host_hci_cmd_build_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr,
                                             uint8_t *dst, int dst_len);
-int host_hci_cmd_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr);
 int host_hci_cmd_le_lt_key_req_neg_reply(uint16_t handle);
 void host_hci_cmd_build_le_conn_param_reply(struct hci_conn_param_reply *hcr,
                                             uint8_t *dst, int dst_len);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/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 d9e8af6..f8c9a43 100644
--- a/net/nimble/host/src/host_dbg.c
+++ b/net/nimble/host/src/host_dbg.c
@@ -164,7 +164,7 @@ host_hci_dbg_disconn_comp_disp(uint8_t *evdata, uint8_t len)
 }
 
 /**
- * Display an encryption change event.
+ * Display an encryption change event or encryption key refresh event
  *
  * @param evdata
  * @param len
@@ -178,6 +178,7 @@ host_hci_dbg_encrypt_chg_disp(uint8_t *evdata, uint8_t len)
 
     status = evdata[0];
     handle = le16toh(evdata + 1);
+
     /* Ignore reason if status is not success */
     if (status != BLE_ERR_SUCCESS) {
         enabled = 0;
@@ -189,6 +190,25 @@ host_hci_dbg_encrypt_chg_disp(uint8_t *evdata, uint8_t len)
 }
 
 /**
+ * Display an encryption encryption key refresh event
+ *
+ * @param evdata
+ * @param len
+ */
+static void
+host_hci_dbg_encrypt_refresh_disp(uint8_t *evdata, uint8_t len)
+{
+    uint8_t status;
+    uint16_t handle;
+
+    status = evdata[0];
+    handle = le16toh(evdata + 1);
+
+    BLE_HS_LOG(DEBUG, "Encrypt key refresh: status=%u handle=%u\n",
+               status, handle);
+}
+
+/**
  * Display a version information event
  *
  * @param evdata
@@ -403,6 +423,9 @@ host_hci_dbg_event_disp(uint8_t *evbuf)
     case BLE_HCI_EVCODE_DISCONN_CMP:
         host_hci_dbg_disconn_comp_disp(evdata, len);
         break;
+    case BLE_HCI_EVCODE_ENC_KEY_REFRESH:
+        host_hci_dbg_encrypt_refresh_disp(evdata, len);
+        break;
     case BLE_HCI_EVCODE_ENCRYPT_CHG:
         host_hci_dbg_encrypt_chg_disp(evdata, len);
         break;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/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 8a923ae..16d6536 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -809,32 +809,6 @@ host_hci_cmd_build_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr,
     host_hci_cmd_body_le_lt_key_req_reply(hkr, dst);
 }
 
-/**
- * Sends the long-term key (LTK) to the controller.
- *
- * Note: This function expects the 128-bit key to be in little-endian byte
- * order.
- *
- * OGF = 0x08 (LE)
- * OCF = 0x001a
- *
- * @param key
- * @param pt
- *
- * @return int
- */
-int
-host_hci_cmd_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr)
-{
-    uint8_t cmd[BLE_HCI_LT_KEY_REQ_REPLY_LEN];
-    int rc;
-
-    host_hci_cmd_body_le_lt_key_req_reply(hkr, cmd);
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY,
-                              sizeof cmd, cmd);
-    return rc;
-}
-
 static void
 host_hci_cmd_body_le_conn_param_reply(struct hci_conn_param_reply *hcr,
                                       uint8_t *dst)
@@ -863,18 +837,6 @@ host_hci_cmd_build_le_conn_param_reply(struct hci_conn_param_reply *hcr,
 }
 
 int
-host_hci_cmd_le_lt_key_req_neg_reply(uint16_t handle)
-{
-    uint8_t cmd[sizeof(uint16_t)];
-    int rc;
-
-    htole16(cmd, handle);
-    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY,
-                              sizeof(uint16_t), cmd);
-    return rc;
-}
-
-int
 host_hci_cmd_le_conn_param_reply(struct hci_conn_param_reply *hcr)
 {
     uint8_t cmd[BLE_HCI_CONN_PARAM_REPLY_LEN];

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/470262a2/net/nimble/include/nimble/hci_common.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h
index 50d6142..e5c3e2c 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -452,6 +452,7 @@
 
 /* Event encryption change (code=0x08) */
 #define BLE_HCI_EVENT_ENCRYPT_CHG_LEN       (4)
+#define BLE_HCI_EVENT_ENC_KEY_REFRESH_LEN   (3)
 
 /* Event command complete */
 #define BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN  (5)


[44/50] [abbrv] incubator-mynewt-core git commit: native uart; workaround the problem of console TX buffer filling up when OS is not running.

Posted by ma...@apache.org.
native uart; workaround the problem of console TX buffer filling
up when OS is not running.


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

Branch: refs/heads/master
Commit: 01879020418094a8e1e18a726a54b390084862f9
Parents: 470262a
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Tue Apr 26 10:25:43 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Tue Apr 26 10:25:43 2016 -0700

----------------------------------------------------------------------
 hw/mcu/native/src/hal_uart.c | 62 ++++++++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/01879020/hw/mcu/native/src/hal_uart.c
----------------------------------------------------------------------
diff --git a/hw/mcu/native/src/hal_uart.c b/hw/mcu/native/src/hal_uart.c
index dae24c7..c30a414 100644
--- a/hw/mcu/native/src/hal_uart.c
+++ b/hw/mcu/native/src/hal_uart.c
@@ -6,7 +6,7 @@
  * 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,
@@ -128,6 +128,37 @@ uart_log_data(struct uart *u, int istx, uint8_t data)
     }
 }
 
+static int
+uart_transmit_char(struct uart *uart)
+{
+    int sr;
+    int rc;
+    char ch;
+
+    OS_ENTER_CRITICAL(sr);
+    rc = uart->u_tx_func(uart->u_func_arg);
+    if (rc < 0) {
+        /*
+         * No more data to send.
+         */
+        uart->u_tx_run = 0;
+        if (uart->u_tx_done) {
+            uart->u_tx_done(uart->u_func_arg);
+        }
+        OS_EXIT_CRITICAL(sr);
+        return 0;
+    }
+    uart_log_data(uart, 1, ch);
+    OS_EXIT_CRITICAL(sr);
+    ch = rc;
+    rc = write(uart->u_fd, &ch, 1);
+    if (rc <= 0) {
+        /* XXX EOF/error, what now? */
+        return -1;
+    }
+    return 0;
+}
+
 static void
 uart_poller(void *arg)
 {
@@ -147,28 +178,7 @@ uart_poller(void *arg)
 
             for (bytes = 0; bytes < UART_MAX_BYTES_PER_POLL; bytes++) {
                 if (uart->u_tx_run) {
-                    OS_ENTER_CRITICAL(sr);
-                    rc = uart->u_tx_func(uart->u_func_arg);
-                    if (rc < 0) {
-                        /*
-                         * No more data to send.
-                         */
-                        uart->u_tx_run = 0;
-                        if (uart->u_tx_done) {
-                            uart->u_tx_done(uart->u_func_arg);
-                        }
-                        OS_EXIT_CRITICAL(sr);
-                        break;
-                    }
-                    uart_log_data(uart, 1, ch);
-                    OS_EXIT_CRITICAL(sr);
-                    ch = rc;
-                    rc = write(uart->u_fd, &ch, 1);
-                    if (rc <= 0) {
-                        /* XXX EOF/error, what now? */
-                        assert(0);
-                        break;
-                    }
+                    uart_transmit_char(uart);
                 }
             }
             for (bytes = 0; bytes < UART_MAX_BYTES_PER_POLL; bytes++) {
@@ -279,6 +289,12 @@ hal_uart_start_tx(int port)
     }
     OS_ENTER_CRITICAL(sr);
     uarts[port].u_tx_run = 1;
+    if (!os_started()) {
+        /*
+         * XXX this is a hack.
+         */
+        uart_transmit_char(&uarts[port]);
+    }
     OS_EXIT_CRITICAL(sr);
 }
 


[03/50] [abbrv] incubator-mynewt-core git commit: Add support for 1 megabaud for nrf UART.

Posted by ma...@apache.org.
Add support for 1 megabaud for nrf UART.


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

Branch: refs/heads/master
Commit: 27605cb1c0ed6e82bf75ccb0019c4a1e6de1e22d
Parents: a590265
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Apr 18 23:59:37 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon Apr 18 23:59:37 2016 -0700

----------------------------------------------------------------------
 hw/mcu/nordic/nrf51xxx/src/hal_uart.c | 2 ++
 hw/mcu/nordic/nrf52xxx/src/hal_uart.c | 2 ++
 2 files changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/27605cb1/hw/mcu/nordic/nrf51xxx/src/hal_uart.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_uart.c b/hw/mcu/nordic/nrf51xxx/src/hal_uart.c
index 06d2490..798c2df 100644
--- a/hw/mcu/nordic/nrf51xxx/src/hal_uart.c
+++ b/hw/mcu/nordic/nrf51xxx/src/hal_uart.c
@@ -209,6 +209,8 @@ hal_uart_baudrate(int baudrate)
         return UART_BAUDRATE_BAUDRATE_Baud460800;
     case 921600:
         return UART_BAUDRATE_BAUDRATE_Baud921600;
+    case 1000000:
+        return UART_BAUDRATE_BAUDRATE_Baud1M;
     default:
         return 0;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/27605cb1/hw/mcu/nordic/nrf52xxx/src/hal_uart.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_uart.c b/hw/mcu/nordic/nrf52xxx/src/hal_uart.c
index 5e7adac..4986100 100644
--- a/hw/mcu/nordic/nrf52xxx/src/hal_uart.c
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_uart.c
@@ -210,6 +210,8 @@ hal_uart_baudrate(int baudrate)
         return UARTE_BAUDRATE_BAUDRATE_Baud460800;
     case 921600:
         return UARTE_BAUDRATE_BAUDRATE_Baud921600;
+    case 1000000:
+        return UARTE_BAUDRATE_BAUDRATE_Baud1M;
     default:
         return 0;
     }


[34/50] [abbrv] incubator-mynewt-core git commit: MYNEWT-284: fix nrf51 radio state errors

Posted by ma...@apache.org.
MYNEWT-284: fix nrf51 radio state errors


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

Branch: refs/heads/master
Commit: 27705013e505dc6b90a7a946e7ce7f8e064ef0f4
Parents: 88356a0
Author: William San Filippo <wi...@runtime.io>
Authored: Thu Apr 21 14:46:17 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Thu Apr 21 14:46:24 2016 -0700

----------------------------------------------------------------------
 net/nimble/drivers/nrf51/src/ble_phy.c | 272 +++++++++++++---------------
 net/nimble/drivers/nrf52/src/ble_phy.c | 272 +++++++++++++---------------
 2 files changed, 249 insertions(+), 295 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/27705013/net/nimble/drivers/nrf51/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf51/src/ble_phy.c b/net/nimble/drivers/nrf51/src/ble_phy.c
index bc4a258..d95329a 100644
--- a/net/nimble/drivers/nrf51/src/ble_phy.c
+++ b/net/nimble/drivers/nrf51/src/ble_phy.c
@@ -202,6 +202,11 @@ ble_phy_rxpdu_get(void)
     return m;
 }
 
+/**
+ * Called when we want to wait if the radio is in either the rx or tx
+ * disable states. We want to wait until that state is over before doing
+ * anything to the radio
+ */
 static void
 nrf_wait_disabled(void)
 {
@@ -220,112 +225,135 @@ nrf_wait_disabled(void)
     }
 }
 
+/**
+ * Setup transceiver for receive.
+ */
 static void
-ble_phy_isr(void)
+ble_phy_rx_xcvr_setup(void)
 {
-    int rc;
-    uint8_t transition;
-    uint8_t crcok;
-    uint32_t irq_en;
-    uint32_t state;
-    uint32_t wfr_time;
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-    uint8_t *dptr;
+    if (g_ble_phy_data.phy_encrypted) {
+        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+        NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+        NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+        NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
+        NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
+        NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
+        NRF_CCM->SHORTS = 0;
+        NRF_CCM->EVENTS_ERROR = 0;
+        NRF_CCM->EVENTS_ENDCRYPT = 0;
+        NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
+    } else {
+        NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+    }
+#else
+    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
 #endif
-    struct os_mbuf *rxpdu;
-    struct ble_mbuf_hdr *ble_hdr;
 
-    /* Read irq register to determine which interrupts are enabled */
-    irq_en = NRF_RADIO->INTENCLR;
+    /* Reset the rx started flag. Used for the wait for response */
+    g_ble_phy_data.phy_rx_started = 0;
+    g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
 
-    /* Check for disabled event. This only happens for transmits now */
-    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
-        /* Better be in TX state! */
-        assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
+    /* I want to know when 1st byte received (after address) */
+    NRF_RADIO->BCC = 8; /* in bits */
+    NRF_RADIO->EVENTS_ADDRESS = 0;
+    NRF_RADIO->EVENTS_DEVMATCH = 0;
+    NRF_RADIO->EVENTS_BCMATCH = 0;
+    NRF_RADIO->EVENTS_RSSIEND = 0;
+    NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
+                        RADIO_SHORTS_READY_START_Msk |
+                        RADIO_SHORTS_DISABLED_TXEN_Msk |
+                        RADIO_SHORTS_ADDRESS_BCSTART_Msk |
+                        RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
+                        RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
 
-        ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
-                   g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
+    NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
+}
 
-        /* Clear events and clear interrupt on disabled event */
-        NRF_RADIO->EVENTS_DISABLED = 0;
-        NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk;
-        NRF_RADIO->EVENTS_END = 0;
-        state = NRF_RADIO->SHORTS;
+/**
+ * Called from interrupt context when the transmit ends
+ *
+ */
+static void
+ble_phy_tx_end_isr(void)
+{
+    uint8_t transition;
+    uint32_t wfr_time;
+
+    /* Better be in TX state! */
+    assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
+
+    /* Log the event */
+    ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
+               g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
+
+    /* Clear events and clear interrupt on disabled event */
+    NRF_RADIO->EVENTS_DISABLED = 0;
+    NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk;
+    NRF_RADIO->EVENTS_END = 0;
+    wfr_time = NRF_RADIO->SHORTS;
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-        /*
-         * XXX: not sure what to do. We had a HW error during transmission.
-         * For now I just count a stat but continue on like all is good.
-         */
-        if (g_ble_phy_data.phy_encrypted) {
-            if (NRF_CCM->EVENTS_ERROR) {
-                STATS_INC(ble_phy_stats, tx_hw_err);
-                NRF_CCM->EVENTS_ERROR = 0;
-            }
+    /*
+     * XXX: not sure what to do. We had a HW error during transmission.
+     * For now I just count a stat but continue on like all is good.
+     */
+    if (g_ble_phy_data.phy_encrypted) {
+        if (NRF_CCM->EVENTS_ERROR) {
+            STATS_INC(ble_phy_stats, tx_hw_err);
+            NRF_CCM->EVENTS_ERROR = 0;
         }
+    }
 #endif
 
-        transition = g_ble_phy_data.phy_transition;
-        if (transition == BLE_PHY_TRANSITION_TX_RX) {
-            /* Clear the rx started flag */
-            g_ble_phy_data.phy_rx_started = 0;
+    transition = g_ble_phy_data.phy_transition;
+    if (transition == BLE_PHY_TRANSITION_TX_RX) {
+        /* Packet pointer needs to be reset. */
+        if (g_ble_phy_data.rxpdu != NULL) {
+            ble_phy_rx_xcvr_setup();
+        } else {
+            /* Disable the phy */
+            STATS_INC(ble_phy_stats, no_bufs);
+            ble_phy_disable();
+        }
+
+        /*
+         * Enable the wait for response timer. Note that cc #2 on
+         * timer 0 contains the transmit end time
+         */
+        wfr_time = NRF_TIMER0->CC[2];
+        wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
+        ble_ll_wfr_enable(wfr_time);
+    } else {
+        /* Better not be going from rx to tx! */
+        assert(transition == BLE_PHY_TRANSITION_NONE);
+    }
+
+    /* Call transmit end callback */
+    if (g_ble_phy_data.txend_cb) {
+        g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
+    }
+}
 
-            /* Packet pointer needs to be reset. */
-            if (g_ble_phy_data.rxpdu != NULL) {
+static void
+ble_phy_isr(void)
+{
+    int rc;
+    uint8_t crcok;
+    uint32_t irq_en;
+    uint32_t state;
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-                if (g_ble_phy_data.phy_encrypted) {
-                    NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-                    NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-                    NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-                    NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
-                    NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
-                    NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
-                    NRF_CCM->SHORTS = 0;
-                    NRF_CCM->EVENTS_ENDCRYPT = 0;
-                    NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
-                } else {
-                    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-                }
-#else
-                NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+    uint8_t *dptr;
 #endif
+    struct os_mbuf *rxpdu;
+    struct ble_mbuf_hdr *ble_hdr;
 
-                /* I want to know when 1st byte received (after address) */
-                NRF_RADIO->BCC = 8; /* in bits */
-                NRF_RADIO->EVENTS_ADDRESS = 0;
-                NRF_RADIO->EVENTS_DEVMATCH = 0;
-                NRF_RADIO->EVENTS_BCMATCH = 0;
-                NRF_RADIO->EVENTS_RSSIEND = 0;
-                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
-                                    RADIO_SHORTS_READY_START_Msk |
-                                    RADIO_SHORTS_ADDRESS_BCSTART_Msk |
-                                    RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
-                                    RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
-
-                NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
-                g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
-            } else {
-                /* Disable the phy */
-                STATS_INC(ble_phy_stats, no_bufs);
-                ble_phy_disable();
-            }
-
-            /*
-             * Enable the wait for response timer. Note that cc #2 on
-             * timer 0 contains the transmit end time
-             */
-            wfr_time = NRF_TIMER0->CC[2];
-            wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
-            ble_ll_wfr_enable(wfr_time);
-        } else {
-            /* Better not be going from rx to tx! */
-            assert(transition == BLE_PHY_TRANSITION_NONE);
-        }
+    /* Read irq register to determine which interrupts are enabled */
+    irq_en = NRF_RADIO->INTENCLR;
 
-        /* Call transmit end callback */
-        if (g_ble_phy_data.txend_cb) {
-            g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
-        }
+    /* Check for disabled event. This only happens for transmits now */
+    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
+        ble_phy_tx_end_isr();
     }
 
     /* We get this if we have started to receive a frame */
@@ -363,18 +391,8 @@ ble_phy_isr(void)
         /* Call Link Layer receive start function */
         rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
         if (rc >= 0) {
+            /* Set rx started flag and enable rx end ISR */
             g_ble_phy_data.phy_rx_started = 1;
-            if (rc > 0) {
-                /* We need to go from disabled to TXEN */
-                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
-                                    RADIO_SHORTS_READY_START_Msk |
-                                    RADIO_SHORTS_DISABLED_TXEN_Msk;
-            } else {
-                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
-                                    RADIO_SHORTS_READY_START_Msk;
-            }
-
-            /* Set rx end ISR enable */
             NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
         } else {
             /* Disable PHY */
@@ -457,7 +475,6 @@ ble_phy_isr(void)
 #endif
         rc = ble_ll_rx_end(rxpdu, ble_hdr);
         if (rc < 0) {
-            /* Disable the PHY. */
             ble_phy_disable();
         }
     }
@@ -563,6 +580,11 @@ ble_phy_init(void)
     return 0;
 }
 
+/**
+ * Puts the phy into receive mode.
+ *
+ * @return int 0: success; BLE Phy error code otherwise
+ */
 int
 ble_phy_rx(void)
 {
@@ -579,64 +601,19 @@ ble_phy_rx(void)
         return BLE_PHY_ERR_NO_BUFS;
     }
 
-    /* Set packet pointer */
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-    if (g_ble_phy_data.phy_encrypted) {
-        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-    } else {
-        NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-    }
-#else
-    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-#endif
-
     /* Make sure all interrupts are disabled */
     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
 
     /* Clear events prior to enabling receive */
     NRF_RADIO->EVENTS_END = 0;
-    NRF_RADIO->EVENTS_ADDRESS = 0;
     NRF_RADIO->EVENTS_DISABLED = 0;
-    NRF_RADIO->EVENTS_BCMATCH = 0;
-    NRF_RADIO->EVENTS_RSSIEND = 0;
-    NRF_RADIO->EVENTS_DEVMATCH = 0;
-
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-    if (g_ble_phy_data.phy_encrypted) {
-        NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-        NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-        NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
-        NRF_CCM->EVENTS_ERROR = 0;
-        NRF_CCM->EVENTS_ENDCRYPT = 0;
-        NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
-        /* XXX: can I just set this once? (i.e per connection)? In other
-           words, only do this during encrypt enable? */
-        NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
-        NRF_CCM->SHORTS = 0;
-        NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
-    }
-#endif
 
-    /* XXX: could it be that I am late turning on the device? That I need
-       to automatically go from rx to tx always? I dont here */
-    /* I want to know when 1st byte received (after address) */
-    NRF_RADIO->BCC = 8; /* in bits */
-    NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
-                        RADIO_SHORTS_READY_START_Msk |
-                        RADIO_SHORTS_ADDRESS_BCSTART_Msk |
-                        RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
-                        RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
-
-    NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
-
-    /* Reset the rx started flag. Used for the wait for response */
-    g_ble_phy_data.phy_rx_started = 0;
+    /* Setup for rx */
+    ble_phy_rx_xcvr_setup();
 
     /* Start the receive task in the radio */
     NRF_RADIO->TASKS_RXEN = 1;
 
-    g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
-
     return 0;
 }
 
@@ -998,4 +975,3 @@ ble_phy_rx_started(void)
 {
     return g_ble_phy_data.phy_rx_started;
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/27705013/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 fee6043..cecbe60 100644
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@ -196,6 +196,11 @@ ble_phy_rxpdu_get(void)
     return m;
 }
 
+/**
+ * Called when we want to wait if the radio is in either the rx or tx
+ * disable states. We want to wait until that state is over before doing
+ * anything to the radio
+ */
 static void
 nrf_wait_disabled(void)
 {
@@ -214,110 +219,134 @@ nrf_wait_disabled(void)
     }
 }
 
+/**
+ * Setup transceiver for receive
+ *
+ */
 static void
-ble_phy_isr(void)
+ble_phy_rx_xcvr_setup(void)
+{
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    if (g_ble_phy_data.phy_encrypted) {
+        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+        NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
+        NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+        NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
+        NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption;
+        NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
+        NRF_CCM->SHORTS = 0;
+        NRF_CCM->EVENTS_ERROR = 0;
+        NRF_CCM->EVENTS_ENDCRYPT = 0;
+        NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
+    } else {
+        NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+    }
+#else
+    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+#endif
+
+    /* Reset the rx started flag. Used for the wait for response */
+    g_ble_phy_data.phy_rx_started = 0;
+    g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
+
+    /* I want to know when 1st byte received (after address) */
+    NRF_RADIO->BCC = 8; /* in bits */
+    NRF_RADIO->EVENTS_ADDRESS = 0;
+    NRF_RADIO->EVENTS_DEVMATCH = 0;
+    NRF_RADIO->EVENTS_BCMATCH = 0;
+    NRF_RADIO->EVENTS_RSSIEND = 0;
+    NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
+                        RADIO_SHORTS_READY_START_Msk |
+                        RADIO_SHORTS_DISABLED_TXEN_Msk |
+                        RADIO_SHORTS_ADDRESS_BCSTART_Msk |
+                        RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
+                        RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
+
+    NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
+}
+
+/**
+ * Called from interrupt context when the transmit ends
+ *
+ */
+static void
+ble_phy_tx_end_isr(void)
 {
-    int rc;
     uint8_t transition;
-    uint8_t crcok;
-    uint32_t irq_en;
-    uint32_t state;
     uint32_t wfr_time;
-    uint8_t *dptr;
-    struct os_mbuf *rxpdu;
-    struct ble_mbuf_hdr *ble_hdr;
-
-    /* Read irq register to determine which interrupts are enabled */
-    irq_en = NRF_RADIO->INTENCLR;
 
-    /* Check for disabled event. This only happens for transmits now */
-    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
-        /* Better be in TX state! */
-        assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
+    /* Better be in TX state! */
+    assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
 
-        ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
-                   g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
+    /* Log the event */
+    ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
+               g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
 
-        /* Clear events and clear interrupt on disabled event */
-        NRF_RADIO->EVENTS_DISABLED = 0;
-        NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk;
-        NRF_RADIO->EVENTS_END = 0;
-        state = NRF_RADIO->SHORTS;
+    /* Clear events and clear interrupt on disabled event */
+    NRF_RADIO->EVENTS_DISABLED = 0;
+    NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk;
+    NRF_RADIO->EVENTS_END = 0;
+    wfr_time = NRF_RADIO->SHORTS;
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-        /*
-         * XXX: not sure what to do. We had a HW error during transmission.
-         * For now I just count a stat but continue on like all is good.
-         */
-        if (g_ble_phy_data.phy_encrypted) {
-            if (NRF_CCM->EVENTS_ERROR) {
-                STATS_INC(ble_phy_stats, tx_hw_err);
-                NRF_CCM->EVENTS_ERROR = 0;
-            }
+    /*
+     * XXX: not sure what to do. We had a HW error during transmission.
+     * For now I just count a stat but continue on like all is good.
+     */
+    if (g_ble_phy_data.phy_encrypted) {
+        if (NRF_CCM->EVENTS_ERROR) {
+            STATS_INC(ble_phy_stats, tx_hw_err);
+            NRF_CCM->EVENTS_ERROR = 0;
         }
+    }
 #endif
 
-        transition = g_ble_phy_data.phy_transition;
-        if (transition == BLE_PHY_TRANSITION_TX_RX) {
-            /* Clear the rx started flag */
-            g_ble_phy_data.phy_rx_started = 0;
+    transition = g_ble_phy_data.phy_transition;
+    if (transition == BLE_PHY_TRANSITION_TX_RX) {
+        /* Packet pointer needs to be reset. */
+        if (g_ble_phy_data.rxpdu != NULL) {
+            ble_phy_rx_xcvr_setup();
+        } else {
+            /* Disable the phy */
+            STATS_INC(ble_phy_stats, no_bufs);
+            ble_phy_disable();
+        }
 
-            /* Packet pointer needs to be reset. */
-            if (g_ble_phy_data.rxpdu != NULL) {
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-                if (g_ble_phy_data.phy_encrypted) {
-                    NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-                    NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-                    NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-                    NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
-                    NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption;
-                    NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
-                    NRF_CCM->SHORTS = 0;
-                    NRF_CCM->EVENTS_ENDCRYPT = 0;
-                    NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
-                } else {
-                    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-                }
-#else
-                NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-#endif
+        /*
+         * Enable the wait for response timer. Note that cc #2 on
+         * timer 0 contains the transmit end time
+         */
+        wfr_time = NRF_TIMER0->CC[2];
+        wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
+        ble_ll_wfr_enable(wfr_time);
+    } else {
+        /* Better not be going from rx to tx! */
+        assert(transition == BLE_PHY_TRANSITION_NONE);
+    }
 
-                /* I want to know when 1st byte received (after address) */
-                NRF_RADIO->BCC = 8; /* in bits */
-                NRF_RADIO->EVENTS_ADDRESS = 0;
-                NRF_RADIO->EVENTS_DEVMATCH = 0;
-                NRF_RADIO->EVENTS_BCMATCH = 0;
-                NRF_RADIO->EVENTS_RSSIEND = 0;
-                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
-                                    RADIO_SHORTS_READY_START_Msk |
-                                    RADIO_SHORTS_ADDRESS_BCSTART_Msk |
-                                    RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
-                                    RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
-
-                NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
-                g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
-            } else {
-                /* Disable the phy */
-                STATS_INC(ble_phy_stats, no_bufs);
-                ble_phy_disable();
-            }
+    /* Call transmit end callback */
+    if (g_ble_phy_data.txend_cb) {
+        g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
+    }
+}
 
-            /*
-             * Enable the wait for response timer. Note that cc #2 on
-             * timer 0 contains the transmit end time
-             */
-            wfr_time = NRF_TIMER0->CC[2];
-            wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
-            ble_ll_wfr_enable(wfr_time);
-        } else {
-            /* Better not be going from rx to tx! */
-            assert(transition == BLE_PHY_TRANSITION_NONE);
-        }
+static void
+ble_phy_isr(void)
+{
+    int rc;
+    uint8_t crcok;
+    uint32_t irq_en;
+    uint32_t state;
+    uint8_t *dptr;
+    struct os_mbuf *rxpdu;
+    struct ble_mbuf_hdr *ble_hdr;
 
-        /* Call transmit end callback */
-        if (g_ble_phy_data.txend_cb) {
-            g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
-        }
+    /* Read irq register to determine which interrupts are enabled */
+    irq_en = NRF_RADIO->INTENCLR;
+
+    /* Check for disabled event. This only happens for transmits now */
+    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
+        ble_phy_tx_end_isr();
     }
 
     /* We get this if we have started to receive a frame */
@@ -355,18 +384,8 @@ ble_phy_isr(void)
         /* Call Link Layer receive start function */
         rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
         if (rc >= 0) {
+            /* Set rx started flag and enable rx end ISR */
             g_ble_phy_data.phy_rx_started = 1;
-            if (rc > 0) {
-                /* We need to go from disabled to TXEN */
-                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
-                                    RADIO_SHORTS_READY_START_Msk |
-                                    RADIO_SHORTS_DISABLED_TXEN_Msk;
-            } else {
-                NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
-                                    RADIO_SHORTS_READY_START_Msk;
-            }
-
-            /* Set rx end ISR enable */
             NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
         } else {
             /* Disable PHY */
@@ -553,6 +572,11 @@ ble_phy_init(void)
     return 0;
 }
 
+/**
+ * Puts the phy into receive mode.
+ *
+ * @return int 0: success; BLE Phy error code otherwise
+ */
 int
 ble_phy_rx(void)
 {
@@ -569,64 +593,19 @@ ble_phy_rx(void)
         return BLE_PHY_ERR_NO_BUFS;
     }
 
-    /* Set packet pointer */
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-    if (g_ble_phy_data.phy_encrypted) {
-        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-    } else {
-        NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-    }
-#else
-    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-#endif
-
     /* Make sure all interrupts are disabled */
     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
 
     /* Clear events prior to enabling receive */
     NRF_RADIO->EVENTS_END = 0;
-    NRF_RADIO->EVENTS_ADDRESS = 0;
     NRF_RADIO->EVENTS_DISABLED = 0;
-    NRF_RADIO->EVENTS_BCMATCH = 0;
-    NRF_RADIO->EVENTS_RSSIEND = 0;
-    NRF_RADIO->EVENTS_DEVMATCH = 0;
-
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-    if (g_ble_phy_data.phy_encrypted) {
-        NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-        NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
-        NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
-        NRF_CCM->EVENTS_ERROR = 0;
-        NRF_CCM->EVENTS_ENDCRYPT = 0;
-        NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption;
-        /* XXX: can I just set this once? (i.e per connection)? In other
-           words, only do this during encrypt enable? */
-        NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
-        NRF_CCM->SHORTS = 0;
-        NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
-    }
-#endif
 
-    /* XXX: could it be that I am late turning on the device? That I need
-       to automatically go from rx to tx always? I dont here */
-    /* I want to know when 1st byte received (after address) */
-    NRF_RADIO->BCC = 8; /* in bits */
-    NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk |
-                        RADIO_SHORTS_READY_START_Msk |
-                        RADIO_SHORTS_ADDRESS_BCSTART_Msk |
-                        RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
-                        RADIO_SHORTS_DISABLED_RSSISTOP_Msk;
-
-    NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk;
-
-    /* Reset the rx started flag. Used for the wait for response */
-    g_ble_phy_data.phy_rx_started = 0;
+    /* Setup for rx */
+    ble_phy_rx_xcvr_setup();
 
     /* Start the receive task in the radio */
     NRF_RADIO->TASKS_RXEN = 1;
 
-    g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
-
     return 0;
 }
 
@@ -980,4 +959,3 @@ ble_phy_rx_started(void)
 {
     return g_ble_phy_data.phy_rx_started;
 }
-


[27/50] [abbrv] incubator-mynewt-core git commit: ble ll - don't undef feature macros.

Posted by ma...@apache.org.
ble ll - don't undef feature macros.


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

Branch: refs/heads/master
Commit: e4669ed649daac57a130b58fc555fa2592b0fbb5
Parents: 61458e3
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 20 15:26:16 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 20 16:11:48 2016 -0700

----------------------------------------------------------------------
 net/nimble/controller/include/controller/ble_ll.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e4669ed6/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 af16f9a..60a8408 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -24,14 +24,14 @@
 #include "hal/hal_cputime.h"
 
 /* Configuration for supported features */
-#undef  BLE_LL_CFG_FEAT_LE_ENCRYPTION
-#undef  BLE_LL_CFG_FEAT_CONN_PARAM_REQ
-#undef  BLE_LL_CFG_FEAT_EXT_REJECT_IND
+//#define  BLE_LL_CFG_FEAT_LE_ENCRYPTION
+//#define  BLE_LL_CFG_FEAT_CONN_PARAM_REQ
+//#define  BLE_LL_CFG_FEAT_EXT_REJECT_IND
 #define BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG
-#undef  BLE_LL_CFG_FEAT_LE_PING
+//#define  BLE_LL_CFG_FEAT_LE_PING
 #define  BLE_LL_CFG_FEAT_DATA_LEN_EXT
-#undef  BLE_LL_CFG_FEAT_LL_PRIVACY
-#undef  BLE_LL_CFG_FEAT_EXT_SCAN_FILT
+//#define  BLE_LL_CFG_FEAT_LL_PRIVACY
+//#define  BLE_LL_CFG_FEAT_EXT_SCAN_FILT
 
 /* Controller revision. */
 #define BLE_LL_SUB_VERS_NR      (0x0000)


[20/50] [abbrv] incubator-mynewt-core git commit: Add bootloader support for bmd300eval bsp

Posted by ma...@apache.org.
Add bootloader support for bmd300eval bsp


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

Branch: refs/heads/master
Commit: 9abd8ceebc0d973e573625438a560c03758b4c91
Parents: 598b910
Author: William San Filippo <wi...@runtime.io>
Authored: Tue Apr 19 20:42:34 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Tue Apr 19 20:58:59 2016 -0700

----------------------------------------------------------------------
 hw/bsp/bmd300eval/bmd300eval.ld          |  13 +-
 hw/bsp/bmd300eval/bmd300eval_download.sh |  52 +++++--
 hw/bsp/bmd300eval/bmd300eval_no_boot.ld  | 195 ++++++++++++++++++++++++++
 hw/bsp/bmd300eval/boot-bmd300eval.ld     | 195 ++++++++++++++++++++++++++
 hw/bsp/bmd300eval/src/os_bsp.c           |  10 +-
 5 files changed, 441 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9abd8cee/hw/bsp/bmd300eval/bmd300eval.ld
----------------------------------------------------------------------
diff --git a/hw/bsp/bmd300eval/bmd300eval.ld b/hw/bsp/bmd300eval/bmd300eval.ld
index f227c39..c019b63 100755
--- a/hw/bsp/bmd300eval/bmd300eval.ld
+++ b/hw/bsp/bmd300eval/bmd300eval.ld
@@ -19,7 +19,7 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
 
 MEMORY
 {
-  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000
+  FLASH (rx) : ORIGIN = 0x00008000, LENGTH = 0x3a000
   RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
 }
 
@@ -27,7 +27,7 @@ MEMORY
  * with other linker script that defines memory regions FLASH and RAM.
  * It references following symbols, which must be defined in code:
  *   Reset_Handler : Entry of reset handler
- * 
+ *
  * It defines following symbols, which code can use without definition:
  *   __exidx_start
  *   __exidx_end
@@ -54,6 +54,11 @@ ENTRY(Reset_Handler)
 
 SECTIONS
 {
+    .imghdr (NOLOAD):
+    {
+        . = . + 0x20;
+    } > FLASH
+
     .text :
     {
         __isr_vector_start = .;
@@ -85,7 +90,7 @@ SECTIONS
     } > FLASH
 
 
-    .ARM.extab : 
+    .ARM.extab :
     {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
         . = ALIGN(4);
@@ -108,7 +113,7 @@ SECTIONS
         . = . + (__isr_vector_end - __isr_vector_start);
         . = ALIGN(4);
     } > RAM
-            
+
     .data : AT (__etext)
     {
         __data_start__ = .;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9abd8cee/hw/bsp/bmd300eval/bmd300eval_download.sh
----------------------------------------------------------------------
diff --git a/hw/bsp/bmd300eval/bmd300eval_download.sh b/hw/bsp/bmd300eval/bmd300eval_download.sh
index c0259c1..028a5aa 100755
--- a/hw/bsp/bmd300eval/bmd300eval_download.sh
+++ b/hw/bsp/bmd300eval/bmd300eval_download.sh
@@ -6,46 +6,70 @@
 # 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.
-#
+
 # Called: $0 <bsp_directory_path> <binary> [features...]
 #  - bsp_directory_path is absolute path to hw/bsp/bsp_name
 #  - binary is the path to prefix to target binary, .elf.bin appended to this
 #    name is the raw binary format of the binary.
 #  - features are the target features. So you can have e.g. different
 #    flash offset for bootloader 'feature'
-# 
 #
+#
+
 if [ $# -lt 2 ]; then
     echo "Need binary to download"
     exit 1
 fi
 
-FLASH_OFFSET=0x0
-FILE_NAME=$2.elf.bin
-JLINK_SCRIPT=.download.jlink
+IS_BOOTLOADER=0
+BASENAME=$2
+GDB_CMD_FILE=.gdb_cmds
+
+# Look for 'bootloader' from 3rd arg onwards
+shift
+shift
+while [ $# -gt 0 ]; do
+    if [ $1 = "bootloader" ]; then
+        IS_BOOTLOADER=1
+    fi
+    shift
+done
+
+if [ $IS_BOOTLOADER -eq 1 ]; then
+    FLASH_OFFSET=0x0
+    FILE_NAME=$BASENAME.elf.bin
+else
+    FLASH_OFFSET=0x8000
+    FILE_NAME=$BASENAME.img
+fi
 
 echo "Downloading" $FILE_NAME "to" $FLASH_OFFSET
 
-cat > $JLINK_SCRIPT <<EOF
-w 4001e504 1
-loadbin $FILE_NAME $FLASH_OFFSET
-q
-EOF
+# XXX for some reason JLinkExe overwrites flash at offset 0 when
+# downloading somewhere in the flash. So need to figure out how to tell it
+# not to do that, or report failure if gdb fails to write this file
+#
+echo "shell /bin/sh -c 'trap \"\" 2;JLinkGDBServer -device nRF52 -speed 4000 -if SWD -port 3333 -singlerun' & " > $GDB_CMD_FILE
+echo "target remote localhost:3333" >> $GDB_CMD_FILE
+echo "restore $FILE_NAME binary $FLASH_OFFSET" >> $GDB_CMD_FILE
+echo "quit" >> $GDB_CMD_FILE
+
+msgs=`arm-none-eabi-gdb -x $GDB_CMD_FILE 2>&1`
+echo $msgs > .gdb_out
 
-msgs=`JLinkExe -device nRF52 -speed 4000 -if SWD $JLINK_SCRIPT 2>&1`
+rm $GDB_CMD_FILE
 
 # Echo output from script run, so newt can show it if things go wrong.
 echo $msgs
-rm $JLINK_SCRIPT
 
 error=`echo $msgs | grep error`
 if [ -n "$error" ]; then

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9abd8cee/hw/bsp/bmd300eval/bmd300eval_no_boot.ld
----------------------------------------------------------------------
diff --git a/hw/bsp/bmd300eval/bmd300eval_no_boot.ld b/hw/bsp/bmd300eval/bmd300eval_no_boot.ld
new file mode 100755
index 0000000..cd8d570
--- /dev/null
+++ b/hw/bsp/bmd300eval/bmd300eval_no_boot.ld
@@ -0,0 +1,195 @@
+/* Linker script for Nordic Semiconductor nRF5 devices
+ *
+ * Version: Sourcery G++ 4.5-1
+ * Support: https://support.codesourcery.com/GNUToolchain/
+ *
+ * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions.  No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000
+  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __bssnz_start__
+ *   __bssnz_end__
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+    .text :
+    {
+        __isr_vector_start = .;
+        KEEP(*(.isr_vector))
+        __isr_vector_end = .;
+        *(.text*)
+
+        KEEP(*(.init))
+        KEEP(*(.fini))
+
+        /* .ctors */
+        *crtbegin.o(.ctors)
+        *crtbegin?.o(.ctors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+        *(SORT(.ctors.*))
+        *(.ctors)
+
+        /* .dtors */
+        *crtbegin.o(.dtors)
+        *crtbegin?.o(.dtors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+        *(SORT(.dtors.*))
+        *(.dtors)
+
+        *(.rodata*)
+
+        *(.eh_frame*)
+        . = ALIGN(4);
+    } > FLASH
+
+
+    .ARM.extab :
+    {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+        . = ALIGN(4);
+    } > FLASH
+
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+        . = ALIGN(4);
+    } > FLASH
+    __exidx_end = .;
+
+    __etext = .;
+
+    .vector_relocation :
+    {
+        . = ALIGN(4);
+        __vector_tbl_reloc__ = .;
+        . = . + (__isr_vector_end - __isr_vector_start);
+        . = ALIGN(4);
+    } > RAM
+
+    .data : AT (__etext)
+    {
+        __data_start__ = .;
+        *(vtable)
+        *(.data*)
+
+        . = ALIGN(4);
+        /* preinit data */
+        PROVIDE_HIDDEN (__preinit_array_start = .);
+        *(.preinit_array)
+        PROVIDE_HIDDEN (__preinit_array_end = .);
+
+        . = ALIGN(4);
+        /* init data */
+        PROVIDE_HIDDEN (__init_array_start = .);
+        *(SORT(.init_array.*))
+        *(.init_array)
+        PROVIDE_HIDDEN (__init_array_end = .);
+
+
+        . = ALIGN(4);
+        /* finit data */
+        PROVIDE_HIDDEN (__fini_array_start = .);
+        *(SORT(.fini_array.*))
+        *(.fini_array)
+        PROVIDE_HIDDEN (__fini_array_end = .);
+
+        *(.jcr)
+        . = ALIGN(4);
+        /* All data end */
+        __data_end__ = .;
+    } > RAM
+
+    /* Non-zeroed BSS.  This section is similar to BSS, with the following two
+     * caveats:
+     *    1. It does not get zeroed at init-time.
+     *    2. You cannot use it as source memory for EasyDMA.
+     *
+     * This section exists because of a hardware defect; see errata 33 and 34
+     * in STM32F40x errata sheet.
+     */
+    .bssnz :
+    {
+        . = ALIGN(4);
+        __bssnz_start__ = .;
+        *(.bss.core.nz*)
+        . = ALIGN(4);
+        __bssnz_end__ = .;
+    } > RAM
+
+    .bss :
+    {
+        . = ALIGN(4);
+        __bss_start__ = .;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(4);
+        __bss_end__ = .;
+    } > RAM
+
+    /* Heap starts after BSS */
+    __HeapBase = .;
+
+    /* .stack_dummy section doesn't contains any symbols. It is only
+     * used for linker to calculate size of stack sections, and assign
+     * values to stack symbols later */
+    .stack_dummy (COPY):
+    {
+        *(.stack*)
+    } > RAM
+
+    /* Set stack top to end of RAM, and stack limit move down by
+     * size of stack_dummy section */
+    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+    PROVIDE(__stack = __StackTop);
+
+    /* Top of head is the bottom of the stack */
+    __HeapLimit = __StackLimit;
+
+    /* Check if data + heap + stack exceeds RAM limit */
+    ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack")
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9abd8cee/hw/bsp/bmd300eval/boot-bmd300eval.ld
----------------------------------------------------------------------
diff --git a/hw/bsp/bmd300eval/boot-bmd300eval.ld b/hw/bsp/bmd300eval/boot-bmd300eval.ld
new file mode 100755
index 0000000..1ed2c14
--- /dev/null
+++ b/hw/bsp/bmd300eval/boot-bmd300eval.ld
@@ -0,0 +1,195 @@
+/* Linker script for Nordic Semiconductor nRF5 devices
+ *
+ * Version: Sourcery G++ 4.5-1
+ * Support: https://support.codesourcery.com/GNUToolchain/
+ *
+ * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions.  No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x8000
+  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __bssnz_start__
+ *   __bssnz_end__
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+    .text :
+    {
+        __isr_vector_start = .;
+        KEEP(*(.isr_vector))
+        __isr_vector_end = .;
+        *(.text*)
+
+        KEEP(*(.init))
+        KEEP(*(.fini))
+
+        /* .ctors */
+        *crtbegin.o(.ctors)
+        *crtbegin?.o(.ctors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+        *(SORT(.ctors.*))
+        *(.ctors)
+
+        /* .dtors */
+        *crtbegin.o(.dtors)
+        *crtbegin?.o(.dtors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+        *(SORT(.dtors.*))
+        *(.dtors)
+
+        *(.rodata*)
+
+        *(.eh_frame*)
+        . = ALIGN(4);
+    } > FLASH
+
+
+    .ARM.extab :
+    {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+        . = ALIGN(4);
+    } > FLASH
+
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+        . = ALIGN(4);
+    } > FLASH
+    __exidx_end = .;
+
+    __etext = .;
+
+    .vector_relocation :
+    {
+        . = ALIGN(4);
+        __vector_tbl_reloc__ = .;
+        . = . + (__isr_vector_end - __isr_vector_start);
+        . = ALIGN(4);
+    } > RAM
+
+    .data : AT (__etext)
+    {
+        __data_start__ = .;
+        *(vtable)
+        *(.data*)
+
+        . = ALIGN(4);
+        /* preinit data */
+        PROVIDE_HIDDEN (__preinit_array_start = .);
+        *(.preinit_array)
+        PROVIDE_HIDDEN (__preinit_array_end = .);
+
+        . = ALIGN(4);
+        /* init data */
+        PROVIDE_HIDDEN (__init_array_start = .);
+        *(SORT(.init_array.*))
+        *(.init_array)
+        PROVIDE_HIDDEN (__init_array_end = .);
+
+
+        . = ALIGN(4);
+        /* finit data */
+        PROVIDE_HIDDEN (__fini_array_start = .);
+        *(SORT(.fini_array.*))
+        *(.fini_array)
+        PROVIDE_HIDDEN (__fini_array_end = .);
+
+        *(.jcr)
+        . = ALIGN(4);
+        /* All data end */
+        __data_end__ = .;
+    } > RAM
+
+    /* Non-zeroed BSS.  This section is similar to BSS, with the following two
+     * caveats:
+     *    1. It does not get zeroed at init-time.
+     *    2. You cannot use it as source memory for EasyDMA.
+     *
+     * This section exists because of a hardware defect; see errata 33 and 34
+     * in STM32F40x errata sheet.
+     */
+    .bssnz :
+    {
+        . = ALIGN(4);
+        __bssnz_start__ = .;
+        *(.bss.core.nz*)
+        . = ALIGN(4);
+        __bssnz_end__ = .;
+    } > RAM
+
+    .bss :
+    {
+        . = ALIGN(4);
+        __bss_start__ = .;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(4);
+        __bss_end__ = .;
+    } > RAM
+
+    /* Heap starts after BSS */
+    __HeapBase = .;
+
+    /* .stack_dummy section doesn't contains any symbols. It is only
+     * used for linker to calculate size of stack sections, and assign
+     * values to stack symbols later */
+    .stack_dummy (COPY):
+    {
+        *(.stack*)
+    } > RAM
+
+    /* Set stack top to end of RAM, and stack limit move down by
+     * size of stack_dummy section */
+    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+    PROVIDE(__stack = __StackTop);
+
+    /* Top of head is the bottom of the stack */
+    __HeapLimit = __StackLimit;
+
+    /* Check if data + heap + stack exceeds RAM limit */
+    ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack")
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9abd8cee/hw/bsp/bmd300eval/src/os_bsp.c
----------------------------------------------------------------------
diff --git a/hw/bsp/bmd300eval/src/os_bsp.c b/hw/bsp/bmd300eval/src/os_bsp.c
index 92bd69c..c05b208 100644
--- a/hw/bsp/bmd300eval/src/os_bsp.c
+++ b/hw/bsp/bmd300eval/src/os_bsp.c
@@ -6,7 +6,7 @@
  * 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,
@@ -19,17 +19,15 @@
 #include <hal/flash_map.h>
 
 static struct flash_area bsp_flash_areas[] = {
-#if 0
     [FLASH_AREA_BOOTLOADER] = {
         .fa_flash_id = 0,       /* internal flash */
-        .fa_off = 0x08000000,   /* beginning */
+        .fa_off = 0x00000000,   /* beginning */
         .fa_size = (32 * 1024)
     },
-#endif
-    /* 2 * 16K and 1*64K sectors here */
+    /* 2*16K and 1*64K sectors here */
     [FLASH_AREA_IMAGE_0] = {
         .fa_flash_id = 0,
-        .fa_off = 0x00000000,
+        .fa_off = 0x00008000,
         .fa_size = (232 * 1024)
     },
     [FLASH_AREA_IMAGE_1] = {


[33/50] [abbrv] incubator-mynewt-core git commit: console; instead of poking libs/os var g_os_started, use the provided API call.

Posted by ma...@apache.org.
console; instead of poking libs/os var g_os_started, use the provided API call.


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

Branch: refs/heads/master
Commit: 88356a0df1811e5905588116f6c7cab62764e6ad
Parents: 75d3220
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Thu Apr 21 12:58:16 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Thu Apr 21 12:58:16 2016 -0700

----------------------------------------------------------------------
 libs/console/full/src/cons_tty.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/88356a0d/libs/console/full/src/cons_tty.c
----------------------------------------------------------------------
diff --git a/libs/console/full/src/cons_tty.c b/libs/console/full/src/cons_tty.c
index b7320be..e7057a1 100644
--- a/libs/console/full/src/cons_tty.c
+++ b/libs/console/full/src/cons_tty.c
@@ -102,7 +102,7 @@ console_queue_char(char ch)
         /* TX needs to drain */
         hal_uart_start_tx(CONSOLE_UART);
         OS_EXIT_CRITICAL(sr);
-	if (g_os_started) {
+	if (os_started()) {
             os_time_delay(1);
 	}
         OS_ENTER_CRITICAL(sr);


[35/50] [abbrv] incubator-mynewt-core git commit: CM0 fault handler; print newline at the end of last line of output.

Posted by ma...@apache.org.
CM0 fault handler; print newline at the end of last line of output.


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

Branch: refs/heads/master
Commit: f0556b1887ab8e1797f4ef4ee56d0c631b69e6da
Parents: 2770501
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Thu Apr 21 15:25:17 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Thu Apr 21 15:37:16 2016 -0700

----------------------------------------------------------------------
 libs/os/src/arch/cortex_m0/os_fault.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f0556b18/libs/os/src/arch/cortex_m0/os_fault.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/cortex_m0/os_fault.c b/libs/os/src/arch/cortex_m0/os_fault.c
index 4c67f6c..c46f8a8 100644
--- a/libs/os/src/arch/cortex_m0/os_fault.c
+++ b/libs/os/src/arch/cortex_m0/os_fault.c
@@ -81,7 +81,7 @@ os_default_irq(struct trap_frame *tf)
       tf->r8, tf->r9, tf->r10, tf->r11);
     console_printf("r12:0x%08lx  lr:0x%08lx  pc:0x%08lx psr:0x%08lx\n",
       tf->ef->r12, tf->ef->lr, tf->ef->pc, tf->ef->psr);
-    console_printf("ICSR:0x%08lx ",SCB->ICSR);
+    console_printf("ICSR:0x%08lx\n", SCB->ICSR);
     system_reset();
 }
 


[12/50] [abbrv] incubator-mynewt-core git commit: ble host - major changes.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 f4cac43..7e87661 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -27,32 +27,12 @@
 #include "ble_hs_priv.h"
 
 #define BLE_GAP_OP_NULL                                 0
-#define BLE_GAP_STATE_NULL                              255
 
 #define BLE_GAP_OP_M_DISC                               1
 #define BLE_GAP_OP_M_CONN                               2
 
 #define BLE_GAP_OP_S_ADV                                1
 
-/** Discovery master states. */
-#define BLE_GAP_STATE_M_DISC_PENDING                    0
-#define BLE_GAP_STATE_M_DISC_ACTIVE                     1
-#define BLE_GAP_STATE_M_DISC_DISABLE                    2
-
-/** Connect master states. */
-#define BLE_GAP_STATE_M_CONN_PENDING                    0
-#define BLE_GAP_STATE_M_CONN_ACTIVE                     1
-
-/** Advertise slave states. */
-#define BLE_GAP_STATE_S_ADV_PENDING                     0
-#define BLE_GAP_STATE_S_ADV_ACTIVE                      1
-
-/** Connection update states. */
-#define BLE_GAP_STATE_U_UPDATE                          0
-#define BLE_GAP_STATE_U_REPLY                           1
-#define BLE_GAP_STATE_U_REPLY_ACKED                     2
-#define BLE_GAP_STATE_U_NEG_REPLY                       3
-
 /**
  * The maximum amount of user data that can be put into the advertising data.
  * The stack may automatically insert some fields on its own, limiting the
@@ -92,24 +72,20 @@ static const struct hci_adv_params ble_gap_adv_params_dflt = {
  */
 static bssnz_t struct {
     uint8_t op;
-    uint8_t state;
 
     unsigned exp_set:1;
     uint32_t exp_os_ticks;
 
     union {
         struct {
-            uint8_t addr_type;
-            uint8_t addr[6];
-            struct ble_gap_crt_params params;
             ble_gap_conn_fn *cb;
             void *cb_arg;
+
+            unsigned using_wl:1;
         } conn;
 
         struct {
             uint8_t disc_mode;
-            uint8_t filter_policy;
-            uint8_t scan_type;
             ble_gap_disc_fn *cb;
             void *cb_arg;
         } disc;
@@ -124,16 +100,10 @@ static bssnz_t struct {
     uint8_t op;
 
     uint8_t conn_mode;
-    uint8_t state;
     uint8_t disc_mode;
     ble_gap_conn_fn *cb;
     void *cb_arg;
 
-    uint8_t dir_addr_type;
-    uint8_t dir_addr[BLE_DEV_ADDR_LEN];
-
-    struct hci_adv_params adv_params;
-    struct hci_adv_params rsp_params;
     uint8_t adv_data[BLE_HCI_MAX_ADV_DATA_LEN];
     uint8_t rsp_data[BLE_HCI_MAX_ADV_DATA_LEN];
     uint8_t adv_data_len;
@@ -143,20 +113,7 @@ static bssnz_t struct {
     unsigned adv_pwr_lvl:1;
 } ble_gap_slave;
 
-struct ble_gap_update_entry {
-    SLIST_ENTRY(ble_gap_update_entry) next;
-    struct ble_gap_upd_params params;
-    uint16_t conn_handle;
-    uint8_t reject_reason;
-    uint8_t state;
-    uint8_t hci_handle;
-};
-static SLIST_HEAD(, ble_gap_update_entry) ble_gap_update_entries;
-
-static void *ble_gap_update_mem;
-static struct os_mempool ble_gap_update_pool;
-
-static int ble_gap_disc_tx_disable(void *arg);
+static int ble_gap_disc_tx_disable(void);
 
 struct ble_gap_snapshot {
     struct ble_gap_conn_desc desc;
@@ -164,8 +121,6 @@ struct ble_gap_snapshot {
     void *cb_arg;
 };
 
-static struct os_mutex ble_gap_mutex;
-
 STATS_SECT_DECL(ble_gap_stats) ble_gap_stats;
 STATS_NAME_START(ble_gap_stats)
     STATS_NAME(ble_gap_stats, wl_set)
@@ -198,83 +153,45 @@ STATS_NAME_START(ble_gap_stats)
 STATS_NAME_END(ble_gap_stats)
 
 /*****************************************************************************
- * $mutex                                                                    *
+ * $log                                                                      *
  *****************************************************************************/
 
 static void
-ble_gap_lock(void)
+ble_gap_log_conn(uint8_t addr_type, uint8_t *addr,
+                 struct ble_gap_crt_params *params)
 {
-    struct os_task *owner;
-    int rc;
-
-    owner = ble_gap_mutex.mu_owner;
-    if (owner != NULL) {
-        BLE_HS_DBG_ASSERT_EVAL(owner != os_sched_get_current_task());
+    BLE_HS_LOG(INFO, "addr_type=%d addr=", addr_type);
+    if (addr == NULL) {
+        BLE_HS_LOG(INFO, "N/A");
+    } else {
+        BLE_HS_LOG_ADDR(INFO, addr);
     }
 
-    rc = os_mutex_pend(&ble_gap_mutex, 0xffffffff);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-static void
-ble_gap_unlock(void)
-{
-    int rc;
-
-    rc = os_mutex_release(&ble_gap_mutex);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-int
-ble_gap_locked_by_cur_task(void)
-{
-    struct os_task *owner;
-
-    owner = ble_gap_mutex.mu_owner;
-    return owner != NULL && owner == os_sched_get_current_task();
-}
-
-/*****************************************************************************
- * $log                                                                      *
- *****************************************************************************/
-
-static void
-ble_gap_log_conn(void)
-{
-    BLE_HS_LOG(INFO, "addr_type=%d addr=", ble_gap_master.conn.addr_type);
-    BLE_HS_LOG_ADDR(INFO, ble_gap_master.conn.addr);
     BLE_HS_LOG(INFO, " scan_itvl=%d scan_window=%d itvl_min=%d itvl_max=%d "
                      "latency=%d supervision_timeout=%d min_ce_len=%d "
                      "max_ce_len=%d",
-               ble_gap_master.conn.params.scan_itvl,
-               ble_gap_master.conn.params.scan_window,
-               ble_gap_master.conn.params.itvl_min,
-               ble_gap_master.conn.params.itvl_max,
-               ble_gap_master.conn.params.latency,
-               ble_gap_master.conn.params.supervision_timeout,
-               ble_gap_master.conn.params.min_ce_len,
-               ble_gap_master.conn.params.max_ce_len);
+               params->scan_itvl, params->scan_window, params->itvl_min,
+               params->itvl_max, params->latency, params->supervision_timeout,
+               params->min_ce_len, params->max_ce_len);
 }
 
 static void
-ble_gap_log_disc(void)
+ble_gap_log_disc(uint8_t scan_type, uint8_t filter_policy)
 {
     BLE_HS_LOG(INFO, "disc_mode=%d filter_policy=%d scan_type=%d",
                ble_gap_master.disc.disc_mode,
-               ble_gap_master.disc.filter_policy,
-               ble_gap_master.disc.scan_type);
+               filter_policy, scan_type);
 }
 
 static void
-ble_gap_log_update(struct ble_gap_update_entry *entry)
+ble_gap_log_update(uint16_t conn_handle, struct ble_gap_upd_params *params)
 {
     BLE_HS_LOG(INFO, "connection parameter update; "
                      "conn_handle=%d itvl_min=%d itvl_max=%d latency=%d "
                      "supervision_timeout=%d min_ce_len=%d max_ce_len=%d",
-               entry->conn_handle, entry->params.itvl_min,
-               entry->params.itvl_max, entry->params.latency,
-               entry->params.supervision_timeout, entry->params.min_ce_len,
-               entry->params.max_ce_len);
+               conn_handle, params->itvl_min, params->itvl_max,
+               params->latency, params->supervision_timeout,
+               params->min_ce_len, params->max_ce_len);
 }
 
 static void
@@ -296,20 +213,20 @@ ble_gap_log_wl(struct ble_gap_white_entry *white_list,
 }
 
 static void
-ble_gap_log_adv(void)
+ble_gap_log_adv(struct hci_adv_params *adv_params)
 {
     BLE_HS_LOG(INFO, "disc_mode=%d addr_type=%d addr=",
-               ble_gap_slave.disc_mode, ble_gap_slave.dir_addr_type);
-    BLE_HS_LOG_ADDR(INFO, ble_gap_slave.dir_addr);
+               ble_gap_slave.disc_mode, adv_params->peer_addr_type);
+    BLE_HS_LOG_ADDR(INFO, adv_params->peer_addr);
     BLE_HS_LOG(INFO, " adv_type=%d adv_channel_map=%d own_addr_type=%d "
                      "adv_filter_policy=%d adv_itvl_min=%d  adv_itvl_max=%d "
                      "adv_data_len=%d",
-               ble_gap_slave.adv_params.adv_type,
-               ble_gap_slave.adv_params.adv_channel_map,
-               ble_gap_slave.adv_params.own_addr_type,
-               ble_gap_slave.adv_params.adv_filter_policy,
-               ble_gap_slave.adv_params.adv_itvl_min,
-               ble_gap_slave.adv_params.adv_itvl_max,
+               adv_params->adv_type,
+               adv_params->adv_channel_map,
+               adv_params->own_addr_type,
+               adv_params->adv_filter_policy,
+               adv_params->adv_itvl_min,
+               adv_params->adv_itvl_max,
                ble_gap_slave.adv_data_len);
 }
 
@@ -353,17 +270,17 @@ ble_gap_find_snapshot(uint16_t handle, struct ble_gap_snapshot *snap)
 {
     struct ble_hs_conn *conn;
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     conn = ble_hs_conn_find(handle);
     if (conn != NULL) {
         ble_gap_conn_to_snapshot(conn, snap);
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     if (conn == NULL) {
-        return BLE_HS_ENOENT;
+        return BLE_HS_ENOTCONN;
     } else {
         return 0;
     }
@@ -375,28 +292,6 @@ ble_gap_find_snapshot(uint16_t handle, struct ble_gap_snapshot *snap)
 
 /**
  * Lock restrictions:
- *     o Caller locks gap.
- */
-static void
-ble_gap_master_reset_state(void)
-{
-    ble_gap_master.state = BLE_GAP_STATE_NULL;
-    ble_gap_master.op = BLE_GAP_OP_NULL;
-}
-
-/**
- * Lock restrictions:
- *     o Caller locks gap.
- */
-static void
-ble_gap_slave_reset_state(void)
-{
-    ble_gap_slave.state = BLE_GAP_STATE_NULL;
-    ble_gap_slave.op = BLE_GAP_OP_NULL;
-}
-
-/**
- * Lock restrictions:
  *     o Caller unlocks all ble_hs mutexes.
  */
 static int
@@ -405,7 +300,7 @@ ble_gap_call_conn_cb(int event, int status, struct ble_gap_conn_ctxt *ctxt,
 {
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     if (cb != NULL) {
         rc = cb(event, status, ctxt, cb_arg);
@@ -432,22 +327,18 @@ ble_gap_call_slave_cb(int event, int status, int reset_state)
     ble_gap_conn_fn *cb;
     void *cb_arg;
 
-    ble_hs_misc_assert_no_locks();
-
-    ble_gap_lock();
+    ble_hs_lock();
 
     desc.conn_handle = BLE_HS_CONN_HANDLE_NONE;
-    desc.peer_addr_type = ble_gap_slave.dir_addr_type;
-    memcpy(desc.peer_addr, ble_gap_slave.dir_addr, sizeof desc.peer_addr);
 
     cb = ble_gap_slave.cb;
     cb_arg = ble_gap_slave.cb_arg;
 
     if (reset_state) {
-        ble_gap_slave_reset_state();
+        ble_gap_slave.op = BLE_GAP_OP_NULL;
     }
 
-    ble_gap_unlock();
+    ble_hs_unlock();
 
     if (cb != NULL) {
         memset(&ctxt, 0, sizeof ctxt);
@@ -470,25 +361,20 @@ ble_gap_call_master_conn_cb(int event, int status, int reset_state)
     void *cb_arg;
     int rc;
 
-    ble_hs_misc_assert_no_locks();
-
-    ble_gap_lock();
+    ble_hs_lock();
 
     memset(&desc, 0, sizeof ctxt);
 
     desc.conn_handle = BLE_HS_CONN_HANDLE_NONE;
-    desc.peer_addr_type = ble_gap_master.conn.addr_type;
-    memcpy(desc.peer_addr, ble_gap_master.conn.addr,
-           sizeof desc.peer_addr);
 
     cb = ble_gap_master.conn.cb;
     cb_arg = ble_gap_master.conn.cb_arg;
 
     if (reset_state) {
-        ble_gap_master_reset_state();
+        ble_gap_master.op = BLE_GAP_OP_NULL;
     }
 
-    ble_gap_unlock();
+    ble_hs_unlock();
 
     if (cb != NULL) {
         memset(&ctxt, 0, sizeof ctxt);
@@ -514,9 +400,7 @@ ble_gap_call_master_disc_cb(int event, int status, struct ble_hs_adv *adv,
     ble_gap_disc_fn *cb;
     void *cb_arg;
 
-    ble_hs_misc_assert_no_locks();
-
-    ble_gap_lock();
+    ble_hs_lock();
 
     if (adv != NULL) {
         desc.event_type = adv->event_type;
@@ -534,10 +418,10 @@ ble_gap_call_master_disc_cb(int event, int status, struct ble_hs_adv *adv,
     cb_arg = ble_gap_master.disc.cb_arg;
 
     if (reset_state) {
-        ble_gap_master_reset_state();
+        ble_gap_master.op = BLE_GAP_OP_NULL;
     }
 
-    ble_gap_unlock();
+    ble_hs_unlock();
 
     if (cb != NULL) {
         cb(event, status, &desc, cb_arg);
@@ -548,48 +432,33 @@ ble_gap_call_master_disc_cb(int event, int status, struct ble_hs_adv *adv,
  * Lock restrictions:
  *     o Caller locks gap.
  */
-static struct ble_gap_update_entry *
-ble_gap_update_find(uint16_t conn_handle)
+int
+ble_gap_update_in_progress(uint16_t conn_handle)
 {
-    struct ble_gap_update_entry *entry;
-
-    SLIST_FOREACH(entry, &ble_gap_update_entries, next) {
-        if (entry->conn_handle == conn_handle) {
-            return entry;
-        }
-    }
+    struct ble_hs_conn *conn;
 
-    return NULL;
+    /* XXX LOCKING */
+    conn = ble_hs_conn_find(conn_handle);
+    return conn != NULL && conn->bhc_flags & BLE_HS_CONN_F_UPDATE;
 }
 
-/**
- * Lock restrictions: None.
- */
-static struct ble_gap_update_entry *
-ble_gap_update_entry_alloc(void)
+static int
+ble_gap_update_set_flag(uint16_t conn_handle, int val)
 {
-    struct ble_gap_update_entry *entry;
+    struct ble_hs_conn *conn;
 
-    entry = os_memblock_get(&ble_gap_update_pool);
-    if (entry == NULL) {
-        return NULL;
+    /* XXX LOCKING */
+    conn = ble_hs_conn_find(conn_handle);
+    if (conn == NULL) {
+        return BLE_HS_ENOTCONN;
+    } else {
+        if (val) {
+            conn->bhc_flags |= BLE_HS_CONN_F_UPDATE;
+        } else {
+            conn->bhc_flags &= ~BLE_HS_CONN_F_UPDATE;
+        }
+        return 0;
     }
-
-    memset(entry, 0, sizeof *entry);
-
-    return entry;
-}
-
-/**
- * Lock restrictions: None.
- */
-static void
-ble_gap_update_entry_free(struct ble_gap_update_entry *entry)
-{
-    int rc;
-
-    rc = os_memblock_put(&ble_gap_update_pool, entry);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
 }
 
 /**
@@ -597,13 +466,13 @@ ble_gap_update_entry_free(struct ble_gap_update_entry *entry)
  *     o Caller unlocks all ble_hs mutexes.
  */
 static void
-ble_gap_update_notify(struct ble_gap_update_entry *entry, int status)
+ble_gap_update_notify(uint16_t conn_handle, int status)
 {
     struct ble_gap_conn_ctxt ctxt;
     struct ble_gap_snapshot snap;
     int rc;
 
-    rc = ble_gap_find_snapshot(entry->conn_handle, &snap);
+    rc = ble_gap_find_snapshot(conn_handle, &snap);
     if (rc != 0) {
         return;
     }
@@ -650,26 +519,12 @@ ble_gap_master_failed(int status)
     }
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
-ble_gap_update_entry_remove_free(struct ble_gap_update_entry *entry)
-{
-    SLIST_REMOVE(&ble_gap_update_entries, entry, ble_gap_update_entry, next);
-    ble_gap_update_entry_free(entry);
-}
-
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-static void
-ble_gap_update_failed(struct ble_gap_update_entry *entry, int status)
+ble_gap_update_failed(uint16_t conn_handle, int status)
 {
     STATS_INC(ble_gap_stats, update_fail);
-    ble_gap_update_notify(entry, status);
-    ble_gap_update_entry_free(entry);
+    ble_gap_update_set_flag(conn_handle, 0);
+    ble_gap_update_notify(conn_handle, status);
 }
 
 /**
@@ -677,24 +532,18 @@ ble_gap_update_failed(struct ble_gap_update_entry *entry, int status)
  *     o Caller unlocks gap.
  */
 static void
-ble_gap_conn_broken(uint16_t conn_handle)
+ble_gap_conn_broken(struct ble_gap_snapshot *snap)
 {
-    struct ble_gap_update_entry *entry;
-
-    ble_gap_lock();
-
-    entry = ble_gap_update_find(conn_handle);
-    if (entry != NULL) {
-        if (entry->hci_handle != BLE_HCI_SCHED_HANDLE_NONE) {
-            ble_hci_sched_cancel(entry->hci_handle);
-        }
-        ble_gap_update_entry_remove_free(entry);
-    }
+    struct ble_gap_conn_ctxt ctxt;
 
-    ble_gap_unlock();
+    ble_gattc_connection_broken(snap->desc.conn_handle);
+    ble_l2cap_sm_connection_broken(snap->desc.conn_handle);
 
-    ble_gattc_connection_broken(conn_handle);
-    ble_l2cap_sm_connection_broken(conn_handle);
+    memset(&ctxt, 0, sizeof ctxt);
+    ctxt.desc = &snap->desc;
+    ble_gap_call_conn_cb(BLE_GAP_EVENT_CONN, BLE_HS_ENOTCONN, &ctxt,
+                         snap->cb, snap->cb_arg);
+    ble_hs_atomic_conn_delete(snap->desc.conn_handle);
 
     STATS_INC(ble_gap_stats, disconnect);
 }
@@ -712,41 +561,24 @@ ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt)
 
     struct ble_gap_conn_ctxt ctxt;
     struct ble_gap_snapshot snap;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_misc_assert_no_locks();
-
     STATS_INC(ble_gap_stats, rx_disconnect);
 
-    if (evt->status == 0) {
-        /* Find the connection that this event refers to. */
-        ble_hs_conn_lock();
-        conn = ble_hs_conn_find(evt->connection_handle);
-        if (conn != NULL) {
-            ble_gap_conn_to_snapshot(conn, &snap);
-            ble_hs_conn_remove(conn);
-            ble_hs_conn_free(conn);
-        }
-        ble_hs_conn_unlock();
-
-        if (conn != NULL) {
-            ble_gap_conn_broken(evt->connection_handle);
+    rc = ble_gap_find_snapshot(evt->connection_handle, &snap);
+    if (rc != 0) {
+        /* No longer connected. */
+        return;
+    }
 
-            memset(&ctxt, 0, sizeof ctxt);
-            ctxt.desc = &snap.desc;
-            ble_gap_call_conn_cb(BLE_GAP_EVENT_CONN, BLE_HS_ENOTCONN, &ctxt,
-                                 snap.cb, snap.cb_arg);
-        }
+    if (evt->status == 0) {
+        ble_gap_conn_broken(&snap);
     } else {
-        rc = ble_gap_find_snapshot(evt->connection_handle, &snap);
-        if (rc == 0) {
-            memset(&ctxt, 0, sizeof ctxt);
-            ctxt.desc = &snap.desc;
-            ble_gap_call_conn_cb(BLE_GAP_EVENT_TERM_FAILURE,
-                                 BLE_HS_HCI_ERR(evt->status), &ctxt,
-                                 snap.cb, snap.cb_arg);
-        }
+        memset(&ctxt, 0, sizeof ctxt);
+        ctxt.desc = &snap.desc;
+        ble_gap_call_conn_cb(BLE_GAP_EVENT_TERM_FAILURE,
+                             BLE_HS_HCI_ERR(evt->status), &ctxt,
+                             snap.cb, snap.cb_arg);
     }
 }
 
@@ -761,28 +593,18 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
     return;
 #endif
 
-    struct ble_gap_update_entry *entry;
     struct ble_gap_conn_ctxt ctxt;
     struct ble_gap_snapshot snap;
     struct ble_hs_conn *conn;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     STATS_INC(ble_gap_stats, rx_update_complete);
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     conn = ble_hs_conn_find(evt->connection_handle);
     if (conn != NULL) {
-        ble_gap_lock();
-
-        entry = ble_gap_update_find(evt->connection_handle);
-        if (entry != NULL) {
-            ble_gap_update_entry_remove_free(entry);
-        }
-
-        ble_gap_unlock();
-
         if (evt->status == 0) {
             conn->bhc_itvl = evt->conn_itvl;
             conn->bhc_latency = evt->conn_latency;
@@ -792,7 +614,8 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
         ble_gap_conn_to_snapshot(conn, &snap);
     }
 
-    ble_hs_conn_unlock();
+    ble_gap_update_set_flag(evt->connection_handle, 0);
+    ble_hs_unlock();
 
     if (conn != NULL) {
         memset(&ctxt, 0, sizeof ctxt);
@@ -826,84 +649,6 @@ ble_gap_slave_in_progress(void)
 }
 
 /**
- * Tells you if the BLE host is in the process of updating a connection.
- *
- * Lock restrictions:
- *     o Caller unlocks gap.
- *
- * @param conn_handle           The connection to test, or
- *                                  BLE_HS_CONN_HANDLE_NONE to check all
- *                                  connections.
- *
- * @return                      0=connection not being updated;
- *                              1=connection being updated.
- */
-int
-ble_gap_update_in_progress(uint16_t conn_handle)
-{
-#if !NIMBLE_OPT_CONNECT
-    return BLE_HS_ENOTSUP;
-#endif
-
-    struct ble_gap_update_entry *entry;
-
-    ble_gap_lock();
-
-    if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
-        entry = ble_gap_update_find(conn_handle);
-    } else {
-        entry = SLIST_FIRST(&ble_gap_update_entries);
-    }
-
-    ble_gap_unlock();
-
-    return entry != NULL;
-}
-
-/**
- * Lock restrictions:
- *     o Caller unlocks gap.
- */
-static int
-ble_gap_gen_set_op(uint8_t *slot, uint8_t op)
-{
-    int rc;
-
-    ble_gap_lock();
-
-    if (*slot != BLE_GAP_OP_NULL) {
-        rc = BLE_HS_EALREADY;
-    } else {
-        *slot = op;
-        rc = 0;
-    }
-
-    ble_gap_unlock();
-
-    return rc;
-}
-
-/**
- * Lock restrictions:
- *     o Caller unlocks gap.
- */
-static int
-ble_gap_master_set_op(uint8_t op)
-{
-    return ble_gap_gen_set_op(&ble_gap_master.op, op);
-}
-
-/**
- * Lock restrictions:
- *     o Caller unlocks gap.
- */
-static int
-ble_gap_slave_set_op(uint8_t op)
-{
-    return ble_gap_gen_set_op(&ble_gap_slave.op, op);
-}
-
-/**
  * Lock restrictions: None.
  */
 static int
@@ -943,17 +688,7 @@ ble_gap_accept_master_conn(uint8_t addr_type, uint8_t *addr)
         break;
 
     case BLE_GAP_OP_M_CONN:
-        if (ble_gap_master.state != BLE_GAP_STATE_M_CONN_ACTIVE) {
-            rc = BLE_HS_ENOENT;
-        } else if (ble_gap_master.conn.addr_type == BLE_GAP_ADDR_TYPE_WL ||
-                   (addr_type == ble_gap_master.conn.addr_type &&
-                    memcmp(addr, ble_gap_master.conn.addr,
-                           BLE_DEV_ADDR_LEN) == 0)) {
-            rc = 0;
-        } else {
-            ble_gap_master_failed(BLE_HS_ECONTROLLER);
-            rc = BLE_HS_ECONTROLLER;
-        }
+        rc = 0;
         break;
 
     default:
@@ -1005,13 +740,7 @@ ble_gap_accept_slave_conn(uint8_t addr_type, uint8_t *addr)
             break;
 
         case BLE_GAP_CONN_MODE_DIR:
-            if (ble_gap_slave.dir_addr_type != addr_type ||
-                memcmp(ble_gap_slave.dir_addr, addr, BLE_DEV_ADDR_LEN) != 0) {
-
-                rc = BLE_HS_ENOENT;
-            } else {
-                rc = 0;
-            }
+            rc = 0;
             break;
 
         default:
@@ -1044,9 +773,7 @@ ble_gap_rx_adv_report(struct ble_hs_adv *adv)
 
     STATS_INC(ble_gap_stats, rx_adv_report);
 
-    if (ble_gap_master.op      != BLE_GAP_OP_M_DISC ||
-        ble_gap_master.state   != BLE_GAP_STATE_M_DISC_ACTIVE) {
-
+    if (ble_gap_master.op != BLE_GAP_OP_M_DISC) {
         return;
     }
 
@@ -1089,30 +816,14 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
     /* Determine if this event refers to a completed connection or a connection
      * in progress.
      */
-    ble_hs_conn_lock();
-    conn = ble_hs_conn_find(evt->connection_handle);
+    rc = ble_gap_find_snapshot(evt->connection_handle, &snap);
 
     /* Apply the event to the existing connection if it exists. */
-    if (conn != NULL) {
+    if (rc == 0) {
         /* XXX: Does this ever happen? */
-        if (evt->status != 0) {
-            ble_gap_conn_to_snapshot(conn, &snap);
-
-            ble_gap_conn_broken(evt->connection_handle);
-
-            ble_hs_conn_remove(conn);
-            ble_hs_conn_free(conn);
-        }
-    }
 
-    ble_hs_conn_unlock();
-
-    if (conn != NULL) {
         if (evt->status != 0) {
-            memset(&ctxt, 0, sizeof ctxt);
-            ctxt.desc = &snap.desc;
-            ble_gap_call_conn_cb(BLE_GAP_EVENT_CONN, evt->status, &ctxt,
-                                 snap.cb, snap.cb_arg);
+            ble_gap_conn_broken(&snap);
         }
         return 0;
     }
@@ -1176,16 +887,16 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
         conn->bhc_flags |= BLE_HS_CONN_F_MASTER;
         conn->bhc_cb = ble_gap_master.conn.cb;
         conn->bhc_cb_arg = ble_gap_master.conn.cb_arg;
-        ble_gap_master_reset_state();
+        ble_gap_master.op = BLE_GAP_OP_NULL;
     } else {
         conn->bhc_cb = ble_gap_slave.cb;
         conn->bhc_cb_arg = ble_gap_slave.cb_arg;
-        ble_gap_slave_reset_state();
+        ble_gap_slave.op = BLE_GAP_OP_NULL;
     }
 
     ble_gap_conn_to_snapshot(conn, &snap);
 
-    ble_hs_conn_insert(conn);
+    ble_hs_atomic_conn_insert(conn);
 
     memset(&ctxt, 0, sizeof ctxt);
     ctxt.desc = &snap.desc;
@@ -1206,7 +917,7 @@ ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
     struct ble_gap_snapshot snap;
     int rc;
 
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     rc = ble_gap_find_snapshot(conn_handle, &snap);
     if (rc != 0) {
@@ -1253,11 +964,9 @@ ble_gap_heartbeat(void)
         switch (ble_gap_master.op) {
         case BLE_GAP_OP_M_DISC:
             /* When a discovery procedure times out, it is not a failure. */
-            ble_gap_master.state = BLE_GAP_STATE_M_DISC_DISABLE;
-            rc = ble_hci_sched_enqueue(ble_gap_disc_tx_disable, NULL, NULL);
-            if (rc != 0) {
-                ble_gap_master_failed(rc);
-            }
+            rc = ble_gap_disc_tx_disable();
+            ble_gap_call_master_disc_cb(BLE_GAP_EVENT_DISC_FINISHED, rc,
+                                        NULL, NULL, 1);
             break;
 
         default:
@@ -1285,7 +994,7 @@ ble_gap_wl_busy(void)
      * progress.
      */
     return ble_gap_master.op == BLE_GAP_OP_M_CONN &&
-           ble_gap_master.conn.addr_type == BLE_GAP_ADDR_TYPE_WL;
+           ble_gap_master.conn.using_wl;
 }
 
 /**
@@ -1304,7 +1013,7 @@ ble_gap_wl_tx_add(struct ble_gap_white_entry *entry)
         return rc;
     }
 
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1322,8 +1031,8 @@ ble_gap_wl_tx_clear(void)
     uint8_t buf[BLE_HCI_CMD_HDR_LEN];
     int rc;
 
-    host_hci_cmd_le_build_clear_whitelist(buf, sizeof buf);
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    host_hci_cmd_build_le_clear_whitelist(buf, sizeof buf);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1350,7 +1059,7 @@ ble_gap_wl_set(struct ble_gap_white_entry *white_list,
 
     if (white_list_count == 0) {
         rc = BLE_HS_EINVAL;
-        goto done;
+        goto err;
     }
 
     for (i = 0; i < white_list_count; i++) {
@@ -1358,36 +1067,35 @@ ble_gap_wl_set(struct ble_gap_white_entry *white_list,
             white_list[i].addr_type != BLE_ADDR_TYPE_RANDOM) {
 
             rc = BLE_HS_EINVAL;
-            goto done;
+            goto err;
         }
     }
 
     if (ble_gap_wl_busy()) {
         rc = BLE_HS_EBUSY;
-        goto done;
+        goto err;
     }
 
+    BLE_HS_LOG(INFO, "GAP procedure initiated: set whitelist; ");
+    ble_gap_log_wl(white_list, white_list_count);
+    BLE_HS_LOG(INFO, "\n");
+
     rc = ble_gap_wl_tx_clear();
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
     for (i = 0; i < white_list_count; i++) {
         rc = ble_gap_wl_tx_add(white_list + i);
         if (rc != 0) {
-            goto done;
+            goto err;
         }
     }
 
-done:
-    if (rc == 0) {
-        BLE_HS_LOG(INFO, "GAP procedure initiated: set whitelist; ");
-        ble_gap_log_wl(white_list, white_list_count);
-        BLE_HS_LOG(INFO, "\n");
-    } else {
-        STATS_INC(ble_gap_stats, wl_set_fail);
-    }
+    return 0;
 
+err:
+    STATS_INC(ble_gap_stats, wl_set_fail);
     return rc;
 }
 
@@ -1406,7 +1114,7 @@ ble_gap_adv_disable_tx(void)
     int rc;
 
     host_hci_cmd_build_le_set_adv_enable(0, buf, sizeof buf);
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1432,25 +1140,22 @@ ble_gap_adv_stop(void)
     /* Do nothing if advertising is already disabled. */
     if (!ble_gap_currently_advertising()) {
         rc = BLE_HS_EALREADY;
-        goto done;
+        goto err;
     }
 
+    BLE_HS_LOG(INFO, "GAP procedure initiated: stop advertising.\n");
+
     rc = ble_gap_adv_disable_tx();
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
-    ble_gap_slave_reset_state();
+    ble_gap_slave.op = BLE_GAP_OP_NULL;
 
-done:
-    if (rc == 0) {
-        BLE_HS_LOG(INFO, "GAP procedure initiated: stop advertising; ");
-        ble_gap_log_adv();
-        BLE_HS_LOG(INFO, "\n");
-    } else {
-        STATS_INC(ble_gap_stats, adv_set_fields_fail);
-    }
+    return 0;
 
+err:
+    STATS_INC(ble_gap_stats, adv_set_fields_fail);
     return rc;
 }
 
@@ -1463,7 +1168,7 @@ done:
  */
 static void
 ble_gap_adv_itvls(uint8_t disc_mode, uint8_t conn_mode,
-                       uint16_t *out_itvl_min, uint16_t *out_itvl_max)
+                  uint16_t *out_itvl_min, uint16_t *out_itvl_max)
 {
     switch (conn_mode) {
     case BLE_GAP_CONN_MODE_NON:
@@ -1499,7 +1204,7 @@ ble_gap_adv_enable_tx(void)
 
     host_hci_cmd_build_le_set_adv_enable(1, buf, sizeof buf);
 
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1524,7 +1229,7 @@ ble_gap_adv_rsp_data_tx(void)
         return rc;
     }
 
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1589,7 +1294,7 @@ ble_gap_adv_data_tx(void)
         return rc;
     }
 
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1602,56 +1307,22 @@ ble_gap_adv_data_tx(void)
  *     o Caller unlocks all ble_hs mutexes.
  */
 static int
-ble_gap_adv_power_tx(void)
-{
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
-    struct ble_hci_block_result result;
-    uint8_t tx_pwr;
-    int rc;
-
-    host_hci_cmd_build_read_adv_pwr(buf, sizeof buf);
-    rc = ble_hci_block_tx(buf, &tx_pwr, 1, &result);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (result.evt_total_len != 1           ||
-        tx_pwr < BLE_HCI_ADV_CHAN_TXPWR_MIN ||
-        tx_pwr > BLE_HCI_ADV_CHAN_TXPWR_MAX) {
-
-        return BLE_HS_ECONTROLLER;
-    }
-
-    ble_gap_slave.tx_pwr_lvl = tx_pwr;
-
-    return 0;
-}
-
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-static int
-ble_gap_adv_params_tx(void)
+ble_gap_adv_params_tx(struct hci_adv_params *adv_params)
 {
     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADV_PARAM_LEN];
-    struct hci_adv_params hap;
     int rc;
 
-    hap = ble_gap_slave.adv_params;
-
     switch (ble_gap_slave.conn_mode) {
     case BLE_GAP_CONN_MODE_NON:
-        hap.adv_type = BLE_HCI_ADV_TYPE_ADV_NONCONN_IND;
+        adv_params->adv_type = BLE_HCI_ADV_TYPE_ADV_NONCONN_IND;
         break;
 
     case BLE_GAP_CONN_MODE_DIR:
-        hap.adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD;
-        memcpy(hap.peer_addr, ble_gap_slave.dir_addr, sizeof hap.peer_addr);
+        adv_params->adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD;
         break;
 
     case BLE_GAP_CONN_MODE_UND:
-        hap.adv_type = BLE_HCI_ADV_TYPE_ADV_IND;
+        adv_params->adv_type = BLE_HCI_ADV_TYPE_ADV_IND;
         break;
 
     default:
@@ -1659,12 +1330,12 @@ ble_gap_adv_params_tx(void)
         break;
     }
 
-    rc = host_hci_cmd_build_le_set_adv_params(&hap, buf, sizeof buf);
+    rc = host_hci_cmd_build_le_set_adv_params(adv_params, buf, sizeof buf);
     if (rc != 0) {
         return rc;
     }
 
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1718,10 +1389,18 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
     return BLE_HS_ENOTSUP;
 #endif
 
+    struct hci_adv_params adv_params_copy;
     int rc;
 
+    ble_hs_lock();
+
     STATS_INC(ble_gap_stats, adv_start);
 
+    if (ble_gap_slave.op != BLE_GAP_OP_NULL) {
+        rc = BLE_HS_EALREADY;
+        goto done;
+    }
+
     if (discoverable_mode >= BLE_GAP_DISC_MODE_MAX) {
         rc = BLE_HS_EINVAL;
         goto done;
@@ -1756,40 +1435,38 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
         goto done;
     }
 
-    rc = ble_gap_slave_set_op(BLE_GAP_OP_S_ADV);
-    if (rc != 0) {
-        goto done;
+    if (adv_params != NULL) {
+        adv_params_copy = *adv_params;
+    } else {
+        adv_params_copy = ble_gap_adv_params_dflt;
     }
-    ble_gap_slave.state = BLE_GAP_STATE_S_ADV_PENDING;
+
+    BLE_HS_LOG(INFO, "GAP procedure initiated: advertise; ");
+    ble_gap_log_adv(&adv_params_copy);
+    BLE_HS_LOG(INFO, "\n");
 
     if (connectable_mode == BLE_GAP_CONN_MODE_DIR) {
-        ble_gap_slave.dir_addr_type = peer_addr_type;
-        memcpy(ble_gap_slave.dir_addr, peer_addr, 6);
+        adv_params_copy.peer_addr_type = peer_addr_type;
+        memcpy(adv_params_copy.peer_addr, peer_addr,
+               sizeof adv_params_copy.peer_addr);
     }
 
     ble_gap_slave.cb = cb;
     ble_gap_slave.cb_arg = cb_arg;
-    ble_gap_slave.state = 0;
     ble_gap_slave.conn_mode = connectable_mode;
     ble_gap_slave.disc_mode = discoverable_mode;
 
-    if (adv_params != NULL) {
-        ble_gap_slave.adv_params = *adv_params;
-    } else {
-        ble_gap_slave.adv_params = ble_gap_adv_params_dflt;
-    }
-
     ble_gap_adv_itvls(discoverable_mode, connectable_mode,
-                      &ble_gap_slave.adv_params.adv_itvl_min,
-                      &ble_gap_slave.adv_params.adv_itvl_max);
+                      &adv_params_copy.adv_itvl_min,
+                      &adv_params_copy.adv_itvl_max);
 
-    rc = ble_gap_adv_params_tx();
+    rc = ble_gap_adv_params_tx(&adv_params_copy);
     if (rc != 0) {
         goto done;
     }
 
     if (ble_gap_slave.adv_pwr_lvl) {
-        rc = ble_gap_adv_power_tx();
+        rc = ble_hci_util_read_adv_tx_pwr(&ble_gap_slave.tx_pwr_lvl);
         if (rc != 0) {
             goto done;
         }
@@ -1812,20 +1489,17 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
         goto done;
     }
 
-    ble_gap_slave.state = BLE_GAP_STATE_S_ADV_ACTIVE;
+    ble_gap_slave.op = BLE_GAP_OP_S_ADV;
+
+    rc = 0;
 
 done:
-    if (rc == 0) {
-        BLE_HS_LOG(INFO, "GAP procedure initiated: advertise; ");
-        ble_gap_log_adv();
-        BLE_HS_LOG(INFO, "\n");
-    } else {
+    if (rc != 0) {
         STATS_INC(ble_gap_stats, adv_start_fail);
-        if (rc != BLE_HS_EALREADY) {
-            ble_gap_slave_reset_state();
-        }
     }
 
+    ble_hs_unlock();
+
     return rc;
 }
 
@@ -1842,6 +1516,8 @@ ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields)
     int max_sz;
     int rc;
 
+    ble_hs_lock();
+
     STATS_INC(ble_gap_stats, adv_set_fields);
 
     if (adv_fields->tx_pwr_lvl_is_present) {
@@ -1858,6 +1534,8 @@ ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields)
         STATS_INC(ble_gap_stats, adv_set_fields_fail);
     }
 
+    ble_hs_unlock();
+
     return rc;
 }
 
@@ -1873,6 +1551,8 @@ ble_gap_adv_rsp_set_fields(struct ble_hs_adv_fields *rsp_fields)
 
     int rc;
 
+    ble_hs_lock();
+
     STATS_INC(ble_gap_stats, adv_rsp_set_fields);
 
     rc = ble_hs_adv_set_fields(rsp_fields, ble_gap_slave.rsp_data,
@@ -1882,6 +1562,8 @@ ble_gap_adv_rsp_set_fields(struct ble_hs_adv_fields *rsp_fields)
         STATS_INC(ble_gap_stats, adv_rsp_set_fields_fail);
     }
 
+    ble_hs_unlock();
+
     return rc;
 }
 
@@ -1893,37 +1575,15 @@ ble_gap_adv_rsp_set_fields(struct ble_hs_adv_fields *rsp_fields)
  * Lock restrictions:
  *     o Caller unlocks all ble_hs mutexes.
  */
-static void
-ble_gap_disc_ack_disable(struct ble_hci_ack *ack, void *arg)
-{
-    BLE_HS_DBG_ASSERT(ble_gap_master.op == BLE_GAP_OP_M_DISC);
-    BLE_HS_DBG_ASSERT(ble_gap_master.state == BLE_GAP_STATE_M_DISC_DISABLE);
-
-    if (ack->bha_status != 0) {
-        ble_gap_master_failed(ack->bha_status);
-    } else {
-        ble_gap_call_master_disc_cb(BLE_GAP_EVENT_DISC_FINISHED, 0,
-                                    NULL, NULL, 1);
-    }
-}
-
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
-ble_gap_disc_tx_disable(void *arg)
+ble_gap_disc_tx_disable(void)
 {
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_ENABLE_LEN];
     int rc;
 
-    BLE_HS_DBG_ASSERT(ble_gap_master.op == BLE_GAP_OP_M_DISC);
-    BLE_HS_DBG_ASSERT(ble_gap_master.state == BLE_GAP_STATE_M_DISC_DISABLE);
-
-    ble_hci_sched_set_ack_cb(ble_gap_disc_ack_disable, NULL);
-    rc = host_hci_cmd_le_set_scan_enable(0, 0);
+    host_hci_cmd_build_le_set_scan_enable(0, 0, buf, sizeof buf);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
-        /* XXX: What can we do? */
-        ble_gap_master_failed(rc);
         return rc;
     }
 
@@ -1941,7 +1601,7 @@ ble_gap_disc_tx_enable(void)
     int rc;
 
     host_hci_cmd_build_le_set_scan_enable(1, 0, buf, sizeof buf);
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1954,24 +1614,21 @@ ble_gap_disc_tx_enable(void)
  *     o Caller unlocks all ble_hs mutexes.
  */
 static int
-ble_gap_disc_tx_params(void)
+ble_gap_disc_tx_params(uint8_t scan_type, uint8_t filter_policy)
 {
     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_PARAM_LEN];
     int rc;
 
-    BLE_HS_DBG_ASSERT(ble_gap_master.op == BLE_GAP_OP_M_DISC);
-    BLE_HS_DBG_ASSERT(ble_gap_master.state == BLE_GAP_STATE_M_DISC_PENDING);
-
     rc = host_hci_cmd_build_le_set_scan_params(
-        ble_gap_master.disc.scan_type,
+        scan_type,
         BLE_GAP_SCAN_FAST_INTERVAL_MIN,
         BLE_GAP_SCAN_FAST_WINDOW,
         BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-        ble_gap_master.disc.filter_policy,
+        filter_policy,
         buf, sizeof buf);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0);
 
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1999,6 +1656,13 @@ ble_gap_disc(uint32_t duration_ms, uint8_t discovery_mode,
 
     int rc;
 
+    ble_hs_lock();
+
+    if (ble_gap_master.op != BLE_GAP_OP_NULL) {
+        rc = BLE_HS_EALREADY;
+        goto done;
+    }
+
     STATS_INC(ble_gap_stats, discover);
 
     if (discovery_mode != BLE_GAP_DISC_MODE_LTD &&
@@ -2024,18 +1688,15 @@ ble_gap_disc(uint32_t duration_ms, uint8_t discovery_mode,
         duration_ms = BLE_GAP_GEN_DISC_SCAN_MIN;
     }
 
-    rc = ble_gap_master_set_op(BLE_GAP_OP_M_DISC);
-    if (rc != 0) {
-        goto done;
-    }
-
     ble_gap_master.disc.disc_mode = discovery_mode;
-    ble_gap_master.disc.scan_type = scan_type;
-    ble_gap_master.disc.filter_policy = filter_policy;
     ble_gap_master.disc.cb = cb;
     ble_gap_master.disc.cb_arg = cb_arg;
 
-    rc = ble_gap_disc_tx_params();
+    BLE_HS_LOG(INFO, "GAP procedure initiated: discovery; ");
+    ble_gap_log_disc(scan_type, filter_policy);
+    BLE_HS_LOG(INFO, "\n");
+
+    rc = ble_gap_disc_tx_params(scan_type, filter_policy);
     if (rc != 0) {
         goto done;
     }
@@ -2046,19 +1707,17 @@ ble_gap_disc(uint32_t duration_ms, uint8_t discovery_mode,
     }
 
     ble_gap_master_set_timer(duration_ms);
+    ble_gap_master.op = BLE_GAP_OP_M_DISC;
+
+    rc = 0;
 
 done:
-    if (rc == 0) {
-        BLE_HS_LOG(INFO, "GAP procedure initiated: discovery; ");
-        ble_gap_log_disc();
-        BLE_HS_LOG(INFO, "\n");
-    } else {
-        if (rc != BLE_HS_EALREADY) {
-            ble_gap_master_reset_state();
-        }
+    if (rc != 0) {
         STATS_INC(ble_gap_stats, discover_fail);
     }
 
+    ble_hs_unlock();
+
     return rc;
 }
 
@@ -2079,48 +1738,43 @@ done:
  *     o Caller unlocks all ble_hs mutexes.
  */
 static int
-ble_gap_conn_create_tx(void *arg)
+ble_gap_conn_create_tx(int addr_type, uint8_t *addr,
+                       struct ble_gap_crt_params *params)
 {
     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_CREATE_CONN_LEN];
     struct hci_create_conn hcc;
     int rc;
 
-    BLE_HS_DBG_ASSERT(ble_gap_master.op == BLE_GAP_OP_M_CONN);
+    hcc.scan_itvl = params->scan_itvl;
+    hcc.scan_window = params->scan_window;
 
-    hcc.scan_itvl = ble_gap_master.conn.params.scan_itvl;
-    hcc.scan_window = ble_gap_master.conn.params.scan_window;
-
-    if (ble_gap_master.conn.addr_type == BLE_GAP_ADDR_TYPE_WL) {
+    if (addr_type == BLE_GAP_ADDR_TYPE_WL) {
         hcc.filter_policy = BLE_HCI_CONN_FILT_USE_WL;
         hcc.peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC;
         memset(hcc.peer_addr, 0, sizeof hcc.peer_addr);
     } else {
         hcc.filter_policy = BLE_HCI_CONN_FILT_NO_WL;
-        hcc.peer_addr_type = ble_gap_master.conn.addr_type;
-        memcpy(hcc.peer_addr, ble_gap_master.conn.addr,
-               sizeof hcc.peer_addr);
+        hcc.peer_addr_type = addr_type;
+        memcpy(hcc.peer_addr, addr, sizeof hcc.peer_addr);
     }
     hcc.own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
-    hcc.conn_itvl_min = ble_gap_master.conn.params.itvl_min;
-    hcc.conn_itvl_max = ble_gap_master.conn.params.itvl_max;
-    hcc.conn_latency = ble_gap_master.conn.params.latency;
-    hcc.supervision_timeout =
-        ble_gap_master.conn.params.supervision_timeout;
-    hcc.min_ce_len = ble_gap_master.conn.params.min_ce_len;
-    hcc.max_ce_len = ble_gap_master.conn.params.max_ce_len;
+    hcc.conn_itvl_min = params->itvl_min;
+    hcc.conn_itvl_max = params->itvl_max;
+    hcc.conn_latency = params->latency;
+    hcc.supervision_timeout = params->supervision_timeout;
+    hcc.min_ce_len = params->min_ce_len;
+    hcc.max_ce_len = params->max_ce_len;
 
     rc = host_hci_cmd_build_le_create_connection(&hcc, buf, sizeof buf);
     if (rc != 0) {
         return BLE_HS_EUNKNOWN;
     }
 
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
 
-    ble_gap_master.state = BLE_GAP_STATE_M_CONN_ACTIVE;
-
     return 0;
 }
 
@@ -2152,6 +1806,13 @@ ble_gap_conn_initiate(int addr_type, uint8_t *addr,
 
     int rc;
 
+    ble_hs_lock();
+
+    if (ble_gap_master.op != BLE_GAP_OP_NULL) {
+        rc = BLE_HS_EALREADY;
+        goto done;
+    }
+
     STATS_INC(ble_gap_stats, initiate);
 
     if (addr_type != BLE_HCI_CONN_PEER_ADDR_PUBLIC &&
@@ -2162,44 +1823,36 @@ ble_gap_conn_initiate(int addr_type, uint8_t *addr,
         goto done;
     }
 
-    rc = ble_gap_master_set_op(BLE_GAP_OP_M_CONN);
-    if (rc != 0) {
-        goto done;
-    }
-    ble_gap_master.state = BLE_GAP_STATE_M_CONN_PENDING;
-
     if (params == NULL) {
-        ble_gap_master.conn.params = ble_gap_params_dflt;
-    } else {
-        /* XXX: Verify params. */
-        ble_gap_master.conn.params = *params;
+        params = (void *)&ble_gap_params_dflt;
     }
 
-    ble_gap_master.conn.addr_type = addr_type;
+    /* XXX: Verify params. */
+
+    BLE_HS_LOG(INFO, "GAP procedure initiated: connect; ");
+    ble_gap_log_conn(addr_type, addr, params);
+    BLE_HS_LOG(INFO, "\n");
+
     ble_gap_master.conn.cb = cb;
     ble_gap_master.conn.cb_arg = cb_arg;
+    ble_gap_master.conn.using_wl = addr_type == BLE_GAP_ADDR_TYPE_WL;
 
-    if (addr_type != BLE_GAP_ADDR_TYPE_WL) {
-        memcpy(ble_gap_master.conn.addr, addr, BLE_DEV_ADDR_LEN);
-    }
-
-    rc = ble_gap_conn_create_tx(NULL);
+    rc = ble_gap_conn_create_tx(addr_type, addr, params);
     if (rc != 0) {
         goto done;
     }
 
+    ble_gap_master.op = BLE_GAP_OP_M_CONN;
+
+    rc = 0;
+
 done:
-    if (rc == 0) {
-        BLE_HS_LOG(INFO, "GAP procedure initiated: connect; ");
-        ble_gap_log_conn();
-        BLE_HS_LOG(INFO, "\n");
-    } else {
-        if (rc != BLE_HS_EALREADY) {
-            ble_gap_master_reset_state();
-        }
+    if (rc != 0) {
         STATS_INC(ble_gap_stats, initiate_fail);
     }
 
+    ble_hs_unlock();
+
     return rc;
 }
 
@@ -2217,6 +1870,8 @@ ble_gap_terminate(uint16_t conn_handle)
     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_DISCONNECT_CMD_LEN];
     int rc;
 
+    ble_hs_lock();
+
     STATS_INC(ble_gap_stats, terminate);
 
     if (!ble_hs_conn_exists(conn_handle)) {
@@ -2224,21 +1879,25 @@ ble_gap_terminate(uint16_t conn_handle)
         goto done;
     }
 
+    BLE_HS_LOG(INFO, "GAP procedure initiated: terminate connection; "
+                     "conn_handle=%d\n", conn_handle);
+
     host_hci_cmd_build_disconnect(conn_handle, BLE_ERR_REM_USER_CONN_TERM,
                                   buf, sizeof buf);
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         goto done;
     }
 
+    rc = 0;
+
 done:
-    if (rc == 0) {
-        BLE_HS_LOG(INFO, "GAP procedure initiated: terminate connection; "
-                         "conn_handle=%d\n", conn_handle);
-    } else {
+    if (rc != 0) {
         STATS_INC(ble_gap_stats, terminate_fail);
     }
 
+    ble_hs_unlock();
+
     return rc;
 }
 
@@ -2256,6 +1915,8 @@ ble_gap_cancel(void)
     uint8_t buf[BLE_HCI_CMD_HDR_LEN];
     int rc;
 
+    ble_hs_lock();
+
     STATS_INC(ble_gap_stats, cancel);
 
     if (!ble_gap_master_in_progress()) {
@@ -2263,19 +1924,23 @@ ble_gap_cancel(void)
         goto done;
     }
 
+    BLE_HS_LOG(INFO, "GAP procedure initiated: cancel connection\n");
+
     host_hci_cmd_build_le_create_conn_cancel(buf, sizeof buf);
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         goto done;
     }
 
+    rc = 0;
+
 done:
-    if (rc == 0) {
-        BLE_HS_LOG(INFO, "GAP procedure initiated: cancel connection\n");
-    } else {
+    if (rc != 0) {
         STATS_INC(ble_gap_stats, cancel_fail);
     }
 
+    ble_hs_unlock();
+
     return rc;
 }
 
@@ -2283,128 +1948,48 @@ done:
  * $update connection parameters                                             *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks gap.
- */
-static void
-ble_gap_param_neg_reply_ack(struct ble_hci_ack *ack, void *arg)
-{
-    struct ble_gap_update_entry *entry;
-
-    ble_gap_lock();
-
-    entry = arg;
-    BLE_HS_DBG_ASSERT(entry->state == BLE_GAP_STATE_U_NEG_REPLY);
-    BLE_HS_DBG_ASSERT(entry->hci_handle == ack->bha_hci_handle);
-
-    entry->hci_handle = BLE_HCI_SCHED_HANDLE_NONE;
-
-    SLIST_REMOVE(&ble_gap_update_entries, entry,
-                 ble_gap_update_entry, next);
-
-    ble_gap_unlock();
-
-    ble_gap_update_entry_free(entry);
-}
-
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-static void
-ble_gap_param_reply_ack(struct ble_hci_ack *ack, void *arg)
-{
-    struct ble_gap_update_entry *entry;
-
-    ble_gap_lock();
-
-    entry = arg;
-    BLE_HS_DBG_ASSERT(entry->state == BLE_GAP_STATE_U_REPLY);
-    BLE_HS_DBG_ASSERT(entry->hci_handle == ack->bha_hci_handle);
-
-    entry->hci_handle = BLE_HCI_SCHED_HANDLE_NONE;
-
-    if (ack->bha_status != 0) {
-        SLIST_REMOVE(&ble_gap_update_entries, entry,
-                     ble_gap_update_entry, next);
-    } else {
-        entry->state = BLE_GAP_STATE_U_REPLY_ACKED;
-    }
-
-    ble_gap_unlock();
-
-    if (ack->bha_status != 0) {
-        ble_gap_update_failed(entry, ack->bha_status);
-    }
-}
-
 static int
-ble_gap_tx_param_pos_reply(void *arg)
+ble_gap_tx_param_pos_reply(uint16_t conn_handle,
+                           struct ble_gap_upd_params *params)
 {
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_CONN_PARAM_REPLY_LEN];
     struct hci_conn_param_reply pos_reply;
-    struct ble_gap_update_entry *entry;
-    struct ble_gap_conn_ctxt ctxt;
-    struct ble_gap_snapshot snap;
-    int snap_rc;
     int rc;
 
-    entry = arg;
-
-    pos_reply.handle = entry->conn_handle;
-    pos_reply.conn_itvl_min = entry->params.itvl_min;
-    pos_reply.conn_itvl_max = entry->params.itvl_max;
-    pos_reply.conn_latency = entry->params.latency;
-    pos_reply.supervision_timeout = entry->params.supervision_timeout;
-    pos_reply.min_ce_len = entry->params.min_ce_len;
-    pos_reply.max_ce_len = entry->params.max_ce_len;
-
-    ble_hci_sched_set_ack_cb(ble_gap_param_reply_ack, entry);
+    pos_reply.handle = conn_handle;
+    pos_reply.conn_itvl_min = params->itvl_min;
+    pos_reply.conn_itvl_max = params->itvl_max;
+    pos_reply.conn_latency = params->latency;
+    pos_reply.supervision_timeout = params->supervision_timeout;
+    pos_reply.min_ce_len = params->min_ce_len;
+    pos_reply.max_ce_len = params->max_ce_len;
 
-    rc = host_hci_cmd_le_conn_param_reply(&pos_reply);
+    host_hci_cmd_build_le_conn_param_reply(&pos_reply, buf, sizeof buf);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
-        rc = BLE_HS_HCI_ERR(rc);
-        snap_rc = ble_gap_find_snapshot(entry->conn_handle, &snap);
-        if (snap_rc == 0) {
-            memset(&ctxt, 0, sizeof ctxt);
-            ctxt.desc = &snap.desc;
-            ble_gap_call_conn_cb(BLE_GAP_EVENT_CONN_UPDATE_REQ, rc, &ctxt,
-                                 snap.cb, snap.cb_arg);
-        }
+        return rc;
     }
 
-    return rc;
+    return 0;
 }
 
 static int
-ble_gap_tx_param_neg_reply(void *arg)
+ble_gap_tx_param_neg_reply(uint16_t conn_handle, uint8_t reject_reason)
 {
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_CONN_PARAM_NEG_REPLY_LEN];
     struct hci_conn_param_neg_reply neg_reply;
-    struct ble_gap_update_entry *entry;
-    struct ble_gap_conn_ctxt ctxt;
-    struct ble_gap_snapshot snap;
-    int snap_rc;
     int rc;
 
-    entry = arg;
-
-    neg_reply.handle = entry->conn_handle;
-    neg_reply.reason = entry->reject_reason;
+    neg_reply.handle = conn_handle;
+    neg_reply.reason = reject_reason;
 
-    ble_hci_sched_set_ack_cb(ble_gap_param_neg_reply_ack, entry);
-    rc = host_hci_cmd_le_conn_param_neg_reply(&neg_reply);
+    host_hci_cmd_build_le_conn_param_neg_reply(&neg_reply, buf, sizeof buf);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
-        rc = BLE_HS_HCI_ERR(rc);
-        snap_rc = ble_gap_find_snapshot(entry->conn_handle, &snap);
-        if (snap_rc == 0) {
-            memset(&ctxt, 0, sizeof ctxt);
-            ctxt.desc = &snap.desc;
-            ble_gap_call_conn_cb(BLE_GAP_EVENT_CONN_UPDATE_REQ, rc, &ctxt,
-                                 snap.cb, snap.cb_arg);
-        }
+        return rc;
     }
 
-    return rc;
+    return 0;
 }
 
 /**
@@ -2419,29 +2004,22 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
 #endif
 
     struct ble_gap_upd_params peer_params;
-    struct ble_gap_update_entry *entry;
+    struct ble_gap_upd_params self_params;
     struct ble_gap_conn_ctxt ctxt;
     struct ble_gap_snapshot snap;
+    uint8_t reject_reason;
     int rc;
 
+    ble_hs_lock();
+
+    reject_reason = 0; /* Silence warning. */
+
     rc = ble_gap_find_snapshot(evt->connection_handle, &snap);
     if (rc != 0) {
         /* We are not connected to the sender. */
-        return;
+        goto done;;
     }
 
-    ble_gap_lock();
-
-    entry = ble_gap_update_find(evt->connection_handle);
-    if (entry != NULL) {
-        /* Parameter update already in progress; replace existing request with
-         * new one.
-         */
-        ble_gap_update_entry_remove_free(entry);
-    }
-
-    ble_gap_unlock();
-
     peer_params.itvl_min = evt->itvl_min;
     peer_params.itvl_max = evt->itvl_max;
     peer_params.latency = evt->latency;
@@ -2449,51 +2027,32 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
     peer_params.min_ce_len = 0;
     peer_params.max_ce_len = 0;
 
-    entry = ble_gap_update_entry_alloc();
-    if (entry == NULL) {
-        /* Out of memory; reject. */
-        /* XXX: Our negative response should indicate which connection handle
-         * it applies to, but we don't have anywhere to store this information.
-         * For now, just send a connection handle of 0 and hope the peer can
-         * sort it out.
-         */
-        rc = BLE_ERR_MEM_CAPACITY;
-    } else {
-        entry->state = BLE_GAP_STATE_U_REPLY;
-        entry->conn_handle = evt->connection_handle;
-        entry->params = peer_params;
+    /* By default, the application will just XXX */
+    self_params = peer_params;
 
-        memset(&ctxt, 0, sizeof ctxt);
-        ctxt.desc = &snap.desc;
-        ctxt.update.self_params = &entry->params;
-        ctxt.update.peer_params = &peer_params;
-        rc = ble_gap_call_conn_cb(BLE_GAP_EVENT_CONN_UPDATE_REQ, 0, &ctxt,
-                                  snap.cb, snap.cb_arg);
-        if (rc != 0) {
-            entry->reject_reason = rc;
-        }
+    memset(&ctxt, 0, sizeof ctxt);
+    ctxt.desc = &snap.desc;
+    ctxt.update.self_params = &self_params;
+    ctxt.update.peer_params = &peer_params;
+    rc = ble_gap_call_conn_cb(BLE_GAP_EVENT_CONN_UPDATE_REQ, 0, &ctxt,
+                              snap.cb, snap.cb_arg);
+    if (rc != 0) {
+        reject_reason = rc;
     }
 
     if (rc == 0) {
-        ble_hci_sched_enqueue(ble_gap_tx_param_pos_reply, entry,
-                              &entry->hci_handle);
-    }
-
-    if (rc != 0) {
-        if (entry != NULL) {
-            entry->state = BLE_GAP_STATE_U_NEG_REPLY;
-            ble_hci_sched_enqueue(ble_gap_tx_param_neg_reply, entry,
-                                  &entry->hci_handle);
+        rc = ble_gap_tx_param_pos_reply(evt->connection_handle, &self_params);
+        if (rc != 0) {
+            ble_gap_update_failed(evt->connection_handle, rc);
         } else {
-            ble_hci_sched_enqueue(ble_gap_tx_param_neg_reply, NULL, NULL);
+            ble_gap_update_set_flag(evt->connection_handle, 1);
         }
+    } else {
+        ble_gap_tx_param_neg_reply(evt->connection_handle, reject_reason);
     }
 
-    if (entry != NULL) {
-        ble_gap_lock();
-        SLIST_INSERT_HEAD(&ble_gap_update_entries, entry, next);
-        ble_gap_unlock();
-    }
+done:
+    ble_hs_unlock();
 }
 
 /**
@@ -2501,26 +2060,26 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
  *     o Caller locks gap.
  */
 static int
-ble_gap_update_tx(struct ble_gap_update_entry *entry)
+ble_gap_update_tx(uint16_t conn_handle, struct ble_gap_upd_params *params)
 {
     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_CONN_UPDATE_LEN];
     struct hci_conn_update cmd;
     int rc;
 
-    cmd.handle = entry->conn_handle;
-    cmd.conn_itvl_min = entry->params.itvl_min;
-    cmd.conn_itvl_max = entry->params.itvl_max;
-    cmd.conn_latency = entry->params.latency;
-    cmd.supervision_timeout = entry->params.supervision_timeout;
-    cmd.min_ce_len = entry->params.min_ce_len;
-    cmd.max_ce_len = entry->params.max_ce_len;
+    cmd.handle = conn_handle;
+    cmd.conn_itvl_min = params->itvl_min;
+    cmd.conn_itvl_max = params->itvl_max;
+    cmd.conn_latency = params->latency;
+    cmd.supervision_timeout = params->supervision_timeout;
+    cmd.min_ce_len = params->min_ce_len;
+    cmd.max_ce_len = params->max_ce_len;
 
     rc = host_hci_cmd_build_le_conn_update(&cmd, buf, sizeof buf);
     if (rc != 0) {
         return rc;
     }
 
-    rc = ble_hci_block_tx(buf, NULL, 0, NULL);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -2540,50 +2099,39 @@ ble_gap_update_params(uint16_t conn_handle, struct ble_gap_upd_params *params)
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_gap_update_entry *entry;
     int rc;
 
-    STATS_INC(ble_gap_stats, update);
+    ble_hs_lock();
 
-    ble_gap_lock();
+    STATS_INC(ble_gap_stats, update);
 
     if (!ble_hs_conn_exists(conn_handle)) {
         rc = BLE_HS_ENOTCONN;
         goto done;
     }
 
-    entry = ble_gap_update_find(conn_handle);
-    if (entry != NULL) {
+    if (ble_gap_update_in_progress(conn_handle)) {
         rc = BLE_HS_EALREADY;
         goto done;
     }
 
-    entry = ble_gap_update_entry_alloc();
-    if (entry == NULL) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
-    }
-
-    entry->state = BLE_GAP_STATE_U_UPDATE;
-    entry->conn_handle = conn_handle;
-    entry->params = *params;
+    BLE_HS_LOG(INFO, "GAP procedure initiated: ");
+    ble_gap_log_update(conn_handle, params);
+    BLE_HS_LOG(INFO, "\n");
 
-    rc = ble_gap_update_tx(entry);
+    rc = ble_gap_update_tx(conn_handle, params);
     if (rc != 0) {
         goto done;
     }
 
+    ble_gap_update_set_flag(conn_handle, 1);
+
 done:
-    if (rc == 0) {
-        BLE_HS_LOG(INFO, "GAP procedure initiated: ");
-        ble_gap_log_update(entry);
-        BLE_HS_LOG(INFO, "\n");
-        SLIST_INSERT_HEAD(&ble_gap_update_entries, entry, next);
-    } else {
+    if (rc != 0) {
         STATS_INC(ble_gap_stats, update_fail);
     }
 
-    ble_gap_unlock();
+    ble_hs_unlock();
 
     return rc;
 }
@@ -2600,12 +2148,14 @@ ble_gap_security_initiate(uint16_t conn_handle)
     struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
+
     conn = ble_hs_conn_find(conn_handle);
     if (conn != NULL) {
         conn_flags = conn->bhc_flags;
     }
-    ble_hs_conn_unlock();
+
+    ble_hs_unlock();
 
     if (conn == NULL) {
         return BLE_HS_ENOTCONN;
@@ -2627,7 +2177,7 @@ ble_gap_security_event(uint16_t conn_handle, int status,
     struct ble_gap_snapshot snap;
     struct ble_hs_conn *conn;
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     conn = ble_hs_conn_find(conn_handle);
     if (conn != NULL) {
@@ -2635,7 +2185,7 @@ ble_gap_security_event(uint16_t conn_handle, int status,
         ble_gap_conn_to_snapshot(conn, &snap);
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     if (conn == NULL) {
         /* No longer connected. */
@@ -2664,36 +2214,12 @@ ble_gap_init(void)
     memset(&ble_gap_master, 0, sizeof ble_gap_master);
     memset(&ble_gap_slave, 0, sizeof ble_gap_slave);
 
-    free(ble_gap_update_mem);
-    ble_gap_update_mem = malloc(
-        OS_MEMPOOL_BYTES(ble_hs_cfg.max_conn_update_entries,
-                         sizeof (struct ble_gap_update_entry)));
-
-    if (ble_hs_cfg.max_conn_update_entries > 0) {
-        rc = os_mempool_init(&ble_gap_update_pool,
-                             ble_hs_cfg.max_conn_update_entries,
-                             sizeof (struct ble_gap_update_entry),
-                             ble_gap_update_mem, "ble_gap_update_pool");
-        if (rc != 0) {
-            rc = BLE_HS_EOS;
-            goto err;
-        }
-    }
-
-    SLIST_INIT(&ble_gap_update_entries);
-
     rc = stats_init_and_reg(
         STATS_HDR(ble_gap_stats), STATS_SIZE_INIT_PARMS(ble_gap_stats,
         STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_gap_stats), "ble_gap");
     if (rc != 0) {
-        rc = BLE_HS_EOS;
-        goto err;
+        return BLE_HS_EOS;
     }
 
     return 0;
-
-err:
-    free(ble_gap_update_mem);
-    ble_gap_update_mem = NULL;
-    return rc;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_gatt_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatt_priv.h b/net/nimble/host/src/ble_gatt_priv.h
index 9200c4c..704d441 100644
--- a/net/nimble/host/src/ble_gatt_priv.h
+++ b/net/nimble/host/src/ble_gatt_priv.h
@@ -104,7 +104,6 @@ int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle,
                        ble_gatt_attr_fn *cb, void *cb_arg);
 
 void ble_gattc_rx_err(uint16_t conn_handle, struct ble_att_error_rsp *rsp);
-void ble_gattc_wakeup(void);
 void ble_gattc_rx_mtu(uint16_t conn_handle, int status, uint16_t chan_mtu);
 void ble_gattc_rx_read_type_adata(uint16_t conn_handle,
                                   struct ble_att_read_type_adata *adata);


[29/50] [abbrv] incubator-mynewt-core git commit: nffs - Fix for broken iteration through all objs.

Posted by ma...@apache.org.
nffs - Fix for broken iteration through all objs.

The NFFS_HASH_FOREACH macro was broken because it did not account for
the fact that read operations can still modify the ordering in the hash.
In particular, lookups cause an object to be moved to the front of the
list to facilitate LRU.

Now, the macro stores a "next" pointer before executing the body of the
loop.


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

Branch: refs/heads/master
Commit: ff2049703b1b9720ad1d047df3cfbe119e1e70fb
Parents: 832637d
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 20 17:52:03 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 20 17:52:03 2016 -0700

----------------------------------------------------------------------
 fs/nffs/src/nffs_priv.h    | 6 ++++--
 fs/nffs/src/nffs_restore.c | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ff204970/fs/nffs/src/nffs_priv.h
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_priv.h b/fs/nffs/src/nffs_priv.h
index 3670251..49b72ea 100644
--- a/fs/nffs/src/nffs_priv.h
+++ b/fs/nffs/src/nffs_priv.h
@@ -431,9 +431,11 @@ int nffs_restore_full(const struct nffs_area_desc *area_descs);
 int nffs_write_to_file(struct nffs_file *file, const void *data, int len);
 
 
-#define NFFS_HASH_FOREACH(entry, i)                                     \
+#define NFFS_HASH_FOREACH(entry, i, next)                               \
     for ((i) = 0; (i) < NFFS_HASH_SIZE; (i)++)                          \
-        SLIST_FOREACH((entry), &nffs_hash[i], nhe_next)
+        for ((entry) = SLIST_FIRST(nffs_hash + (i));                    \
+             (entry) && (((next)) = SLIST_NEXT((entry), nhe_next), 1);  \
+             (entry) = ((next)))
 
 #define NFFS_FLASH_LOC_NONE  nffs_flash_loc(NFFS_AREA_ID_NONE, 0)
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ff204970/fs/nffs/src/nffs_restore.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_restore.c b/fs/nffs/src/nffs_restore.c
index 28ea39a..9289203 100644
--- a/fs/nffs/src/nffs_restore.c
+++ b/fs/nffs/src/nffs_restore.c
@@ -275,10 +275,11 @@ static int
 nffs_restore_find_file_ends(void)
 {
     struct nffs_hash_entry *block_entry;
+    struct nffs_hash_entry *next;
     int rc;
     int i;
 
-    NFFS_HASH_FOREACH(block_entry, i) {
+    NFFS_HASH_FOREACH(block_entry, i, next) {
         if (!nffs_hash_id_is_inode(block_entry->nhe_id)) {
             rc = nffs_restore_find_file_end_block(block_entry);
             assert(rc == 0);
@@ -984,12 +985,13 @@ nffs_log_contents(void)
 
     struct nffs_inode_entry *inode_entry;
     struct nffs_hash_entry *entry;
+    struct nffs_hash_entry *next;
     struct nffs_block block;
     struct nffs_inode inode;
     int rc;
     int i;
 
-    NFFS_HASH_FOREACH(entry, i) {
+    NFFS_HASH_FOREACH(entry, i, next) {
         if (nffs_hash_id_is_block(entry->nhe_id)) {
             rc = nffs_block_from_hash_entry(&block, entry);
             assert(rc == 0);


[39/50] [abbrv] incubator-mynewt-core git commit: MYNEWT-288: add nrf52dk support

Posted by ma...@apache.org.
MYNEWT-288: add nrf52dk support


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

Branch: refs/heads/master
Commit: 2b268fbebeb3e742620188d053b0656f80776ead
Parents: 6d8a3a7
Author: William San Filippo <wi...@runtime.io>
Authored: Fri Apr 22 17:47:55 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Fri Apr 22 17:47:55 2016 -0700

----------------------------------------------------------------------
 hw/bsp/nrf52dk/boot-nrf52dk.ld                  | 191 +++++++++++++
 hw/bsp/nrf52dk/include/bsp/bsp.h                |  49 ++++
 hw/bsp/nrf52dk/include/bsp/bsp_sysid.h          |  37 +++
 hw/bsp/nrf52dk/include/bsp/cmsis_nvic.h         |  29 ++
 hw/bsp/nrf52dk/nrf52dk.ld                       | 200 +++++++++++++
 hw/bsp/nrf52dk/nrf52dk_debug.sh                 |  47 +++
 hw/bsp/nrf52dk/nrf52dk_download.sh              |  94 ++++++
 hw/bsp/nrf52dk/nrf52dk_no_boot.ld               | 191 +++++++++++++
 hw/bsp/nrf52dk/pkg.yml                          |  40 +++
 .../src/arch/cortex_m4/gcc_startup_nrf52.s      | 284 +++++++++++++++++++
 hw/bsp/nrf52dk/src/hal_bsp.c                    |  46 +++
 hw/bsp/nrf52dk/src/libc_stubs.c                 |  84 ++++++
 hw/bsp/nrf52dk/src/os_bsp.c                     |  78 +++++
 hw/bsp/nrf52dk/src/sbrk.c                       |  54 ++++
 hw/bsp/nrf52dk/src/system_nrf52.c               | 183 ++++++++++++
 15 files changed, 1607 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/boot-nrf52dk.ld
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/boot-nrf52dk.ld b/hw/bsp/nrf52dk/boot-nrf52dk.ld
new file mode 100755
index 0000000..8c47d2e
--- /dev/null
+++ b/hw/bsp/nrf52dk/boot-nrf52dk.ld
@@ -0,0 +1,191 @@
+/* Linker script for Nordic Semiconductor nRF5 devices
+ *
+ * Version: Sourcery G++ 4.5-1
+ * Support: https://support.codesourcery.com/GNUToolchain/
+ *
+ * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions.  No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x8000
+  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __bssnz_start__
+ *   __bssnz_end__
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+    .text :
+    {
+        __isr_vector_start = .;
+        KEEP(*(.isr_vector))
+        __isr_vector_end = .;
+        *(.text*)
+
+        KEEP(*(.init))
+        KEEP(*(.fini))
+
+        /* .ctors */
+        *crtbegin.o(.ctors)
+        *crtbegin?.o(.ctors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+        *(SORT(.ctors.*))
+        *(.ctors)
+
+        /* .dtors */
+        *crtbegin.o(.dtors)
+        *crtbegin?.o(.dtors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+        *(SORT(.dtors.*))
+        *(.dtors)
+
+        *(.rodata*)
+
+        *(.eh_frame*)
+        . = ALIGN(4);
+    } > FLASH
+
+
+    .ARM.extab :
+    {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+        . = ALIGN(4);
+    } > FLASH
+
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+        . = ALIGN(4);
+    } > FLASH
+    __exidx_end = .;
+
+    __etext = .;
+
+    .vector_relocation :
+    {
+        . = ALIGN(4);
+        __vector_tbl_reloc__ = .;
+        . = . + (__isr_vector_end - __isr_vector_start);
+        . = ALIGN(4);
+    } > RAM
+
+    .data : AT (__etext)
+    {
+        __data_start__ = .;
+        *(vtable)
+        *(.data*)
+
+        . = ALIGN(4);
+        /* preinit data */
+        PROVIDE_HIDDEN (__preinit_array_start = .);
+        *(.preinit_array)
+        PROVIDE_HIDDEN (__preinit_array_end = .);
+
+        . = ALIGN(4);
+        /* init data */
+        PROVIDE_HIDDEN (__init_array_start = .);
+        *(SORT(.init_array.*))
+        *(.init_array)
+        PROVIDE_HIDDEN (__init_array_end = .);
+
+
+        . = ALIGN(4);
+        /* finit data */
+        PROVIDE_HIDDEN (__fini_array_start = .);
+        *(SORT(.fini_array.*))
+        *(.fini_array)
+        PROVIDE_HIDDEN (__fini_array_end = .);
+
+        *(.jcr)
+        . = ALIGN(4);
+        /* All data end */
+        __data_end__ = .;
+    } > RAM
+
+    /* Non-zeroed BSS.  This section is similar to BSS, with the following 
+     * caveat:
+     *    1. It does not get zeroed at init-time.
+     */
+    .bssnz :
+    {
+        . = ALIGN(4);
+        __bssnz_start__ = .;
+        *(.bss.core.nz*)
+        . = ALIGN(4);
+        __bssnz_end__ = .;
+    } > RAM
+
+    .bss :
+    {
+        . = ALIGN(4);
+        __bss_start__ = .;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(4);
+        __bss_end__ = .;
+    } > RAM
+
+    /* Heap starts after BSS */
+    __HeapBase = .;
+
+    /* .stack_dummy section doesn't contains any symbols. It is only
+     * used for linker to calculate size of stack sections, and assign
+     * values to stack symbols later */
+    .stack_dummy (COPY):
+    {
+        *(.stack*)
+    } > RAM
+
+    /* Set stack top to end of RAM, and stack limit move down by
+     * size of stack_dummy section */
+    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+    PROVIDE(__stack = __StackTop);
+
+    /* Top of head is the bottom of the stack */
+    __HeapLimit = __StackLimit;
+
+    /* Check if data + heap + stack exceeds RAM limit */
+    ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack")
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/include/bsp/bsp.h
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/include/bsp/bsp.h b/hw/bsp/nrf52dk/include/bsp/bsp.h
new file mode 100644
index 0000000..d2a32c5
--- /dev/null
+++ b/hw/bsp/nrf52dk/include/bsp/bsp.h
@@ -0,0 +1,49 @@
+/**
+ * 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_BSP_H
+#define H_BSP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define special stackos sections */
+#define sec_data_core   __attribute__((section(".data.core")))
+#define sec_bss_core    __attribute__((section(".bss.core")))
+#define sec_bss_nz_core __attribute__((section(".bss.core.nz")))
+
+/* More convenient section placement macros. */
+#define bssnz_t         sec_bss_nz_core
+
+/* LED pins */
+#define LED_BLINK_PIN   (17)
+
+/* UART info */
+#define CONSOLE_UART    0
+
+int bsp_imgr_current_slot(void);
+
+#define NFFS_AREA_MAX    (8)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* H_BSP_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/include/bsp/bsp_sysid.h
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/include/bsp/bsp_sysid.h b/hw/bsp/nrf52dk/include/bsp/bsp_sysid.h
new file mode 100644
index 0000000..63959e5
--- /dev/null
+++ b/hw/bsp/nrf52dk/include/bsp/bsp_sysid.h
@@ -0,0 +1,37 @@
+/**
+ * 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 BSP_SYSID_H
+#define BSP_SYSID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* stub until this BSP gets new HAL */
+enum system_device_id  
+{
+    RESERVED,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_SYSID_H */
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/include/bsp/cmsis_nvic.h
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/include/bsp/cmsis_nvic.h b/hw/bsp/nrf52dk/include/bsp/cmsis_nvic.h
new file mode 100644
index 0000000..6f07f11
--- /dev/null
+++ b/hw/bsp/nrf52dk/include/bsp/cmsis_nvic.h
@@ -0,0 +1,29 @@
+/* mbed Microcontroller Library - cmsis_nvic
+ * Copyright (c) 2009-2011 ARM Limited. All rights reserved.
+ *
+ * CMSIS-style functionality to support dynamic vectors
+ */
+
+#ifndef MBED_CMSIS_NVIC_H
+#define MBED_CMSIS_NVIC_H
+
+#include <stdint.h>
+
+#define NVIC_NUM_VECTORS      (16 + 38)   // CORE + MCU Peripherals
+#define NVIC_USER_IRQ_OFFSET  16
+
+#include "mcu/nrf52.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void NVIC_Relocate(void);
+void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
+uint32_t NVIC_GetVector(IRQn_Type IRQn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/nrf52dk.ld
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/nrf52dk.ld b/hw/bsp/nrf52dk/nrf52dk.ld
new file mode 100755
index 0000000..c019b63
--- /dev/null
+++ b/hw/bsp/nrf52dk/nrf52dk.ld
@@ -0,0 +1,200 @@
+/* Linker script for Nordic Semiconductor nRF5 devices
+ *
+ * Version: Sourcery G++ 4.5-1
+ * Support: https://support.codesourcery.com/GNUToolchain/
+ *
+ * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions.  No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00008000, LENGTH = 0x3a000
+  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __bssnz_start__
+ *   __bssnz_end__
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+    .imghdr (NOLOAD):
+    {
+        . = . + 0x20;
+    } > FLASH
+
+    .text :
+    {
+        __isr_vector_start = .;
+        KEEP(*(.isr_vector))
+        __isr_vector_end = .;
+        *(.text*)
+
+        KEEP(*(.init))
+        KEEP(*(.fini))
+
+        /* .ctors */
+        *crtbegin.o(.ctors)
+        *crtbegin?.o(.ctors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+        *(SORT(.ctors.*))
+        *(.ctors)
+
+        /* .dtors */
+        *crtbegin.o(.dtors)
+        *crtbegin?.o(.dtors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+        *(SORT(.dtors.*))
+        *(.dtors)
+
+        *(.rodata*)
+
+        *(.eh_frame*)
+        . = ALIGN(4);
+    } > FLASH
+
+
+    .ARM.extab :
+    {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+        . = ALIGN(4);
+    } > FLASH
+
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+        . = ALIGN(4);
+    } > FLASH
+    __exidx_end = .;
+
+    __etext = .;
+
+    .vector_relocation :
+    {
+        . = ALIGN(4);
+        __vector_tbl_reloc__ = .;
+        . = . + (__isr_vector_end - __isr_vector_start);
+        . = ALIGN(4);
+    } > RAM
+
+    .data : AT (__etext)
+    {
+        __data_start__ = .;
+        *(vtable)
+        *(.data*)
+
+        . = ALIGN(4);
+        /* preinit data */
+        PROVIDE_HIDDEN (__preinit_array_start = .);
+        *(.preinit_array)
+        PROVIDE_HIDDEN (__preinit_array_end = .);
+
+        . = ALIGN(4);
+        /* init data */
+        PROVIDE_HIDDEN (__init_array_start = .);
+        *(SORT(.init_array.*))
+        *(.init_array)
+        PROVIDE_HIDDEN (__init_array_end = .);
+
+
+        . = ALIGN(4);
+        /* finit data */
+        PROVIDE_HIDDEN (__fini_array_start = .);
+        *(SORT(.fini_array.*))
+        *(.fini_array)
+        PROVIDE_HIDDEN (__fini_array_end = .);
+
+        *(.jcr)
+        . = ALIGN(4);
+        /* All data end */
+        __data_end__ = .;
+    } > RAM
+
+    /* Non-zeroed BSS.  This section is similar to BSS, with the following two
+     * caveats:
+     *    1. It does not get zeroed at init-time.
+     *    2. You cannot use it as source memory for EasyDMA.
+     *
+     * This section exists because of a hardware defect; see errata 33 and 34
+     * in nrf52 errata sheet.
+     */
+    .bssnz :
+    {
+        . = ALIGN(4);
+        __bssnz_start__ = .;
+        *(.bss.core.nz*)
+        . = ALIGN(4);
+        __bssnz_end__ = .;
+    } > RAM
+
+    .bss :
+    {
+        . = ALIGN(4);
+        __bss_start__ = .;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(4);
+        __bss_end__ = .;
+    } > RAM
+
+    /* Heap starts after BSS */
+    __HeapBase = .;
+
+    /* .stack_dummy section doesn't contains any symbols. It is only
+     * used for linker to calculate size of stack sections, and assign
+     * values to stack symbols later */
+    .stack_dummy (COPY):
+    {
+        *(.stack*)
+    } > RAM
+
+    /* Set stack top to end of RAM, and stack limit move down by
+     * size of stack_dummy section */
+    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+    PROVIDE(__stack = __StackTop);
+
+    /* Top of head is the bottom of the stack */
+    __HeapLimit = __StackLimit;
+
+    /* Check if data + heap + stack exceeds RAM limit */
+    ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack")
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/nrf52dk_debug.sh
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/nrf52dk_debug.sh b/hw/bsp/nrf52dk/nrf52dk_debug.sh
new file mode 100755
index 0000000..469bbaa
--- /dev/null
+++ b/hw/bsp/nrf52dk/nrf52dk_debug.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+# 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.
+#
+# Called: $0 <bsp_directory_path> <binary> [features...]
+#  - bsp_directory_path is absolute path to hw/bsp/bsp_name
+#  - binary is the path to prefix to target binary, .elf.bin appended to this
+#    name is the raw binary format of the binary.
+#  - features are the target features. So you can have e.g. different
+#    flash offset for bootloader 'feature'
+# 
+#
+if [ $# -lt 1 ]; then
+    echo "Need binary to download"
+    exit 1
+fi
+
+FILE_NAME=$2.elf
+GDB_CMD_FILE=.gdb_cmds
+
+echo "Debugging" $FILE_NAME
+
+# Monitor mode. Background process gets it's own process group.
+set -m
+JLinkGDBServer -device nRF52 -speed 4000 -if SWD -port 3333 -singlerun > /dev/null &
+set +m
+
+echo "target remote localhost:3333" > $GDB_CMD_FILE
+
+arm-none-eabi-gdb -x $GDB_CMD_FILE $FILE_NAME
+
+rm $GDB_CMD_FILE
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/nrf52dk_download.sh
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/nrf52dk_download.sh b/hw/bsp/nrf52dk/nrf52dk_download.sh
new file mode 100755
index 0000000..028a5aa
--- /dev/null
+++ b/hw/bsp/nrf52dk/nrf52dk_download.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+# 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.
+
+# Called: $0 <bsp_directory_path> <binary> [features...]
+#  - bsp_directory_path is absolute path to hw/bsp/bsp_name
+#  - binary is the path to prefix to target binary, .elf.bin appended to this
+#    name is the raw binary format of the binary.
+#  - features are the target features. So you can have e.g. different
+#    flash offset for bootloader 'feature'
+#
+#
+
+if [ $# -lt 2 ]; then
+    echo "Need binary to download"
+    exit 1
+fi
+
+IS_BOOTLOADER=0
+BASENAME=$2
+GDB_CMD_FILE=.gdb_cmds
+
+# Look for 'bootloader' from 3rd arg onwards
+shift
+shift
+while [ $# -gt 0 ]; do
+    if [ $1 = "bootloader" ]; then
+        IS_BOOTLOADER=1
+    fi
+    shift
+done
+
+if [ $IS_BOOTLOADER -eq 1 ]; then
+    FLASH_OFFSET=0x0
+    FILE_NAME=$BASENAME.elf.bin
+else
+    FLASH_OFFSET=0x8000
+    FILE_NAME=$BASENAME.img
+fi
+
+echo "Downloading" $FILE_NAME "to" $FLASH_OFFSET
+
+# XXX for some reason JLinkExe overwrites flash at offset 0 when
+# downloading somewhere in the flash. So need to figure out how to tell it
+# not to do that, or report failure if gdb fails to write this file
+#
+echo "shell /bin/sh -c 'trap \"\" 2;JLinkGDBServer -device nRF52 -speed 4000 -if SWD -port 3333 -singlerun' & " > $GDB_CMD_FILE
+echo "target remote localhost:3333" >> $GDB_CMD_FILE
+echo "restore $FILE_NAME binary $FLASH_OFFSET" >> $GDB_CMD_FILE
+echo "quit" >> $GDB_CMD_FILE
+
+msgs=`arm-none-eabi-gdb -x $GDB_CMD_FILE 2>&1`
+echo $msgs > .gdb_out
+
+rm $GDB_CMD_FILE
+
+# Echo output from script run, so newt can show it if things go wrong.
+echo $msgs
+
+error=`echo $msgs | grep error`
+if [ -n "$error" ]; then
+    exit 1
+fi
+
+error=`echo $msgs | grep -i failed`
+if [ -n "$error" ]; then
+    exit 1
+fi
+
+error=`echo $msgs | grep -i "unknown / supported"`
+if [ -n "$error" ]; then
+    exit 1
+fi
+
+error=`echo $msgs | grep -i "not found"`
+if [ -n "$error" ]; then
+    exit 1
+fi
+
+exit 0

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/nrf52dk_no_boot.ld
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/nrf52dk_no_boot.ld b/hw/bsp/nrf52dk/nrf52dk_no_boot.ld
new file mode 100755
index 0000000..e2fb5a8
--- /dev/null
+++ b/hw/bsp/nrf52dk/nrf52dk_no_boot.ld
@@ -0,0 +1,191 @@
+/* Linker script for Nordic Semiconductor nRF5 devices
+ *
+ * Version: Sourcery G++ 4.5-1
+ * Support: https://support.codesourcery.com/GNUToolchain/
+ *
+ * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions.  No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000
+  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __HeapBase
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __bssnz_start__
+ *   __bssnz_end__
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+    .text :
+    {
+        __isr_vector_start = .;
+        KEEP(*(.isr_vector))
+        __isr_vector_end = .;
+        *(.text*)
+
+        KEEP(*(.init))
+        KEEP(*(.fini))
+
+        /* .ctors */
+        *crtbegin.o(.ctors)
+        *crtbegin?.o(.ctors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+        *(SORT(.ctors.*))
+        *(.ctors)
+
+        /* .dtors */
+        *crtbegin.o(.dtors)
+        *crtbegin?.o(.dtors)
+        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+        *(SORT(.dtors.*))
+        *(.dtors)
+
+        *(.rodata*)
+
+        *(.eh_frame*)
+        . = ALIGN(4);
+    } > FLASH
+
+
+    .ARM.extab :
+    {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+        . = ALIGN(4);
+    } > FLASH
+
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+        . = ALIGN(4);
+    } > FLASH
+    __exidx_end = .;
+
+    __etext = .;
+
+    .vector_relocation :
+    {
+        . = ALIGN(4);
+        __vector_tbl_reloc__ = .;
+        . = . + (__isr_vector_end - __isr_vector_start);
+        . = ALIGN(4);
+    } > RAM
+
+    .data : AT (__etext)
+    {
+        __data_start__ = .;
+        *(vtable)
+        *(.data*)
+
+        . = ALIGN(4);
+        /* preinit data */
+        PROVIDE_HIDDEN (__preinit_array_start = .);
+        *(.preinit_array)
+        PROVIDE_HIDDEN (__preinit_array_end = .);
+
+        . = ALIGN(4);
+        /* init data */
+        PROVIDE_HIDDEN (__init_array_start = .);
+        *(SORT(.init_array.*))
+        *(.init_array)
+        PROVIDE_HIDDEN (__init_array_end = .);
+
+
+        . = ALIGN(4);
+        /* finit data */
+        PROVIDE_HIDDEN (__fini_array_start = .);
+        *(SORT(.fini_array.*))
+        *(.fini_array)
+        PROVIDE_HIDDEN (__fini_array_end = .);
+
+        *(.jcr)
+        . = ALIGN(4);
+        /* All data end */
+        __data_end__ = .;
+    } > RAM
+
+    /* Non-zeroed BSS.  This section is similar to BSS, with the following
+     * caveat:
+     *    1. It does not get zeroed at init-time.
+     */
+    .bssnz :
+    {
+        . = ALIGN(4);
+        __bssnz_start__ = .;
+        *(.bss.core.nz*)
+        . = ALIGN(4);
+        __bssnz_end__ = .;
+    } > RAM
+
+    .bss :
+    {
+        . = ALIGN(4);
+        __bss_start__ = .;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(4);
+        __bss_end__ = .;
+    } > RAM
+
+    /* Heap starts after BSS */
+    __HeapBase = .;
+
+    /* .stack_dummy section doesn't contains any symbols. It is only
+     * used for linker to calculate size of stack sections, and assign
+     * values to stack symbols later */
+    .stack_dummy (COPY):
+    {
+        *(.stack*)
+    } > RAM
+
+    /* Set stack top to end of RAM, and stack limit move down by
+     * size of stack_dummy section */
+    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+    PROVIDE(__stack = __StackTop);
+
+    /* Top of head is the bottom of the stack */
+    __HeapLimit = __StackLimit;
+
+    /* Check if data + heap + stack exceeds RAM limit */
+    ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack")
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/pkg.yml b/hw/bsp/nrf52dk/pkg.yml
new file mode 100644
index 0000000..617cea7
--- /dev/null
+++ b/hw/bsp/nrf52dk/pkg.yml
@@ -0,0 +1,40 @@
+#
+# 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: hw/bsp/nrf52dk
+pkg.type: bsp
+pkg.description: BSP definition for the Nordic nRF52 Development Kit (PCA 10040).
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - nrf52
+    - nrf52dk
+
+pkg.arch: cortex_m4
+pkg.compiler: compiler/arm-none-eabi-m4
+pkg.linkerscript: "nrf52dk.ld"
+pkg.linkerscript.bootloader.OVERWRITE: "boot-nrf52dk.ld"
+pkg.downloadscript: nrf52dk_download.sh
+pkg.debugscript: nrf52dk_debug.sh
+pkg.cflags: -DNRF52
+pkg.deps:
+    - hw/mcu/nordic/nrf52xxx
+    - libs/baselibc
+pkg.deps.BLE_DEVICE:
+    - net/nimble/drivers/nrf52

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/src/arch/cortex_m4/gcc_startup_nrf52.s
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/src/arch/cortex_m4/gcc_startup_nrf52.s b/hw/bsp/nrf52dk/src/arch/cortex_m4/gcc_startup_nrf52.s
new file mode 100755
index 0000000..8bdf2f6
--- /dev/null
+++ b/hw/bsp/nrf52dk/src/arch/cortex_m4/gcc_startup_nrf52.s
@@ -0,0 +1,284 @@
+/*
+Copyright (c) 2015, Nordic Semiconductor ASA
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+* Neither the name of Nordic Semiconductor ASA nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+NOTE: Template files (including this one) are application specific and therefore
+expected to be copied into the application project folder prior to its use!
+*/
+
+    .syntax unified
+    .arch armv7-m
+
+    .section .stack
+    .align 3
+    .equ    Stack_Size, 432
+    .globl    __StackTop
+    .globl    __StackLimit
+__StackLimit:
+    .space    Stack_Size
+    .size __StackLimit, . - __StackLimit
+__StackTop:
+    .size __StackTop, . - __StackTop
+
+    .section .heap
+    .align 3
+#ifdef __HEAP_SIZE
+    .equ    Heap_Size, __HEAP_SIZE
+#else
+    .equ    Heap_Size, 0
+#endif
+    .globl    __HeapBase
+    .globl    __HeapLimit
+__HeapBase:
+    .if    Heap_Size
+    .space    Heap_Size
+    .endif
+    .size __HeapBase, . - __HeapBase
+__HeapLimit:
+    .size __HeapLimit, . - __HeapLimit
+
+    .section .isr_vector
+    .align 2
+    .globl __isr_vector
+__isr_vector:
+    .long    __StackTop            /* Top of Stack */
+    .long   Reset_Handler               /* Reset Handler */
+    .long   NMI_Handler                 /* NMI Handler */
+    .long   HardFault_Handler           /* Hard Fault Handler */
+    .long   0                           /* Reserved */
+    .long   0                           /* Reserved */
+    .long   0                           /* Reserved */
+    .long   0                           /* Reserved */
+    .long   0                           /* Reserved */
+    .long   0                           /* Reserved */
+    .long   0                           /* Reserved */
+    .long   SVC_Handler                 /* SVCall Handler */
+    .long   0                           /* Reserved */
+    .long   0                           /* Reserved */
+    .long   PendSV_Handler              /* PendSV Handler */
+    .long   SysTick_Handler             /* SysTick Handler */
+
+  /* External Interrupts */
+    .long   POWER_CLOCK_IRQHandler
+    .long   RADIO_IRQHandler
+    .long   UARTE0_UART0_IRQHandler
+    .long   SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
+    .long   SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
+    .long   NFCT_IRQHandler
+    .long   GPIOTE_IRQHandler
+    .long   SAADC_IRQHandler
+    .long   TIMER0_IRQHandler
+    .long   TIMER1_IRQHandler
+    .long   TIMER2_IRQHandler
+    .long   RTC0_IRQHandler
+    .long   TEMP_IRQHandler
+    .long   RNG_IRQHandler
+    .long   ECB_IRQHandler
+    .long   CCM_AAR_IRQHandler
+    .long   WDT_IRQHandler
+    .long   RTC1_IRQHandler
+    .long   QDEC_IRQHandler
+    .long   COMP_LPCOMP_IRQHandler
+    .long   SWI0_EGU0_IRQHandler
+    .long   SWI1_EGU1_IRQHandler
+    .long   SWI2_EGU2_IRQHandler
+    .long   SWI3_EGU3_IRQHandler
+    .long   SWI4_EGU4_IRQHandler
+    .long   SWI5_EGU5_IRQHandler
+    .long   TIMER3_IRQHandler
+    .long   TIMER4_IRQHandler
+    .long   PWM0_IRQHandler
+    .long   PDM_IRQHandler
+    .long   0                         /*Reserved */
+    .long   0                         /*Reserved */
+    .long   MWU_IRQHandler
+    .long   PWM1_IRQHandler
+    .long   PWM2_IRQHandler
+    .long   SPIM2_SPIS2_SPI2_IRQHandler
+    .long   RTC2_IRQHandler
+    .long   I2S_IRQHandler
+
+    .size    __isr_vector, . - __isr_vector
+
+/* Reset Handler */
+
+    .text
+    .thumb
+    .thumb_func
+    .align 1
+    .globl    Reset_Handler
+    .type    Reset_Handler, %function
+Reset_Handler:
+    .fnstart
+
+
+/*     Loop to copy data from read only memory to RAM. The ranges
+ *      of copy from/to are specified by following symbols evaluated in
+ *      linker script.
+ *      __etext: End of code section, i.e., begin of data sections to copy from.
+ *      __data_start__/__data_end__: RAM address range that data should be
+ *      copied to. Both must be aligned to 4 bytes boundary.  */
+
+    ldr    r1, =__etext
+    ldr    r2, =__data_start__
+    ldr    r3, =__data_end__
+
+    subs    r3, r2
+    ble     .LC0
+
+.LC1:
+    subs    r3, 4
+    ldr    r0, [r1,r3]
+    str    r0, [r2,r3]
+    bgt    .LC1
+.LC0:
+
+    LDR     R0, =SystemInit
+    BLX     R0
+    LDR     R0, =_start
+    BX      R0
+
+    .pool
+    .cantunwind
+    .fnend
+    .size   Reset_Handler,.-Reset_Handler
+
+    .section ".text"
+
+
+/* Dummy Exception Handlers (infinite loops which can be modified) */
+
+    .weak   NMI_Handler
+    .type   NMI_Handler, %function
+NMI_Handler:
+    B       .
+    .size   NMI_Handler, . - NMI_Handler
+
+
+    .weak   HardFault_Handler
+    .type   HardFault_Handler, %function
+HardFault_Handler:
+    B       .
+    .size   HardFault_Handler, . - HardFault_Handler
+
+
+    .weak   MemoryManagement_Handler
+    .type   MemoryManagement_Handler, %function
+MemoryManagement_Handler:
+    B       .
+    .size   MemoryManagement_Handler, . - MemoryManagement_Handler
+
+
+    .weak   BusFault_Handler
+    .type   BusFault_Handler, %function
+BusFault_Handler:
+    B       .
+    .size   BusFault_Handler, . - BusFault_Handler
+
+
+    .weak   UsageFault_Handler
+    .type   UsageFault_Handler, %function
+UsageFault_Handler:
+    B       .
+    .size   UsageFault_Handler, . - UsageFault_Handler
+
+
+    .weak   SVC_Handler
+    .type   SVC_Handler, %function
+SVC_Handler:
+    B       .
+    .size   SVC_Handler, . - SVC_Handler
+
+
+    .weak   PendSV_Handler
+    .type   PendSV_Handler, %function
+PendSV_Handler:
+    B       .
+    .size   PendSV_Handler, . - PendSV_Handler
+
+
+    .weak   SysTick_Handler
+    .type   SysTick_Handler, %function
+SysTick_Handler:
+    B       .
+    .size   SysTick_Handler, . - SysTick_Handler
+
+
+/* IRQ Handlers */
+
+    .globl  Default_Handler
+    .type   Default_Handler, %function
+Default_Handler:
+    B       .
+    .size   Default_Handler, . - Default_Handler
+
+    .macro  IRQ handler
+    .weak   \handler
+    .set    \handler, Default_Handler
+    .endm
+
+    IRQ  POWER_CLOCK_IRQHandler
+    IRQ  RADIO_IRQHandler
+    IRQ  UARTE0_UART0_IRQHandler
+    IRQ  SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
+    IRQ  SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
+    IRQ  NFCT_IRQHandler
+    IRQ  GPIOTE_IRQHandler
+    IRQ  SAADC_IRQHandler
+    IRQ  TIMER0_IRQHandler
+    IRQ  TIMER1_IRQHandler
+    IRQ  TIMER2_IRQHandler
+    IRQ  RTC0_IRQHandler
+    IRQ  TEMP_IRQHandler
+    IRQ  RNG_IRQHandler
+    IRQ  ECB_IRQHandler
+    IRQ  CCM_AAR_IRQHandler
+    IRQ  WDT_IRQHandler
+    IRQ  RTC1_IRQHandler
+    IRQ  QDEC_IRQHandler
+    IRQ  COMP_LPCOMP_IRQHandler
+    IRQ  SWI0_EGU0_IRQHandler
+    IRQ  SWI1_EGU1_IRQHandler
+    IRQ  SWI2_EGU2_IRQHandler
+    IRQ  SWI3_EGU3_IRQHandler
+    IRQ  SWI4_EGU4_IRQHandler
+    IRQ  SWI5_EGU5_IRQHandler
+    IRQ  TIMER3_IRQHandler
+    IRQ  TIMER4_IRQHandler
+    IRQ  PWM0_IRQHandler
+    IRQ  PDM_IRQHandler
+    IRQ  MWU_IRQHandler
+    IRQ  PWM1_IRQHandler
+    IRQ  PWM2_IRQHandler
+    IRQ  SPIM2_SPIS2_SPI2_IRQHandler
+    IRQ  RTC2_IRQHandler
+    IRQ  I2S_IRQHandler
+
+  .end

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/src/hal_bsp.c
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/src/hal_bsp.c b/hw/bsp/nrf52dk/src/hal_bsp.c
new file mode 100644
index 0000000..0b04610
--- /dev/null
+++ b/hw/bsp/nrf52dk/src/hal_bsp.c
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ */
+#include <stdint.h>
+#include <stddef.h>
+#include "mcu/nrf52_hal.h"
+
+static const struct nrf52_uart_cfg uart_cfg = {
+    .suc_pin_tx = 6,
+    .suc_pin_rx = 8,
+    .suc_pin_rts = 5,
+    .suc_pin_cts = 7
+};
+
+const struct nrf52_uart_cfg *
+bsp_uart_config(void)
+{
+    return &uart_cfg;
+}
+
+const struct hal_flash *
+bsp_flash_dev(uint8_t id)
+{
+    /*
+     * Internal flash mapped to id 0.
+     */
+    if (id != 0) {
+        return NULL;
+    }
+    return &nrf52k_flash_dev;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/src/libc_stubs.c
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/src/libc_stubs.c b/hw/bsp/nrf52dk/src/libc_stubs.c
new file mode 100644
index 0000000..84f855e
--- /dev/null
+++ b/hw/bsp/nrf52dk/src/libc_stubs.c
@@ -0,0 +1,84 @@
+/**
+ * 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.
+ */
+#include <hal/hal_system.h>
+
+void * _sbrk(int c);
+int _close(int fd);
+int _fstat(int fd, void *s);
+void _exit(int s);
+int _kill(int pid, int sig);
+int _write(int fd, void *b, int nb);
+int _isatty(int c);
+int _lseek(int fd, int off, int w);
+int _read(int fd, void *b, int nb);
+int _getpid(void);
+
+int
+_close(int fd)
+{
+    return -1;
+}
+
+int
+_fstat(int fd, void *s)
+{
+    return -1;
+}
+
+
+void
+_exit(int s)
+{
+    system_reset();
+}
+
+int
+_kill(int pid, int sig)
+{
+    return -1;
+}
+
+int
+_write(int fd, void *b, int nb)
+{
+    return -1;
+}
+
+int
+_isatty(int c)
+{
+    return -1;
+}
+
+int
+_lseek(int fd, int off, int w)
+{
+    return -1;
+}
+
+int
+_read(int fd, void *b, int nb)
+{
+    return -1;
+}
+
+int
+_getpid(void) {
+    return -1;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/src/os_bsp.c
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/src/os_bsp.c b/hw/bsp/nrf52dk/src/os_bsp.c
new file mode 100644
index 0000000..c05b208
--- /dev/null
+++ b/hw/bsp/nrf52dk/src/os_bsp.c
@@ -0,0 +1,78 @@
+/**
+ * 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.
+ */
+#include <hal/flash_map.h>
+
+static struct flash_area bsp_flash_areas[] = {
+    [FLASH_AREA_BOOTLOADER] = {
+        .fa_flash_id = 0,       /* internal flash */
+        .fa_off = 0x00000000,   /* beginning */
+        .fa_size = (32 * 1024)
+    },
+    /* 2*16K and 1*64K sectors here */
+    [FLASH_AREA_IMAGE_0] = {
+        .fa_flash_id = 0,
+        .fa_off = 0x00008000,
+        .fa_size = (232 * 1024)
+    },
+    [FLASH_AREA_IMAGE_1] = {
+        .fa_flash_id = 0,
+        .fa_off = 0x00042000,
+        .fa_size = (232 * 1024)
+    },
+    [FLASH_AREA_IMAGE_SCRATCH] = {
+        .fa_flash_id = 0,
+        .fa_off = 0x0007c000,
+        .fa_size = (4 * 1024)
+    },
+    [FLASH_AREA_NFFS] = {
+        .fa_flash_id = 0,
+        .fa_off = 0x0007d000,
+        .fa_size = (12 * 1024)
+    }
+};
+
+void *_sbrk(int incr);
+void _close(int fd);
+
+/*
+ * Returns the flash map slot where the currently active image is located.
+ * If executing from internal flash from fixed location, that slot would
+ * be easy to find.
+ * If images are in external flash, and copied to RAM for execution, then
+ * this routine would have to figure out which one of those slots is being
+ * used.
+ */
+int
+bsp_imgr_current_slot(void)
+{
+    return FLASH_AREA_IMAGE_0;
+}
+
+void
+os_bsp_init(void)
+{
+    /*
+     * XXX this reference is here to keep this function in.
+     */
+    _sbrk(0);
+    _close(0);
+
+    flash_area_init(bsp_flash_areas,
+      sizeof(bsp_flash_areas) / sizeof(bsp_flash_areas[0]));
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/src/sbrk.c
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/src/sbrk.c b/hw/bsp/nrf52dk/src/sbrk.c
new file mode 100644
index 0000000..0fd7a41
--- /dev/null
+++ b/hw/bsp/nrf52dk/src/sbrk.c
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+#include <errno.h>
+
+extern char __HeapBase;
+extern char __HeapLimit;
+
+static char *brk = &__HeapBase;
+
+void *
+_sbrk(int incr)
+{
+    void *prev_brk;
+
+    if (incr < 0) {
+        /* Returning memory to the heap. */
+        incr = -incr;
+        if (brk - incr < &__HeapBase) {
+            prev_brk = (void *)-1;
+            errno = EINVAL;
+        } else {
+            prev_brk = brk;
+            brk -= incr;
+        }
+    } else {
+        /* Allocating memory from the heap. */
+        if (&__HeapLimit - brk >= incr) {
+            prev_brk = brk;
+            brk += incr;
+        } else {
+            prev_brk = (void *)-1;
+            errno = ENOMEM;
+        }
+    }
+
+    return prev_brk;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2b268fbe/hw/bsp/nrf52dk/src/system_nrf52.c
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/src/system_nrf52.c b/hw/bsp/nrf52dk/src/system_nrf52.c
new file mode 100644
index 0000000..5a76c42
--- /dev/null
+++ b/hw/bsp/nrf52dk/src/system_nrf52.c
@@ -0,0 +1,183 @@
+/* Copyright (c) 2015, Nordic Semiconductor ASA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice, this
+ *     list of conditions and the following disclaimer.
+ *
+ *   * Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *
+ *   * Neither the name of Nordic Semiconductor ASA nor the names of its
+ *     contributors may be used to endorse or promote products derived from
+ *     this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "bsp/cmsis_nvic.h"
+#include "mcu/nrf.h"
+#include "mcu/system_nrf52.h"
+
+/*lint ++flb "Enter library region" */
+
+#define __SYSTEM_CLOCK_16M      (16000000UL)     
+#define __SYSTEM_CLOCK_64M      (64000000UL)   
+
+static bool ftpan_32(void); 
+static bool ftpan_37(void); 
+static bool ftpan_36(void); 
+
+
+#if defined ( __CC_ARM )
+    uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
+#elif defined ( __ICCARM__ )
+    __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
+#elif defined   ( __GNUC__ )
+    uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
+#endif
+
+void SystemCoreClockUpdate(void)
+{
+    SystemCoreClock = __SYSTEM_CLOCK_64M;
+}
+
+void SystemInit(void)
+{
+    /* Workaround for FTPAN-32 "DIF: Debug session automatically enables TracePort pins" found at Product Anomaly document 
+       for your device located at https://www.nordicsemi.com/ */
+    if (ftpan_32()){        
+        CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
+    }
+    
+    /* Workaround for FTPAN-37 "AMLI: EasyDMA is slow with Radio, ECB, AAR and CCM." found at Product Anomaly document 
+       for your device located at https://www.nordicsemi.com/  */
+    if (ftpan_37()){        
+        *(volatile uint32_t *)0x400005A0 = 0x3;
+    }
+    
+    /* Workaround for FTPAN-36 "CLOCK: Some registers are not reset when expected." found at Product Anomaly document 
+       for your device located at https://www.nordicsemi.com/  */
+    if (ftpan_36()){        
+        NRF_CLOCK->EVENTS_DONE = 0;
+        NRF_CLOCK->EVENTS_CTTO = 0;
+    }
+
+    /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the 
+     * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit 
+     * operations are not used in your code. */
+    #if (__FPU_USED == 1)
+        SCB->CPACR |= (3UL << 20) | (3UL << 22); 
+        __DSB();
+        __ISB();
+    #endif
+    
+    /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, 
+       two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as 
+       normal GPIOs. */
+    #if defined (CONFIG_NFCT_PINS_AS_GPIOS)
+        if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
+            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
+            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}            
+            NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
+            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}            
+            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
+            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}            
+            NVIC_SystemReset();
+        }
+    #endif
+    
+    /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
+      defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be 
+      reserved for PinReset and not available as normal GPIO. */
+    #if defined (CONFIG_GPIO_AS_PINRESET)
+        if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || 
+            ((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
+            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
+            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
+            NRF_UICR->PSELRESET[0] = 21;
+            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
+            NRF_UICR->PSELRESET[1] = 21;
+            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
+            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
+            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
+            NVIC_SystemReset();
+        }
+    #endif
+    
+    /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product 
+       Specification to see which one). */
+    #if defined (ENABLE_SWO)
+        CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+        NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
+    #endif
+    
+    /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product 
+       Specification to see which ones). */
+    #if defined (ENABLE_TRACE)
+        CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+        NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
+    #endif
+
+    SystemCoreClockUpdate();
+
+    NVIC_Relocate();
+}
+
+static bool ftpan_32(void)
+{
+    if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
+    {
+        if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
+        {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+static bool ftpan_37(void)
+{
+    if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
+    {
+        if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
+        {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+static bool ftpan_36(void)
+{
+    if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
+    {
+        if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
+        {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+
+
+/*lint --flb "Leave library region" */


[41/50] [abbrv] incubator-mynewt-core git commit: formatting typos, license pointers

Posted by ma...@apache.org.
formatting typos, license pointers


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

Branch: refs/heads/master
Commit: 4f9a1f840911d8dbffb5e06dcc23f4f3e6e042d9
Parents: 3bdb018
Author: Sterling Hughes <st...@apache.org>
Authored: Sun Apr 24 10:02:26 2016 -0700
Committer: Sterling Hughes <st...@apache.org>
Committed: Sun Apr 24 10:02:26 2016 -0700

----------------------------------------------------------------------
 CODING_STANDARDS.md | 84 ++++++++++++++++++++++++++++++------------------
 1 file changed, 52 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4f9a1f84/CODING_STANDARDS.md
----------------------------------------------------------------------
diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md
index 5d1e5f3..4727f1e 100644
--- a/CODING_STANDARDS.md
+++ b/CODING_STANDARDS.md
@@ -5,6 +5,40 @@ all subprojects of Apache Mynewt.  This covers C and Assembly coding
 conventions, *only*.  Other languages (such as Go), have their own 
 coding conventions.
 
+## Headers
+
+* All files that are newly written, should have the Apache License clause
+at the top of them.
+
+* For files that are copied from another source, but contain an Apache 
+compatible license, the original license header shall be maintained.
+
+* For more information on applying the Apache license, the definitive 
+source is here: http://www.apache.org/dev/apply-license.html
+
+* The Apache License clause for the top of files is as follows:
+
+```no-highlight
+/**
+ * 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.
+ */
+```
+
 ## Whitespace and Braces
 
 * Code must be indented to 4 spaces, tabs should not be used.
@@ -24,7 +58,7 @@ code blocks, i.e., do:
     }
 ```
 
-not: 
+Not: 
 
 ```
     if (x) 
@@ -45,7 +79,7 @@ not:
     }
 ```
 
-Bad:
+Not:
 
 ```
     for (i = 0; i < 10; i++) 
@@ -81,14 +115,19 @@ not:
 * When you have to wrap a long statement, put the operator at the end of the 
   line.  i.e.:
 
+```
     if (x &&
         y == 10 &&
         b)
-  Not:
+```
+
+Not:
 
+```
     if (x
         && y == 10
         && b)
+```
 
 ## Comments
 
@@ -97,12 +136,16 @@ not:
 * When using a single line comment, put it above the line of code that you 
 intend to comment, i.e., do:
 
+```
     /* check variable */
     if (a) {
+```
 
-and not: 
+Not:
 
+```
     if (a) { /* check variable */
+```
 
 
 * All public APIs should be commented with Doxygen style comments describing 
@@ -112,35 +155,12 @@ purpose, parameters and return values.  Private APIs need not be documented.
 ## Header files
 
 * Header files must contain the following structure:
-    * Apache License
+    * Apache License (see above)
     * ```#ifdef``` aliasing, to prevent multiple includes
     * ```#include``` directives for other required header files
     * ```#ifdef __cplusplus``` wrappers to maintain C++ friendly APIs
     * Contents of the header file
 
-* The Apache License clause is as follows:
-
-```no-highlight
-/**
- * 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.
- */
-```
-
 * ```#ifdef``` aliasing, shall be in the following format, where
 the package name is "os" and the file name is "callout.h": 
 
@@ -174,7 +194,7 @@ followed by the '_' character, i.e.:
     os_callout_init(&c)
 ```
 
-not:
+Not:
 
 ```
     callout_init(c)
@@ -188,7 +208,7 @@ not:
     rc = function(a)
 ```
 
-not: 
+Not: 
 
 ```
     rc = function (a)
@@ -201,7 +221,7 @@ not:
     rc = function(a, b)
 ```
 
-not: 
+Not: 
 
 ```
     rc = function(a,b)
@@ -215,7 +235,7 @@ not:
     {
 ```
 
-not: 
+Not: 
 
 ```
     static void *function(int var1, int var2)


[17/50] [abbrv] incubator-mynewt-core git commit: Fix gratuitous newline deletion.

Posted by ma...@apache.org.
Fix gratuitous newline deletion.


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

Branch: refs/heads/master
Commit: dc1594897cbc22e4620e103e5b5d4ef03cbea5ed
Parents: 3eb0cfb
Author: Neel Natu <ne...@nahannisys.com>
Authored: Tue Apr 19 18:29:48 2016 -0700
Committer: Neel Natu <ne...@nahannisys.com>
Committed: Tue Apr 19 18:29:48 2016 -0700

----------------------------------------------------------------------
 libs/os/src/arch/sim/os_arch_sim.c | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/dc159489/libs/os/src/arch/sim/os_arch_sim.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/sim/os_arch_sim.c b/libs/os/src/arch/sim/os_arch_sim.c
index 50b6663..14316c5 100644
--- a/libs/os/src/arch/sim/os_arch_sim.c
+++ b/libs/os/src/arch/sim/os_arch_sim.c
@@ -363,6 +363,7 @@ timer_handler(int sig)
         time_diff.tv_sec = 0;
         time_diff.tv_usec %= OS_USEC_PER_TICK;
         timersub(&time_now, &time_diff, &time_last);
+
         os_time_advance(ticks);
     }
 }


[13/50] [abbrv] incubator-mynewt-core git commit: ble host - major changes.

Posted by ma...@apache.org.
ble host - major changes.

These changes are detailed in this thread on the mynewt dev list:
http://mail-archives.apache.org/mod_mbox/incubator-mynewt-dev/201604.mbox/%3C20160417225734.GB8991%40iori.nightmare-heaven.no-ip.biz%3E

Here is a summary of the changes:

1. All HCI command/acknowledgement exchanges are blocking.

    * FSM machinery goes away; controller response is indicated in the
      return code of the HCI send function.
    * Nearly all HCI failures are indicated to the application
      immediately, so there is no need for lots of mutexes and temporary
      copies of data structures.
    * API is simplified; operation results are indicated via a simple
      function return code.

2. The Nimble host is "taskless"

the Nimble host is now a "flat" library that runs in an application
task.  When the application initializes the host, it indicates which OS
event queue should be used for host-related events.  Host operations are
captured in OS_EVENT_TIMER events that the application task would need
to handle generically, as it most likely already does.


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

Branch: refs/heads/master
Commit: e32f9f9f20666ecbb42598db0737b9c8f1ca6c74
Parents: f6bc99f
Author: Christopher Collins <cc...@apache.org>
Authored: Tue Apr 12 11:31:14 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Apr 19 17:52:53 2016 -0700

----------------------------------------------------------------------
 apps/bletiny/src/main.c                        |    8 +-
 net/nimble/host/include/host/ble_gatt.h        |   14 +-
 net/nimble/host/include/host/ble_hs.h          |    7 +-
 net/nimble/host/include/host/ble_l2cap.h       |    1 +
 net/nimble/host/include/host/host_hci.h        |   20 +-
 net/nimble/host/src/ble_att.c                  |    7 +-
 net/nimble/host/src/ble_att_clt.c              |   24 +-
 net/nimble/host/src/ble_att_svr.c              |   28 +-
 net/nimble/host/src/ble_fsm.c                  |  530 ----
 net/nimble/host/src/ble_fsm_priv.h             |   88 -
 net/nimble/host/src/ble_gap.c                  | 1146 +++-----
 net/nimble/host/src/ble_gatt_priv.h            |    1 -
 net/nimble/host/src/ble_gattc.c                | 2690 +++++++------------
 net/nimble/host/src/ble_gatts.c                |    8 +-
 net/nimble/host/src/ble_hci_block.c            |  229 --
 net/nimble/host/src/ble_hci_sched.c            |  474 ----
 net/nimble/host/src/ble_hci_sched.h            |   47 -
 net/nimble/host/src/ble_hci_util.c             |   78 +
 net/nimble/host/src/ble_hci_util.h             |   26 +
 net/nimble/host/src/ble_hs.c                   |  179 +-
 net/nimble/host/src/ble_hs_atomic.c            |   45 +
 net/nimble/host/src/ble_hs_atomic.h            |   25 +
 net/nimble/host/src/ble_hs_cfg.c               |    1 -
 net/nimble/host/src/ble_hs_conn.c              |  120 +-
 net/nimble/host/src/ble_hs_conn.h              |    6 +-
 net/nimble/host/src/ble_hs_misc.c              |   10 +-
 net/nimble/host/src/ble_hs_priv.h              |   44 +-
 net/nimble/host/src/ble_hs_startup.c           |  213 +-
 net/nimble/host/src/ble_ibeacon.c              |    9 +-
 net/nimble/host/src/ble_l2cap_priv.h           |    3 +-
 net/nimble/host/src/ble_l2cap_sig.c            |  439 +--
 net/nimble/host/src/ble_l2cap_sig_cmd.c        |    4 +-
 net/nimble/host/src/ble_l2cap_sm.c             | 1142 +++-----
 net/nimble/host/src/ble_l2cap_sm.h             |    9 +-
 net/nimble/host/src/ble_l2cap_sm_cmd.c         |   13 +-
 net/nimble/host/src/host_hci.c                 |  356 ++-
 net/nimble/host/src/host_hci_cmd.c             |  240 +-
 net/nimble/host/src/test/ble_gap_test.c        |  155 +-
 net/nimble/host/src/test/ble_gatt_conn_test.c  |   50 +-
 net/nimble/host/src/test/ble_gatt_read_test.c  |   55 +-
 net/nimble/host/src/test/ble_gatt_write_test.c |    9 +-
 net/nimble/host/src/test/ble_host_hci_test.c   |  133 -
 net/nimble/host/src/test/ble_hs_conn_test.c    |   69 -
 net/nimble/host/src/test/ble_hs_test.c         |   27 +-
 net/nimble/host/src/test/ble_hs_test_util.c    |  149 +-
 net/nimble/host/src/test/ble_hs_test_util.h    |   13 +-
 net/nimble/host/src/test/ble_l2cap_sm_test.c   |   30 +-
 net/nimble/host/src/test/ble_l2cap_test.c      |   12 +-
 net/nimble/host/src/test/ble_os_test.c         |   99 +-
 net/nimble/include/nimble/hci_common.h         |    2 +-
 50 files changed, 2956 insertions(+), 6131 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index 20efe2f..2cec311 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -47,7 +47,6 @@
  * app uses some of nimble's internal details for logging.
  */
 #include "../src/ble_hs_conn.h"
-#include "../src/ble_hci_sched.h"
 
 #define BSWAP16(x)  ((uint16_t)(((x) << 8) | (((x) & 0xff00) >> 8)))
 
@@ -978,6 +977,7 @@ bletiny_on_scan(int event, int status, struct ble_gap_disc_desc *desc,
     }
 }
 
+#if 0
 static void
 bletiny_on_rx_rssi(struct ble_hci_ack *ack, void *unused)
 {
@@ -996,6 +996,7 @@ bletiny_on_rx_rssi(struct ble_hci_ack *ack, void *unused)
     console_printf("rssi response received; status=%d conn=%d rssi=%d\n",
                    params.status, params.connection_handle, params.rssi);
 }
+#endif
 
 int
 bletiny_exchange_mtu(uint16_t conn_handle)
@@ -1267,6 +1268,7 @@ bletiny_l2cap_update(uint16_t conn_handle,
     return rc;
 }
 
+#if 0
 static int
 bletiny_tx_rssi_req(void *arg)
 {
@@ -1285,10 +1287,12 @@ bletiny_tx_rssi_req(void *arg)
 
     return 0;
 }
+#endif
 
 int
 bletiny_show_rssi(uint16_t conn_handle)
 {
+#if 0
     int rc;
 
     rc = ble_hci_sched_enqueue(bletiny_tx_rssi_req,
@@ -1298,8 +1302,8 @@ bletiny_show_rssi(uint16_t conn_handle)
         return rc;
     }
 
+#endif
     return 0;
-
 }
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/include/host/ble_gatt.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gatt.h b/net/nimble/host/include/host/ble_gatt.h
index d147cdf..73d73e5 100644
--- a/net/nimble/host/include/host/ble_gatt.h
+++ b/net/nimble/host/include/host/ble_gatt.h
@@ -68,12 +68,6 @@ typedef int ble_gatt_disc_svc_fn(uint16_t conn_handle,
 typedef int ble_gatt_attr_fn(uint16_t conn_handle,
                              struct ble_gatt_error *error,
                              struct ble_gatt_attr *attr, void *arg);
-typedef int ble_gatt_mult_attr_fn(uint16_t conn_handle,
-                                  struct ble_gatt_error *error,
-                                  uint16_t *attr_handles,
-                                  uint8_t num_attr_handles,
-                                  uint8_t *attr_data, uint16_t attr_data_len,
-                                  void *arg);
 typedef int ble_gatt_reliable_attr_fn(uint16_t conn_handle,
                                       struct ble_gatt_error *error,
                                       struct ble_gatt_attr *attrs,
@@ -112,11 +106,10 @@ int ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle,
 int ble_gattc_read_long(uint16_t conn_handle, uint16_t handle,
                         ble_gatt_attr_fn *cb, void *cb_arg);
 int ble_gattc_read_mult(uint16_t conn_handle, uint16_t *handles,
-                        uint8_t num_handles, ble_gatt_mult_attr_fn *cb,
+                        uint8_t num_handles, ble_gatt_attr_fn *cb,
                         void *cb_arg);
 int ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
-                           void *value, uint16_t value_len,
-                           ble_gatt_attr_fn *cb, void *cb_arg);
+                           void *value, uint16_t value_len);
 int ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, void *value,
                     uint16_t value_len, ble_gatt_attr_fn *cb, void *cb_arg);
 int ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle,
@@ -136,7 +129,8 @@ int ble_gattc_write_long_dsc(uint16_t conn_handle, uint16_t attr_handle,
                              void *value, uint16_t value_len,
                              ble_gatt_attr_fn *cb, void *cb_arg);
 int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle);
-int ble_gattc_notify_custom(uint16_t conn_handle, struct ble_gatt_attr *attr);
+int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle,
+                            void *attr_data, uint16_t attr_data_len);
 
 int ble_gattc_init(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 dfffc97..72cde41 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -28,6 +28,8 @@
 #include "host/ble_hs_test.h"
 #include "host/ble_uuid.h"
 #include "host/host_hci.h"
+struct os_eventq;
+struct os_event;
 
 #define BLE_HS_CONN_HANDLE_NONE     0xffff
 
@@ -69,7 +71,6 @@
 struct ble_hs_cfg {
     /** HCI settings. */
     uint8_t max_hci_bufs;
-    uint8_t max_hci_tx_slots;
 
     /** Connection settings. */
     uint16_t max_outstanding_pkts_per_conn;
@@ -105,7 +106,9 @@ struct ble_hs_cfg {
 
 extern const struct ble_hs_cfg ble_hs_cfg_dflt;
 
+int ble_hs_start(void);
+void ble_hs_event_enqueue(struct os_event *ev);
 int ble_ibeacon_set_adv_data(void *uuid128, uint16_t major, uint16_t minor);
-int ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg);
+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/e32f9f9f/net/nimble/host/include/host/ble_l2cap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_l2cap.h b/net/nimble/host/include/host/ble_l2cap.h
index 01e25a6..b25e163 100644
--- a/net/nimble/host/include/host/ble_l2cap.h
+++ b/net/nimble/host/include/host/ble_l2cap.h
@@ -80,6 +80,7 @@ struct ble_hs_conn;
 #define BLE_L2CAP_SM_ERR_NUM_CMP            0x0c
 #define BLE_L2CAP_SM_ERR_ALREADY            0x0d
 #define BLE_L2CAP_SM_ERR_CROSS_TRANS        0x0e
+#define BLE_L2CAP_SM_ERR_MAX_PLUS_1         0x0f
 
 #define BLE_L2CAP_SM_PAIR_ALG_JW            0
 #define BLE_L2CAP_SM_PAIR_ALG_PASSKEY       1

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 97db9ff..1a15f01 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -30,6 +30,8 @@ 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, void *cmddata);
 int host_hci_cmd_send_buf(void *cmddata);
+void host_hci_cmd_build_set_event_mask(uint64_t event_mask,
+                                       uint8_t *dst, int dst_len);
 int host_hci_cmd_set_event_mask(uint64_t event_mask);
 void host_hci_cmd_build_disconnect(uint16_t handle, uint8_t reason,
                                    uint8_t *dst, int dst_len);
@@ -52,8 +54,12 @@ int host_hci_cmd_build_le_set_adv_params(struct hci_adv_params *adv,
                                          uint8_t *dst, int dst_len);
 int host_hci_cmd_le_set_adv_params(struct hci_adv_params *adv);
 int host_hci_cmd_le_set_rand_addr(uint8_t *addr);
+void host_hci_cmd_build_le_set_event_mask(uint64_t event_mask,
+                                          uint8_t *dst, int dst_len);
 int host_hci_cmd_le_set_event_mask(uint64_t event_mask);
+void host_hci_cmd_build_le_read_buffer_size(uint8_t *dst, int dst_len);
 int host_hci_cmd_le_read_buffer_size(void);
+void host_hci_cmd_build_le_read_loc_supp_feat(uint8_t *dst, uint8_t dst_len);
 int host_hci_cmd_le_read_loc_supp_feat(void);
 int host_hci_cmd_le_read_rem_used_feat(uint16_t handle);
 void host_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst,
@@ -76,13 +82,14 @@ int host_hci_cmd_le_set_scan_enable(uint8_t enable, uint8_t filter_dups);
 int host_hci_cmd_build_le_create_connection(struct hci_create_conn *hcc,
                                             uint8_t *cmd, int cmd_len);
 int host_hci_cmd_le_create_connection(struct hci_create_conn *hcc);
-void host_hci_cmd_le_build_clear_whitelist(uint8_t *dst, int dst_len);
+void host_hci_cmd_build_le_clear_whitelist(uint8_t *dst, int dst_len);
 int host_hci_cmd_le_clear_whitelist(void);
 int host_hci_cmd_le_read_whitelist(void);
 int host_hci_cmd_build_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type,
                                            uint8_t *dst, int dst_len);
 int host_hci_cmd_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type);
 int host_hci_cmd_le_rmv_from_whitelist(uint8_t *addr, uint8_t addr_type);
+void host_hci_cmd_build_reset(uint8_t *dst, int dst_len);
 int host_hci_cmd_reset(void);
 void host_hci_cmd_build_read_adv_pwr(uint8_t *dst, int dst_len);
 int host_hci_cmd_read_adv_pwr(void);
@@ -91,9 +98,15 @@ int host_hci_cmd_le_create_conn_cancel(void);
 int host_hci_cmd_build_le_conn_update(struct hci_conn_update *hcu,
                                       uint8_t *dst, int dst_len);
 int host_hci_cmd_le_conn_update(struct hci_conn_update *hcu);
+void host_hci_cmd_build_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr,
+                                            uint8_t *dst, int dst_len);
 int host_hci_cmd_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr);
 int host_hci_cmd_le_lt_key_req_neg_reply(uint16_t handle);
+void host_hci_cmd_build_le_conn_param_reply(struct hci_conn_param_reply *hcr,
+                                            uint8_t *dst, int dst_len);
 int host_hci_cmd_le_conn_param_reply(struct hci_conn_param_reply *hcr);
+void host_hci_cmd_build_le_conn_param_neg_reply(
+    struct hci_conn_param_neg_reply *hcn, uint8_t *dst, int dst_len);
 int host_hci_cmd_le_conn_param_neg_reply(struct hci_conn_param_neg_reply *hcn);
 int host_hci_cmd_le_read_supp_states(void);
 int host_hci_cmd_le_read_max_datalen(void);
@@ -102,7 +115,10 @@ int host_hci_cmd_le_write_sugg_datalen(uint16_t txoctets, uint16_t txtime);
 int host_hci_cmd_le_set_datalen(uint16_t handle, uint16_t txoctets,
                                 uint16_t txtime);
 int host_hci_cmd_le_encrypt(uint8_t *key, uint8_t *pt);
+void host_hci_cmd_build_le_rand(uint8_t *dst, int dst_len);
 int host_hci_cmd_le_rand(void);
+void host_hci_cmd_build_le_start_encrypt(struct hci_start_encrypt *cmd,
+                                         uint8_t *dst, int dst_len);
 int host_hci_cmd_le_start_encrypt(struct hci_start_encrypt *cmd);
 int host_hci_set_buf_size(uint16_t pktlen, uint8_t max_pkts);
 
@@ -114,6 +130,4 @@ int host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *om);
 void host_hci_timer_set(void);
 void host_hci_init(void);
 
-extern uint16_t host_hci_outstanding_opcode;
-
 #endif /* H_HOST_HCI_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att.c b/net/nimble/host/src/ble_att.c
index c9fa0bb..74679f7 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -396,9 +396,6 @@ ble_att_inc_rx_stat(uint8_t att_op)
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 uint16_t
 ble_att_mtu(uint16_t conn_handle)
 {
@@ -406,7 +403,7 @@ ble_att_mtu(uint16_t conn_handle)
     struct ble_hs_conn *conn;
     uint16_t mtu;
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     ble_att_conn_chan_find(conn_handle, &conn, &chan);
     if (chan != NULL) {
@@ -415,7 +412,7 @@ ble_att_mtu(uint16_t conn_handle)
         mtu = 0;
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     return mtu;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_att_clt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_clt.c b/net/nimble/host/src/ble_att_clt.c
index 575399d..19af956 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -117,10 +117,6 @@ ble_att_clt_copy_attr_to_flatbuf(struct os_mbuf *om, void **out_attr_val,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
 {
@@ -131,19 +127,15 @@ ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
     BLE_HS_DBG_ASSERT_EVAL(txom->om_len >= 1);
     ble_att_inc_tx_stat(txom->om_data[0]);
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
     if (rc == 0) {
-        if (!ble_hs_conn_can_tx(conn)) {
-            rc = BLE_HS_ECONGESTED;
-        } else {
-            rc = ble_l2cap_tx(conn, chan, txom);
-            txom = NULL;
-        }
+        rc = ble_l2cap_tx(conn, chan, txom);
+        txom = NULL;
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     os_mbuf_free_chain(txom);
     return rc;
@@ -233,14 +225,14 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, struct ble_att_mtu_cmd *req)
         return rc;
     }
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
     if (rc == 0) {
         chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     return rc;
 }
@@ -263,7 +255,7 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
     if (rc == 0) {
         ble_att_mtu_cmd_parse((*om)->om_data, (*om)->om_len, &rsp);
 
-        ble_hs_conn_lock();
+        ble_hs_lock();
 
         rc = ble_att_conn_chan_find(conn_handle, NULL, &chan);
         if (rc == 0) {
@@ -271,7 +263,7 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
             mtu = ble_l2cap_chan_mtu(chan);
         }
 
-        ble_hs_conn_unlock();
+        ble_hs_unlock();
     }
 
     ble_gattc_rx_mtu(conn_handle, rc, mtu);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index aadab63..8f647e2 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -240,8 +240,6 @@ ble_att_svr_read(uint16_t conn_handle, struct ble_att_svr_entry *entry,
     uint8_t att_err;
     int rc;
 
-    ble_hs_misc_assert_no_locks();
-
     if (conn_handle != BLE_HS_CONN_HANDLE_NONE &&
         !(entry->ha_flags & HA_FLAG_PERM_READ)) {
 
@@ -312,7 +310,7 @@ ble_att_svr_write(uint16_t conn_handle, struct ble_att_svr_entry *entry,
     uint8_t att_err;
     int rc;
 
-    BLE_HS_DBG_ASSERT(!ble_hs_conn_locked_by_cur_task());
+    ble_hs_misc_assert_not_locked();
 
     if (conn_handle != BLE_HS_CONN_HANDLE_NONE &&
         !(entry->ha_flags & HA_FLAG_PERM_WRITE)) {
@@ -453,7 +451,7 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
     }
 
     if (do_tx) {
-        ble_hs_conn_lock();
+        ble_hs_lock();
 
         ble_att_conn_chan_find(conn_handle, &conn, &chan);
         if (chan == NULL) {
@@ -476,7 +474,7 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
             }
         }
 
-        ble_hs_conn_unlock();
+        ble_hs_unlock();
     }
 
     os_mbuf_free_chain(txom);
@@ -501,12 +499,12 @@ ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct os_mbuf **out_txom,
     *att_err = 0; /* Silence unnecessary warning. */
     txom = NULL;
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
     rc = ble_att_conn_chan_find(conn_handle, NULL, &chan);
     if (rc == 0) {
         mtu = chan->blc_my_mtu;
     }
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     if (rc != 0) {
         goto done;
@@ -570,13 +568,13 @@ done:
     rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_FIND_INFO_REQ,
                             att_err, 0);
     if (rc == 0) {
-        ble_hs_conn_lock();
+        ble_hs_lock();
         ble_att_conn_chan_find(conn_handle, &conn, &chan);
         if (chan != NULL) {
             ble_att_set_peer_mtu(chan, cmd.bamc_mtu);
             chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
         }
-        ble_hs_conn_unlock();
+        ble_hs_unlock();
     }
     return rc;
 }
@@ -2435,7 +2433,7 @@ ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom)
     prep_entry->bape_handle = req.bapc_handle;
     prep_entry->bape_offset = req.bapc_offset;
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     conn = ble_hs_conn_find(conn_handle);
     if (conn == NULL) {
@@ -2466,7 +2464,7 @@ ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom)
         }
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     if (rc != 0) {
         goto done;
@@ -2491,7 +2489,7 @@ ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom)
 
 done:
     if (rc != 0 && rc != BLE_HS_ENOTCONN) {
-        ble_hs_conn_lock();
+        ble_hs_lock();
 
         conn = ble_hs_conn_find(conn_handle);
         if (conn == NULL) {
@@ -2510,7 +2508,7 @@ done:
             }
         }
 
-        ble_hs_conn_unlock();
+        ble_hs_unlock();
     }
 
     rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_PREP_WRITE_REQ,
@@ -2597,7 +2595,7 @@ ble_att_svr_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
 
 done:
     if (rc == 0) {
-        ble_hs_conn_lock();
+        ble_hs_lock();
         conn = ble_hs_conn_find(conn_handle);
         if (conn == NULL) {
             rc = BLE_HS_ENOTCONN;
@@ -2613,7 +2611,7 @@ done:
             /* Erase all prep entries. */
             ble_att_svr_prep_clear(&conn->bhc_att_svr);
         }
-        ble_hs_conn_unlock();
+        ble_hs_unlock();
     }
 
     rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_EXEC_WRITE_REQ,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_fsm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_fsm.c b/net/nimble/host/src/ble_fsm.c
deleted file mode 100644
index e6edd28..0000000
--- a/net/nimble/host/src/ble_fsm.c
+++ /dev/null
@@ -1,530 +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.
- */
-
-#include <stddef.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include "os/os_mempool.h"
-#include "nimble/ble.h"
-#include "host/ble_uuid.h"
-#include "host/ble_gap.h"
-#include "ble_hs_priv.h"
-
-/*****************************************************************************
- * $mutex                                                                    *
- *****************************************************************************/
-
-void
-ble_fsm_lock(struct ble_fsm *fsm)
-{
-    struct os_task *owner;
-    int rc;
-
-    owner = fsm->mutex.mu_owner;
-    if (owner != NULL) {
-        BLE_HS_DBG_ASSERT_EVAL(owner != os_sched_get_current_task());
-    }
-
-    rc = os_mutex_pend(&fsm->mutex, 0xffffffff);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-void
-ble_fsm_unlock(struct ble_fsm *fsm)
-{
-    int rc;
-
-    rc = os_mutex_release(&fsm->mutex);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-int
-ble_fsm_locked_by_cur_task(struct ble_fsm *fsm)
-{
-    struct os_task *owner;
-
-    owner = fsm->mutex.mu_owner;
-    return owner != NULL && owner == os_sched_get_current_task();
-}
-
-/*****************************************************************************
- * $debug                                                                    *
- *****************************************************************************/
-
-/**
- * Ensures all procedure entries are in a valid state.
- *
- * Lock restrictions:
- *     o Caller locks fsm.
- */
-static void
-ble_fsm_assert_sanity(struct ble_fsm *fsm)
-{
-#if !BLE_HS_DEBUG
-    return;
-#endif
-
-    struct ble_fsm_proc *proc;
-    unsigned mask;
-    int num_set;
-
-    STAILQ_FOREACH(proc, &fsm->procs, next) {
-        /* Ensure exactly one flag is set. */
-        num_set = 0;
-        mask = 0x01;
-        while (mask <= UINT8_MAX) {
-            if (proc->flags & mask) {
-                num_set++;
-            }
-            mask <<= 1;
-        }
-
-        BLE_HS_DBG_ASSERT(num_set == 1);
-    }
-}
-
-/*****************************************************************************
- * $proc                                                                     *
- *****************************************************************************/
-
-/**
- * Removes the specified proc entry from a list without freeing it.
- *
- * Lock restrictions:
- *     o Caller locks fsm if the source list is fsm->procs.
- *
- * @param src_list              The list to remove the proc from.
- * @param proc                  The proc to remove.
- * @param prev                  The proc that is previous to "proc" in the
- *                                  list; null if "proc" is the list head.
- */
-void
-ble_fsm_proc_remove(struct ble_fsm_proc_list *src_list,
-                    struct ble_fsm_proc *proc,
-                    struct ble_fsm_proc *prev)
-{
-    if (prev == NULL) {
-        BLE_HS_DBG_ASSERT(STAILQ_FIRST(src_list) == proc);
-        STAILQ_REMOVE_HEAD(src_list, next);
-    } else {
-        BLE_HS_DBG_ASSERT(STAILQ_NEXT(prev, next) == proc);
-        STAILQ_NEXT(prev, next) = STAILQ_NEXT(proc, next);
-    }
-}
-
-/**
- * Concatenates the specified list onto the end of the main proc list.
- *
- * Lock restrictions:
- *     o Caller unlocks fsm.
- */
-void
-ble_fsm_proc_concat(struct ble_fsm *fsm, struct ble_fsm_proc_list *tail_list)
-{
-    struct ble_fsm_proc *proc;
-
-    if (!STAILQ_EMPTY(tail_list)) {
-        ble_fsm_lock(fsm);
-
-        if (STAILQ_EMPTY(&fsm->procs)) {
-            fsm->procs = *tail_list;
-        } else {
-            proc = STAILQ_LAST(&fsm->procs, ble_fsm_proc, next);
-            STAILQ_NEXT(proc, next) = STAILQ_FIRST(tail_list);
-            fsm->procs.stqh_last = tail_list->stqh_last;
-        }
-
-        ble_fsm_unlock(fsm);
-    }
-}
-
-/**
- * Determines if the specified proc entry's "pending" flag can be set.
- *
- * Lock restrictions: None.
- */
-int
-ble_fsm_proc_can_pend(struct ble_fsm_proc *proc)
-{
-    return !(proc->flags & (BLE_FSM_PROC_F_CONGESTED    |
-                            BLE_FSM_PROC_F_NO_MEM       |
-                            BLE_FSM_PROC_F_EXPECTING));
-}
-
-/**
- * Sets the specified proc entry's "pending" flag (i.e., indicates that the
- * FSM procedure is stalled until it transmits its next packet).
- *
- * Lock restrictions:
- *     o Caller locks fsm.
- */
-void
-ble_fsm_proc_set_pending(struct ble_fsm_proc *proc)
-{
-    BLE_HS_DBG_ASSERT(!(proc->flags & BLE_FSM_PROC_F_PENDING));
-
-    proc->flags &= ~BLE_FSM_PROC_F_EXPECTING;
-    proc->flags |= BLE_FSM_PROC_F_PENDING;
-}
-
-/**
- * Sets the specified proc entry's "expecting" flag (i.e., indicates that the
- * FSM procedure is stalled until it receives a packet).
- *
- * Lock restrictions: None.
- */
-static void
-ble_fsm_proc_set_expecting(struct ble_fsm_proc *proc)
-{
-    BLE_HS_DBG_ASSERT(!(proc->flags & BLE_FSM_PROC_F_EXPECTING));
-
-    proc->flags &= ~BLE_FSM_PROC_F_PENDING;
-    proc->flags |= BLE_FSM_PROC_F_EXPECTING;
-    proc->tx_time = os_time_get();
-}
-
-/**
- * Postpones tx for the specified proc entry if appropriate.  The determination
- * of whether tx should be postponed is based on the return code of the
- * previous transmit attempt.  This function should be called immediately after
- * transmission fails.  A tx can be postponed if the failure was caused by
- * congestion or memory exhaustion.  All other failures cannot be postponed,
- * and the procedure should be aborted entirely.
- *
- * Lock restrictions: None.
- *
- * @param proc                  The proc entry to check for postponement.
- * @param rc                    The return code of the previous tx attempt.
- *
- * @return                      1 if the transmit should be postponed; else 0.
- */
-int
-ble_fsm_tx_postpone_chk(struct ble_fsm_proc *proc, int rc)
-{
-    switch (rc) {
-    case BLE_HS_ECONGESTED:
-        proc->flags |= BLE_FSM_PROC_F_CONGESTED;
-        return 1;
-
-    case BLE_HS_ENOMEM:
-        proc->flags |= BLE_FSM_PROC_F_NO_MEM;
-        return 1;
-
-    default:
-        return 0;
-    }
-}
-
-/**
- * Called after an incoming packet is done being processed.  If the status of
- * the response processing is 0, the proc entry is re-inserted into the main
- * proc list.  Otherwise, the proc entry is freed.
- *
- * Lock restrictions:
- *     o Caller unlocks fsm.
- */
-void
-ble_fsm_process_rx_status(struct ble_fsm *fsm, struct ble_fsm_proc *proc,
-                          int status)
-{
-    if (status != 0) {
-        fsm->free_cb(proc);
-    } else {
-        ble_fsm_lock(fsm);
-        STAILQ_INSERT_HEAD(&fsm->procs, proc, next);
-        ble_fsm_unlock(fsm);
-    }
-}
-
-/**
- * Searches an fsm's proc list for the first entry that that fits a custom set
- * of criteria.  The supplied callback is applied to each entry in the list
- * until it indicates a match.  If a matching entry is found, it is removed
- * from the list and returned.
- *
- * Lock restrictions:
- *     o Caller unlocks fsm.
- *
- * @param fsm                   The fsm whose list should be searched.
- * @param out_proc              On success, the address of the matching proc is
- *                                  written here.
- * @extract_cb                  The callback to apply to each proc entry.
- * @arg                         An argument that gets passed to each invocation
- *                                  of the callback.
- *
- * @return                      The matching proc entry on success;
- *                                  null on failure.
- */
-int
-ble_fsm_proc_extract(struct ble_fsm *fsm,
-                     struct ble_fsm_proc **out_proc,
-                     ble_fsm_extract_fn *extract_cb, void *arg)
-{
-    struct ble_fsm_proc *prev;
-    struct ble_fsm_proc *proc;
-    int rc;
-
-    ble_fsm_lock(fsm);
-
-    ble_fsm_assert_sanity(fsm);
-
-    prev = NULL;
-
-    STAILQ_FOREACH(proc, &fsm->procs, next) {
-        rc = extract_cb(proc, arg);
-        switch (rc) {
-        case BLE_FSM_EXTRACT_EMOVE_CONTINUE:
-        case BLE_FSM_EXTRACT_EMOVE_STOP:
-            ble_fsm_proc_remove(&fsm->procs, proc, prev);
-            *out_proc = proc;
-            rc = 0;
-            goto done;
-
-        case BLE_FSM_EXTRACT_EKEEP_CONTINUE:
-            break;
-
-        case BLE_FSM_EXTRACT_EKEEP_STOP:
-            rc = 1;
-            goto done;
-
-        default:
-            BLE_HS_DBG_ASSERT(0);
-            rc = 1;
-            goto done;
-        }
-
-        prev = proc;
-    }
-
-    rc = 1;
-
-done:
-    ble_fsm_unlock(fsm);
-    return rc;
-}
-
-/**
- * Searches an fsm's proc list for all entries that that fits a custom set of
- * criteria.  The supplied callback is applied to each entry in the list to
- * determine if it matches. Each matching entry is removed from the list and
- * inserted into a secondary list.
- *
- * Lock restrictions:
- *     o Caller unlocks fsm.
- *
- * @param fsm                   The fsm whose list should be searched.
- * @param dst_list              Matching procs get appended to this list.
- * @extract_cb                  The callback to apply to each proc entry.
- * @arg                         An argument that gets passed to each invocation
- *                                  of the callback.
- *
- * @return                      The number of matching procs (i.e., the size of
- *                                  the destination list).
- */
-int
-ble_fsm_proc_extract_list(struct ble_fsm *fsm,
-                          struct ble_fsm_proc_list *dst_list,
-                          ble_fsm_extract_fn *extract_cb, void *arg)
-{
-    struct ble_fsm_proc *prev;
-    struct ble_fsm_proc *proc;
-    struct ble_fsm_proc *next;
-    int move;
-    int done;
-    int cnt;
-    int rc;
-
-    STAILQ_INIT(dst_list);
-    cnt = 0;
-
-    ble_fsm_lock(fsm);
-
-    ble_fsm_assert_sanity(fsm);
-
-    prev = NULL;
-    proc = STAILQ_FIRST(&fsm->procs);
-    while (proc != NULL) {
-        next = STAILQ_NEXT(proc, next);
-
-        rc = extract_cb(proc, arg);
-        switch (rc) {
-        case BLE_FSM_EXTRACT_EMOVE_CONTINUE:
-            move = 1;
-            done = 0;
-            break;
-
-        case BLE_FSM_EXTRACT_EMOVE_STOP:
-            move = 1;
-            done = 1;
-            break;
-
-        case BLE_FSM_EXTRACT_EKEEP_CONTINUE:
-            move = 0;
-            done = 0;
-            break;
-
-        case BLE_FSM_EXTRACT_EKEEP_STOP:
-            move = 0;
-            done = 1;
-            break;
-
-        default:
-            BLE_HS_DBG_ASSERT(0);
-            move = 0;
-            done = 1;
-            break;
-        }
-
-        if (move) {
-            ble_fsm_proc_remove(&fsm->procs, proc, prev);
-            STAILQ_INSERT_TAIL(dst_list, proc, next);
-            cnt++;
-        } else {
-            prev = proc;
-        }
-
-        if (done) {
-            break;
-        }
-
-        proc = next;
-    }
-
-    ble_fsm_unlock(fsm);
-
-    return cnt;
-}
-
-/**
- * Triggers a transmission for each active FSM procedure with a pending send.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-void
-ble_fsm_wakeup(struct ble_fsm *fsm)
-{
-    struct ble_fsm_proc_list proc_list;
-    struct ble_fsm_proc *proc;
-    struct ble_fsm_proc *prev;
-    struct ble_fsm_proc *next;
-    int rc;
-
-    ble_hs_misc_assert_no_locks();
-
-    STAILQ_INIT(&proc_list);
-
-    /* Remove all procs with pending transmits and insert them into the
-     * temporary list. Once the elements are moved, they can be processed
-     * without keeping the mutex locked.
-     */
-    ble_fsm_lock(fsm);
-
-    prev = NULL;
-    proc = STAILQ_FIRST(&fsm->procs);
-    while (proc != NULL) {
-        next = STAILQ_NEXT(proc, next);
-
-        if (proc->flags & BLE_FSM_PROC_F_PENDING) {
-            ble_fsm_proc_remove(&fsm->procs, proc, prev);
-            STAILQ_INSERT_TAIL(&proc_list, proc, next);
-        } else {
-            prev = proc;
-        }
-
-        proc = next;
-    }
-
-    ble_fsm_unlock(fsm);
-
-    /* Process each of the pending procs. */
-    prev = NULL;
-    proc = STAILQ_FIRST(&proc_list);
-    while (proc != NULL) {
-        next = STAILQ_NEXT(proc, next);
-
-        proc->flags &= ~BLE_FSM_PROC_F_PENDING;
-        rc = fsm->kick_cb(proc);
-        switch (rc) {
-        case 0:
-            /* Transmit succeeded.  Response expected. */
-            ble_fsm_proc_set_expecting(proc);
-
-            /* Current proc remains; reseat prev. */
-            prev = proc;
-            break;
-
-        case BLE_HS_EAGAIN:
-            /* Transmit failed; Reschedule. */
-            /* Current proc remains; reseat prev. */
-            prev = proc;
-            break;
-
-        case BLE_HS_EDONE:
-            /* Procedure complete. */
-            ble_fsm_proc_remove(&proc_list, proc, prev);
-            fsm->free_cb(proc);
-
-            /* Current proc removed; old prev still valid. */
-            break;
-
-        default:
-            BLE_HS_DBG_ASSERT(0);
-            break;
-        }
-
-        proc = next;
-    }
-
-    /* Concatenate the tempororary list to the end of the main list. */
-    ble_fsm_proc_concat(fsm, &proc_list);
-}
-
-/**
- * Initializes an fsm instance.
- *
- * Lock restrictions: none.
- *
- * @return                      0 on success; nonzero on failure.
- */
-int
-ble_fsm_new(struct ble_fsm *fsm, ble_fsm_kick_fn *kick_cb,
-            ble_fsm_free_fn *free_cb)
-{
-    int rc;
-
-    BLE_HS_DBG_ASSERT(kick_cb != NULL);
-    BLE_HS_DBG_ASSERT(free_cb != NULL);
-
-    memset(fsm, 0, sizeof *fsm);
-
-    rc = os_mutex_init(&fsm->mutex);
-    if (rc != 0) {
-        return BLE_HS_EOS;
-    }
-
-    STAILQ_INIT(&fsm->procs);
-
-    fsm->kick_cb = kick_cb;
-    fsm->free_cb = free_cb;
-
-    return 0;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_fsm_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_fsm_priv.h b/net/nimble/host/src/ble_fsm_priv.h
deleted file mode 100644
index cc874c4..0000000
--- a/net/nimble/host/src/ble_fsm_priv.h
+++ /dev/null
@@ -1,88 +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_BLE_FSM_PRIV_
-#define H_BLE_FSM_PRIV_
-
-#include "os/os_mutex.h"
-
-struct ble_fsm_proc {
-    STAILQ_ENTRY(ble_fsm_proc) next;
-
-    uint8_t op;
-    uint8_t flags;
-    uint16_t conn_handle;
-    uint32_t tx_time; /* OS ticks. */
-};
-
-/** Procedure has a tx pending. */
-#define BLE_FSM_PROC_F_PENDING     0x01
-
-/** Procedure currently expects a response. */
-#define BLE_FSM_PROC_F_EXPECTING   0x02
-
-/** Procedure failed to tx due to too many outstanding txes. */
-#define BLE_FSM_PROC_F_CONGESTED   0x04
-
-/** Procedure failed to tx due to memory exhaustion. */
-#define BLE_FSM_PROC_F_NO_MEM      0x08
-
-STAILQ_HEAD(ble_fsm_proc_list, ble_fsm_proc);
-
-typedef int ble_fsm_kick_fn(struct ble_fsm_proc *proc);
-typedef void ble_fsm_free_fn(struct ble_fsm_proc *proc);
-typedef int ble_fsm_extract_fn(struct ble_fsm_proc *proc, void *arg);
-
-#define BLE_FSM_EXTRACT_EMOVE_CONTINUE      0
-#define BLE_FSM_EXTRACT_EMOVE_STOP          1
-#define BLE_FSM_EXTRACT_EKEEP_CONTINUE      2
-#define BLE_FSM_EXTRACT_EKEEP_STOP          3
-
-struct ble_fsm {
-    struct os_mutex mutex;
-    struct ble_fsm_proc_list procs;
-
-    ble_fsm_kick_fn *kick_cb;
-    ble_fsm_free_fn *free_cb;
-};
-
-void ble_fsm_lock(struct ble_fsm *fsm);
-void ble_fsm_unlock(struct ble_fsm *fsm);
-int ble_fsm_locked_by_cur_task(struct ble_fsm *fsm);
-void ble_fsm_proc_remove(struct ble_fsm_proc_list *src_list,
-                         struct ble_fsm_proc *proc,
-                         struct ble_fsm_proc *prev);
-void ble_fsm_proc_concat(struct ble_fsm *fsm,
-                         struct ble_fsm_proc_list *tail_list);
-int ble_fsm_proc_can_pend(struct ble_fsm_proc *proc);
-void ble_fsm_proc_set_pending(struct ble_fsm_proc *proc);
-int ble_fsm_tx_postpone_chk(struct ble_fsm_proc *proc, int rc);
-void ble_fsm_process_rx_status(struct ble_fsm *fsm, struct ble_fsm_proc *proc,
-                               int status);
-int ble_fsm_proc_extract(struct ble_fsm *fsm,
-                         struct ble_fsm_proc **out_proc,
-                         ble_fsm_extract_fn *extract_cb, void *arg);
-int ble_fsm_proc_extract_list(struct ble_fsm *fsm,
-                              struct ble_fsm_proc_list *dst_list,
-                              ble_fsm_extract_fn *extract_cb, void *arg);
-void ble_fsm_wakeup(struct ble_fsm *fsm);
-int ble_fsm_new(struct ble_fsm *fsm, ble_fsm_kick_fn *kick_cb,
-                ble_fsm_free_fn *free_cb);
-
-#endif



[09/50] [abbrv] incubator-mynewt-core git commit: ble host - major changes.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_l2cap_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.c b/net/nimble/host/src/ble_l2cap_sm.c
index d53124f..a2e5785 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -26,18 +26,14 @@
 
 #if NIMBLE_OPT_SM
 
-#define BLE_L2CAP_SM_PROC_OP_NONE               ((uint8_t)-1)
-
-#define BLE_L2CAP_SM_PROC_OP_PAIR               0
-#define BLE_L2CAP_SM_PROC_OP_CONFIRM            1
-#define BLE_L2CAP_SM_PROC_OP_RANDOM             2
-#define BLE_L2CAP_SM_PROC_OP_FAIL               3
-#define BLE_L2CAP_SM_PROC_OP_LTK                4
-#define BLE_L2CAP_SM_PROC_OP_LTK_TXED           5
-#define BLE_L2CAP_SM_PROC_OP_ENC_CHANGE         6
-#define BLE_L2CAP_SM_PROC_OP_START_ENCRYPT      7
-#define BLE_L2CAP_SM_PROC_OP_START_ENCRYPT_TXED 8
-#define BLE_L2CAP_SM_PROC_OP_CNT                9
+#define BLE_L2CAP_SM_PROC_STATE_NONE            ((uint8_t)-1)
+
+#define BLE_L2CAP_SM_PROC_STATE_PAIR            0
+#define BLE_L2CAP_SM_PROC_STATE_CONFIRM         1
+#define BLE_L2CAP_SM_PROC_STATE_RANDOM          2
+#define BLE_L2CAP_SM_PROC_STATE_LTK             3
+#define BLE_L2CAP_SM_PROC_STATE_ENC_CHANGE      4
+#define BLE_L2CAP_SM_PROC_STATE_CNT             5
 
 #define BLE_L2CAP_SM_PROC_F_INITIATOR           0x01
 
@@ -47,10 +43,14 @@
 typedef uint16_t ble_l2cap_sm_proc_flags;
 
 struct ble_l2cap_sm_proc {
-    struct ble_fsm_proc fsm_proc;
+    STAILQ_ENTRY(ble_l2cap_sm_proc) next;
+
     uint32_t exp_os_ticks;
     ble_l2cap_sm_proc_flags flags;
+    uint16_t conn_handle;
     uint8_t pair_alg;
+    uint8_t state;
+
 
     /* XXX: Minimum security requirements. */
 
@@ -66,25 +66,13 @@ struct ble_l2cap_sm_proc {
 
         struct {
             uint8_t key[16];
-            uint8_t handle;
         } hci;
-
-        struct {
-            uint8_t reason;
-        } fail;
     };
 };
 
-/** Used for extracting proc entries from the fsm list. */
-struct ble_l2cap_sm_extract_arg {
-    uint16_t conn_handle;
-    uint8_t op;
-    int8_t initiator; /* 0=no, 1=yes, -1=don't-care. */
-};
-
-typedef int ble_l2cap_sm_kick_fn(struct ble_l2cap_sm_proc *proc);
+STAILQ_HEAD(ble_l2cap_sm_proc_list, ble_l2cap_sm_proc);
 
-typedef int ble_l2cap_sm_rx_fn(uint16_t conn_handle, uint8_t op,
+typedef int ble_l2cap_sm_rx_fn(uint16_t conn_handle, uint8_t state,
                                struct os_mbuf **om);
 
 static ble_l2cap_sm_rx_fn ble_l2cap_sm_rx_noop;
@@ -94,13 +82,6 @@ static ble_l2cap_sm_rx_fn ble_l2cap_sm_rx_pair_confirm;
 static ble_l2cap_sm_rx_fn ble_l2cap_sm_rx_pair_random;
 static ble_l2cap_sm_rx_fn ble_l2cap_sm_rx_pair_fail;
 
-static ble_l2cap_sm_kick_fn ble_l2cap_sm_pair_kick;
-static ble_l2cap_sm_kick_fn ble_l2cap_sm_confirm_kick;
-static ble_l2cap_sm_kick_fn ble_l2cap_sm_random_kick;
-static ble_l2cap_sm_kick_fn ble_l2cap_sm_fail_kick;
-static ble_l2cap_sm_kick_fn ble_l2cap_sm_lt_key_req_kick;
-static ble_l2cap_sm_kick_fn ble_l2cap_sm_start_encrypt_kick;
-
 static ble_l2cap_sm_rx_fn * const ble_l2cap_sm_dispatch[] = {
    [BLE_L2CAP_SM_OP_PAIR_REQ] = ble_l2cap_sm_rx_pair_req,
    [BLE_L2CAP_SM_OP_PAIR_RSP] = ble_l2cap_sm_rx_pair_rsp,
@@ -118,31 +99,24 @@ static ble_l2cap_sm_rx_fn * const ble_l2cap_sm_dispatch[] = {
    [BLE_L2CAP_SM_OP_PAIR_KEYPRESS_NOTIFY] = ble_l2cap_sm_rx_noop,
 };
 
-static ble_l2cap_sm_kick_fn * const
-ble_l2cap_sm_kick[BLE_L2CAP_SM_PROC_OP_CNT] = {
-    [BLE_L2CAP_SM_PROC_OP_PAIR]             = ble_l2cap_sm_pair_kick,
-    [BLE_L2CAP_SM_PROC_OP_CONFIRM]          = ble_l2cap_sm_confirm_kick,
-    [BLE_L2CAP_SM_PROC_OP_RANDOM]           = ble_l2cap_sm_random_kick,
-    [BLE_L2CAP_SM_PROC_OP_FAIL]             = ble_l2cap_sm_fail_kick,
-    [BLE_L2CAP_SM_PROC_OP_LTK]              = ble_l2cap_sm_lt_key_req_kick,
-    [BLE_L2CAP_SM_PROC_OP_START_ENCRYPT]    = ble_l2cap_sm_start_encrypt_kick,
-};
-
-static void ble_l2cap_sm_rx_lt_key_req_reply_ack(struct ble_hci_ack *ack,
-                                                 void *arg);
-static void ble_l2cap_sm_rx_start_encrypt_ack(struct ble_hci_ack *ack,
-                                              void *arg);
-
 static void *ble_l2cap_sm_proc_mem;
 static struct os_mempool ble_l2cap_sm_proc_pool;
 
-static struct ble_fsm ble_l2cap_sm_fsm;
+/* Maintains the list of active security manager procedures. */
+static struct ble_l2cap_sm_proc_list ble_l2cap_sm_procs;
+
+static int ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
+                                             uint8_t *k, uint8_t *preq,
+                                             uint8_t *pres, uint8_t *iat,
+                                             uint8_t *rat, uint8_t *ia,
+                                             uint8_t *ra);
 
 /*****************************************************************************
  * $debug                                                                    *
  *****************************************************************************/
 
 #ifdef BLE_HS_DEBUG
+
 static uint8_t ble_l2cap_sm_dbg_next_pair_rand[16];
 static uint8_t ble_l2cap_sm_dbg_next_pair_rand_set;
 static uint16_t ble_l2cap_sm_dbg_next_ediv;
@@ -175,135 +149,122 @@ ble_l2cap_sm_dbg_set_next_start_rand(uint64_t next_start_rand)
 int
 ble_l2cap_sm_dbg_num_procs(void)
 {
-    struct ble_fsm_proc *proc;
+    struct ble_l2cap_sm_proc *proc;
     int cnt;
 
-    ble_fsm_lock(&ble_l2cap_sm_fsm);
-
     cnt = 0;
-    STAILQ_FOREACH(proc, &ble_l2cap_sm_fsm.procs, next) {
+    STAILQ_FOREACH(proc, &ble_l2cap_sm_procs, next) {
         cnt++;
     }
 
-    ble_fsm_unlock(&ble_l2cap_sm_fsm);
-
     return cnt;
 }
 
 #endif
 
 /*****************************************************************************
- * $mutex                                                                    *
- *****************************************************************************/
-
-int
-ble_l2cap_sm_locked_by_cur_task(void)
-{
-    return ble_fsm_locked_by_cur_task(&ble_l2cap_sm_fsm);
-}
-
-/*****************************************************************************
  * $misc                                                                     *
  *****************************************************************************/
 
-static void
+static int
 ble_l2cap_sm_gen_pair_rand(uint8_t *pair_rand)
 {
+    int rc;
+
 #ifdef BLE_HS_DEBUG
     if (ble_l2cap_sm_dbg_next_pair_rand_set) {
         ble_l2cap_sm_dbg_next_pair_rand_set = 0;
         memcpy(pair_rand, ble_l2cap_sm_dbg_next_pair_rand,
                sizeof ble_l2cap_sm_dbg_next_pair_rand);
-        return;
+        return 0;
     }
 #endif
 
-    /* XXX: Generate random value rather than zeros. */
-    memset(pair_rand, 0, 16);
+    rc = ble_hci_util_rand(pair_rand, 16);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
 }
 
-static uint16_t
-ble_l2cap_sm_gen_ediv(void)
+static int
+ble_l2cap_sm_gen_ediv(uint16_t *ediv)
 {
+    int rc;
+
 #ifdef BLE_HS_DEBUG
     if (ble_l2cap_sm_dbg_next_ediv_set) {
         ble_l2cap_sm_dbg_next_ediv_set = 0;
-        return ble_l2cap_sm_dbg_next_ediv;
+        *ediv = ble_l2cap_sm_dbg_next_ediv;
+        return 0;
     }
 #endif
 
-    /* XXX: Generate random value rather than zero. */
+    rc = ble_hci_util_rand(ediv, sizeof *ediv);
+    if (rc != 0) {
+        return rc;
+    }
+
     return 0;
 }
 
-static uint64_t
-ble_l2cap_sm_gen_start_rand(void)
+static int
+ble_l2cap_sm_gen_start_rand(uint64_t *start_rand)
 {
+    int rc;
+
 #ifdef BLE_HS_DEBUG
     if (ble_l2cap_sm_dbg_next_start_rand_set) {
         ble_l2cap_sm_dbg_next_start_rand_set = 0;
-        return ble_l2cap_sm_dbg_next_start_rand;
+        *start_rand = ble_l2cap_sm_dbg_next_start_rand;
+        return 0;
     }
 #endif
 
-    /* XXX: Generate random value rather than zeros. */
+    rc = ble_hci_util_rand(start_rand, sizeof *start_rand);
+    if (rc != 0) {
+        return rc;
+    }
+
     return 0;
 }
 
 static int
-ble_l2cap_sm_proc_kick(struct ble_fsm_proc *proc)
+ble_l2cap_sm_gen_key(struct ble_l2cap_sm_proc *proc)
 {
-    struct ble_l2cap_sm_proc *sm_proc;
-    ble_l2cap_sm_kick_fn *kick_cb;
+    uint8_t key[16];
     int rc;
 
-    BLE_HS_DBG_ASSERT(proc->op < BLE_L2CAP_SM_PROC_OP_CNT);
-    kick_cb = ble_l2cap_sm_kick[proc->op];
-    BLE_HS_DBG_ASSERT(kick_cb != NULL);
+    rc = ble_l2cap_sm_alg_s1(proc->phase_1_2.tk, proc->phase_1_2.rand_our,
+                             proc->phase_1_2.rand_their, key);
+    if (rc != 0) {
+        return rc;
+    }
 
-    /* Set a timeout of 30 seconds. */
-    sm_proc = (struct ble_l2cap_sm_proc *)proc;
+    memcpy(proc->hci.key, key, sizeof key);
 
-    sm_proc->exp_os_ticks = os_time_get() + BLE_L2CAP_SM_TIMEOUT_OS_TICKS;
-    rc = kick_cb(sm_proc);
+    return 0;
+}
 
-    return rc;
+static void
+ble_l2cap_sm_proc_set_timer(struct ble_l2cap_sm_proc *proc)
+{
+    /* Set a timeout of 30 seconds. */
+    proc->exp_os_ticks = os_time_get() + BLE_L2CAP_SM_TIMEOUT_OS_TICKS;
 }
 
 /**
  * Lock restrictions: None.
  */
 static ble_l2cap_sm_rx_fn *
-ble_l2cap_sm_dispatch_get(uint8_t op)
+ble_l2cap_sm_dispatch_get(uint8_t state)
 {
-    if (op > sizeof ble_l2cap_sm_dispatch / sizeof ble_l2cap_sm_dispatch[0]) {
+    if (state > sizeof ble_l2cap_sm_dispatch / sizeof ble_l2cap_sm_dispatch[0]) {
         return NULL;
     }
 
-    return ble_l2cap_sm_dispatch[op];
-}
-
-/* Indicates the handle of the specified proc's unserviced HCI reservation, if
- * any.  If there is no such handle associated with the proc,
- * BLE_HCI_SCHED_HANDLE_NONE is returned.
- *
- * Lock restrictions: None.
- *
- * @param proc                  The proc object to query.
- *
- * @return                      The HCI handle, or BLE_HCI_SCHED_HANDLE_NONE.
- */
-static uint8_t
-ble_l2cap_sm_proc_outstanding_hci_handle(struct ble_l2cap_sm_proc *proc)
-{
-    switch (proc->fsm_proc.op) {
-    case BLE_L2CAP_SM_PROC_OP_LTK:
-    case BLE_L2CAP_SM_PROC_OP_START_ENCRYPT_TXED:
-        return proc->hci.handle;
-
-    default:
-        return BLE_HCI_SCHED_HANDLE_NONE;
-    }
+    return ble_l2cap_sm_dispatch[state];
 }
 
 /**
@@ -327,269 +288,336 @@ ble_l2cap_sm_proc_alloc(void)
 }
 
 /**
- * Frees the specified proc entry.  No-op if passed a null pointer.
+ * Frees the specified proc entry.  No-state if passed a null pointer.
  *
  * Lock restrictions: None.
  */
 static void
-ble_l2cap_sm_proc_free(struct ble_fsm_proc *proc)
+ble_l2cap_sm_proc_free(struct ble_l2cap_sm_proc *proc)
 {
-    struct ble_l2cap_sm_proc *sm_proc;
-    uint8_t hci_handle;
     int rc;
 
     if (proc != NULL) {
-        sm_proc = (struct ble_l2cap_sm_proc *)proc;
-
-        /* If this proc has an unserviced HCI reservation, cancel it before
-         * freeing the proc.
-         */
-        hci_handle = ble_l2cap_sm_proc_outstanding_hci_handle(sm_proc);
-        if (hci_handle != BLE_HCI_SCHED_HANDLE_NONE) {
-            rc = ble_hci_sched_cancel(hci_handle);
-            BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-        }
-
         rc = os_memblock_put(&ble_l2cap_sm_proc_pool, proc);
         BLE_HS_DBG_ASSERT_EVAL(rc == 0);
     }
 }
 
-/**
- * Lock restrictions: None.
- */
-static int
-ble_l2cap_sm_proc_new(uint16_t conn_handle, uint8_t op,
-                      struct ble_l2cap_sm_proc **out_proc)
+static void
+ble_l2cap_sm_proc_insert(struct ble_l2cap_sm_proc *proc)
 {
-    *out_proc = ble_l2cap_sm_proc_alloc();
-    if (*out_proc == NULL) {
-        return BLE_HS_ENOMEM;
-    }
-
-    memset(*out_proc, 0, sizeof **out_proc);
-    (*out_proc)->fsm_proc.op = op;
-    (*out_proc)->fsm_proc.conn_handle = conn_handle;
-    (*out_proc)->fsm_proc.tx_time = os_time_get();
+    ble_hs_lock();
+    STAILQ_INSERT_HEAD(&ble_l2cap_sm_procs, proc, next);
+    ble_hs_unlock();
+}
 
-    return 0;
+static void
+ble_l2cap_sm_sec_params(struct ble_l2cap_sm_proc *proc,
+                        struct ble_gap_sec_params *out_sec_params,
+                        int enc_enabled)
+{
+    out_sec_params->pair_alg = proc->pair_alg;
+    out_sec_params->enc_enabled = enc_enabled;
+    out_sec_params->auth_enabled = 0; // XXX
 }
 
-/**
- * Extraction callback used for removing all pairing procedures that have timed
- * out.
- */
-static int
-ble_l2cap_sm_proc_extract_expired_cb(struct ble_fsm_proc *proc, void *unused)
+static void
+ble_l2cap_sm_gap_event(struct ble_l2cap_sm_proc *proc, int status,
+                       int enc_enabled)
 {
-    uint32_t now;
-    int32_t diff;
+    struct ble_gap_sec_params sec_params;
 
-    now = os_time_get();
-    diff = now - ((struct ble_l2cap_sm_proc *)proc)->exp_os_ticks;
-    if (diff >= 0) {
-        return BLE_FSM_EXTRACT_EMOVE_CONTINUE;
+    ble_l2cap_sm_sec_params(proc, &sec_params, enc_enabled);
+    ble_gap_security_event(proc->conn_handle, status, &sec_params);
+}
+
+static void
+ble_l2cap_sm_process_status(struct ble_l2cap_sm_proc *proc, int status,
+                            uint8_t sm_status, int call_cb, int tx_fail)
+{
+    if (status == 0) {
+        ble_l2cap_sm_proc_insert(proc);
     } else {
-        return BLE_FSM_EXTRACT_EKEEP_CONTINUE;
+        if (tx_fail) {
+            ble_l2cap_sm_pair_fail_tx(proc->conn_handle, sm_status);
+        }
+        if (call_cb) {
+            ble_l2cap_sm_gap_event(proc, status, 0);
+        }
+        ble_l2cap_sm_proc_free(proc);
     }
 }
 
 static int
-ble_l2cap_sm_proc_extract_cb(struct ble_fsm_proc *proc, void *arg)
+ble_l2cap_sm_proc_matches(struct ble_l2cap_sm_proc *proc, uint16_t conn_handle,
+                          uint8_t state, int is_initiator)
 {
-    struct ble_l2cap_sm_extract_arg *extarg;
-    struct ble_l2cap_sm_proc *sm_proc;
     int proc_is_initiator;
 
-    extarg = arg;
-    sm_proc = (struct ble_l2cap_sm_proc *)proc;
-
-    if (extarg->conn_handle != proc->conn_handle) {
-        return BLE_FSM_EXTRACT_EKEEP_CONTINUE;
+    if (conn_handle != proc->conn_handle) {
+        return 0;
     }
 
-    if (extarg->op != BLE_L2CAP_SM_PROC_OP_NONE && extarg->op != proc->op) {
-        return BLE_FSM_EXTRACT_EKEEP_CONTINUE;
+    if (state != BLE_L2CAP_SM_PROC_STATE_NONE && state != proc->state) {
+        return 0;
     }
 
-    proc_is_initiator = !!(sm_proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR);
-    if (extarg->initiator != -1 && extarg->initiator != proc_is_initiator) {
-        return BLE_FSM_EXTRACT_EKEEP_CONTINUE;
+    proc_is_initiator = !!(proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR);
+    if (is_initiator != -1 && is_initiator != proc_is_initiator) {
+        return 0;
     }
 
-    return BLE_FSM_EXTRACT_EMOVE_STOP;
+    return 1;
 }
 
 /**
- * Searches the main proc list for an "expecting" entry whose connection handle
- * and op code match those specified.  If a matching entry is found, it is
- * removed from the list and returned.
- *
- * Lock restrictions:
- *     o Caller unlocks l2cap_sm.
+ * Searches the main proc list for an entry whose connection handle and state code
+ * match those specified.  If a matching entry is found, it is removed from the
+ * list and returned.
  *
  * @param conn_handle           The connection handle to match against.
- * @param op                    The op code to match against.
- * @param identifier            The identifier to match against.
+ * @param state                    The state code to match against.
+ * @param is_initiator
  *
  * @return                      The matching proc entry on success;
  *                                  null on failure.
  */
 static struct ble_l2cap_sm_proc *
-ble_l2cap_sm_proc_extract(struct ble_l2cap_sm_extract_arg *arg)
+ble_l2cap_sm_proc_extract(uint16_t conn_handle, uint8_t state,
+                          int is_initiator)
 {
     struct ble_l2cap_sm_proc *proc;
-    int rc;
-
-    rc = ble_fsm_proc_extract(&ble_l2cap_sm_fsm,
-                              (struct ble_fsm_proc **)&proc,
-                              ble_l2cap_sm_proc_extract_cb, arg);
+    struct ble_l2cap_sm_proc *prev;
+
+    ble_hs_lock();
+
+    prev = NULL;
+    STAILQ_FOREACH(proc, &ble_l2cap_sm_procs, next) {
+        if (ble_l2cap_sm_proc_matches(proc, conn_handle, state, is_initiator)) {
+            if (prev == NULL) {
+                STAILQ_REMOVE_HEAD(&ble_l2cap_sm_procs, next);
+            } else {
+                STAILQ_REMOVE_AFTER(&ble_l2cap_sm_procs, prev, next);
+            }
+            break;
+        }
 
-    if (rc != 0) {
-        proc = NULL;
+        prev = proc;
     }
 
+    ble_hs_unlock();
+
     return proc;
 }
 
-/**
- * Sets the specified proc entry's "pending" flag (i.e., indicates that the
- * L2CAP sm procedure is stalled until it transmits its next request).
- *
- * Lock restrictions: None.
- */
 static void
-ble_l2cap_sm_proc_set_pending(struct ble_l2cap_sm_proc *proc)
+ble_l2cap_sm_extract_expired(struct ble_l2cap_sm_proc_list *dst_list)
 {
-    ble_fsm_proc_set_pending(&proc->fsm_proc);
-    ble_hs_kick_l2cap_sm();
-}
+    struct ble_l2cap_sm_proc *proc;
+    struct ble_l2cap_sm_proc *prev;
+    struct ble_l2cap_sm_proc *next;
+    uint32_t now;
+    int32_t time_diff;
 
-static void
-ble_l2cap_sm_set_fail_state(struct ble_l2cap_sm_proc *proc,
-                            uint8_t fail_reason)
-{
-    proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_FAIL;
-    proc->fail.reason = fail_reason;
-    ble_l2cap_sm_proc_set_pending(proc);
+    now = os_time_get();
+    STAILQ_INIT(dst_list);
+
+    ble_hs_lock();
+
+    prev = NULL;
+    proc = STAILQ_FIRST(&ble_l2cap_sm_procs);
+    while (proc != NULL) {
+        next = STAILQ_NEXT(proc, next);
+
+        time_diff = now - proc->exp_os_ticks;
+        if (time_diff >= 0) {
+            if (prev == NULL) {
+                STAILQ_REMOVE_HEAD(&ble_l2cap_sm_procs, next);
+            } else {
+                STAILQ_REMOVE_AFTER(&ble_l2cap_sm_procs, prev, next);
+            }
+            STAILQ_INSERT_TAIL(dst_list, proc, next);
+        }
+
+        prev = proc;
+        proc = next;
+    }
+
+    ble_hs_unlock();
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
-ble_l2cap_sm_rx_noop(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
+ble_l2cap_sm_rx_noop(uint16_t conn_handle, uint8_t state, struct os_mbuf **om)
 {
-    return 0;
+    return BLE_HS_ENOTSUP;
 }
 
+/*****************************************************************************
+ * $hci                                                                      *
+ *****************************************************************************/
+
 static int
-ble_l2cap_sm_request_tk(struct ble_l2cap_sm_proc *proc)
+ble_l2cap_sm_start_encrypt_tx(uint16_t conn_handle, uint8_t *ltk)
 {
-    if (proc->pair_alg == BLE_L2CAP_SM_PAIR_ALG_JW) {
-        ble_l2cap_sm_proc_set_pending(proc);
-    } else {
-        /* XXX: Ask application for TK. */
+    struct hci_start_encrypt cmd;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_START_ENCRYPT_LEN];
+    int rc;
+
+    rc = ble_l2cap_sm_gen_ediv(&cmd.encrypted_diversifier);
+    if (rc != 0) {
+        return rc;
     }
-    return 0;
-}
 
-static void
-ble_l2cap_sm_sec_params(struct ble_l2cap_sm_proc *proc,
-                        struct ble_gap_sec_params *out_sec_params,
-                        int enc_enabled)
-{
-    out_sec_params->pair_alg = proc->pair_alg;
-    out_sec_params->enc_enabled = enc_enabled;
-    out_sec_params->auth_enabled = 0; // XXX
-}
+    rc = ble_l2cap_sm_gen_start_rand(&cmd.random_number);
+    if (rc != 0) {
+        return rc;
+    }
 
-static void
-ble_l2cap_sm_gap_event(struct ble_l2cap_sm_proc *proc, int status,
-                       int enc_enabled)
-{
-    struct ble_gap_sec_params sec_params;
+    cmd.connection_handle = conn_handle;
+    memcpy(cmd.long_term_key, ltk, sizeof cmd.long_term_key);
 
-    ble_l2cap_sm_sec_params(proc, &sec_params, enc_enabled);
-    ble_gap_security_event(proc->fsm_proc.conn_handle, status, &sec_params);
-}
+    host_hci_cmd_build_le_start_encrypt(&cmd, buf, sizeof buf);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
+    if (rc != 0) {
+        return rc;
+    }
 
-/*****************************************************************************
- * $pair                                                                     *
- *****************************************************************************/
+    return 0;
+}
 
 static int
-ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
-                             struct ble_l2cap_sm_pair_cmd *req)
+ble_l2cap_sm_lt_key_req_reply_tx(uint16_t conn_handle, uint8_t *ltk)
 {
-    proc->phase_1_2.pair_req = *req;
-    ble_l2cap_sm_proc_set_pending(proc);
+    struct hci_lt_key_req_reply cmd;
+    uint16_t ack_conn_handle;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LT_KEY_REQ_REPLY_LEN];
+    uint8_t ack_params_len;
+    int rc;
+
+    cmd.conn_handle = conn_handle;
+    memcpy(cmd.long_term_key, ltk, 16);
+
+    host_hci_cmd_build_le_lt_key_req_reply(&cmd, buf, sizeof buf);
+    rc = ble_hci_tx_cmd(buf, &ack_conn_handle, sizeof ack_conn_handle,
+                        &ack_params_len);
+    if (rc != 0) {
+        return rc;
+    }
+    if (ack_params_len != BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN - 1) {
+        return BLE_HS_ECONTROLLER;
+    }
+
+    ack_conn_handle = TOFROMLE16(ack_conn_handle);
+    if (ack_conn_handle != conn_handle) {
+        return BLE_HS_ECONTROLLER;
+    }
 
     return 0;
 }
 
 static int
-ble_l2cap_sm_pair_rsp_handle(struct ble_l2cap_sm_proc *proc,
-                             struct ble_l2cap_sm_pair_cmd *rsp)
+ble_l2cap_sm_lt_key_req_handle(struct ble_l2cap_sm_proc *proc,
+                               struct hci_le_lt_key_req *evt,
+                               uint8_t *out_sm_status)
 {
     int rc;
 
-    proc->phase_1_2.pair_rsp = *rsp;
+    rc = ble_l2cap_sm_lt_key_req_reply_tx(proc->conn_handle, proc->hci.key);
+    if (rc != 0) {
+        *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+        return rc;
+    }
 
-    proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_CONFIRM;
-    proc->fsm_proc.flags &= ~BLE_FSM_PROC_F_EXPECTING;
+    proc->state = BLE_L2CAP_SM_PROC_STATE_ENC_CHANGE;
 
-    /* XXX: Assume legacy "Just Works" for now. */
-    proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
+    return 0;
+}
 
-    rc = ble_l2cap_sm_request_tk(proc);
+/*****************************************************************************
+ * $random                                                                   *
+ *****************************************************************************/
+
+static int
+ble_l2cap_sm_random_go(struct ble_l2cap_sm_proc *proc)
+{
+    struct ble_l2cap_sm_pair_random cmd;
+    int rc;
+
+    memcpy(cmd.value, proc->phase_1_2.rand_our, 16);
+    rc = ble_l2cap_sm_pair_random_tx(proc->conn_handle, &cmd);
     if (rc != 0) {
-        ble_l2cap_sm_set_fail_state(proc, rc);
         return rc;
     }
 
+    ble_l2cap_sm_proc_set_timer(proc);
+
     return 0;
 }
 
 static int
-ble_l2cap_sm_pair_kick(struct ble_l2cap_sm_proc *proc)
+ble_l2cap_sm_random_handle(struct ble_l2cap_sm_proc *proc,
+                           struct ble_l2cap_sm_pair_random *cmd,
+                           uint8_t *out_sm_status)
 {
-    struct ble_l2cap_sm_pair_cmd cmd;
-    int is_req;
+    uint8_t preq[BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ];
+    uint8_t pres[BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ];
+    uint8_t confirm_val[16];
+    uint8_t k[16];
+    uint8_t ia[6];
+    uint8_t ra[6];
+    uint8_t iat;
+    uint8_t rat;
     int rc;
 
-    is_req = proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR;
+    /* Verify peer's random value. */
+    rc = ble_l2cap_sm_confirm_prepare_args(proc, k, preq, pres, &iat, &rat,
+                                           ia, ra);
+    if (rc != 0) {
+        *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+        return rc;
+    }
 
-    cmd.io_cap = ble_hs_cfg.sm_io_cap;
-    cmd.oob_data_flag = ble_hs_cfg.sm_oob_data_flag;
-    cmd.authreq = (ble_hs_cfg.sm_bonding << 0)  |
-                  (ble_hs_cfg.sm_mitm << 2)     |
-                  (ble_hs_cfg.sm_sc << 3)       |
-                  (ble_hs_cfg.sm_keypress << 4);
-    cmd.max_enc_key_size = 16;
+    rc = ble_l2cap_sm_alg_c1(k, cmd->value, preq, pres, iat, rat,
+                             ia, ra, confirm_val);
+    if (rc != 0) {
+        *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+        return rc;
+    }
 
-    if (is_req) {
-        cmd.init_key_dist = ble_hs_cfg.sm_our_key_dist;
-        cmd.resp_key_dist = ble_hs_cfg.sm_their_key_dist;
-    } else {
-        cmd.init_key_dist = ble_hs_cfg.sm_their_key_dist;
-        cmd.resp_key_dist = ble_hs_cfg.sm_our_key_dist;
+    if (memcmp(proc->phase_1_2.confirm_their, confirm_val, 16) != 0) {
+        /* Random number mismatch. */
+        rc = BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH);
+        *out_sm_status = BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH;
+        return rc;
     }
 
-    rc = ble_l2cap_sm_pair_cmd_tx(proc->fsm_proc.conn_handle, is_req, &cmd);
+    memcpy(proc->phase_1_2.rand_their, cmd->value, 16);
+
+    /* Generate the key. */
+    rc = ble_l2cap_sm_gen_key(proc);
     if (rc != 0) {
-        ble_l2cap_sm_set_fail_state(proc, BLE_L2CAP_SM_ERR_UNSPECIFIED);
-        return BLE_HS_EAGAIN;
+        *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+        return rc;
     }
 
-    if (is_req) {
-        proc->phase_1_2.pair_req = cmd;
+    if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+        /* Send the start-encrypt HCI command to the controller. */
+        rc = ble_l2cap_sm_start_encrypt_tx(proc->conn_handle, proc->hci.key);
+        if (rc != 0) {
+            *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+            return rc;
+        }
+        proc->state = BLE_L2CAP_SM_PROC_STATE_ENC_CHANGE;
     } else {
-        proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
-        proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_CONFIRM;
-        proc->phase_1_2.pair_rsp = cmd;
+        rc = ble_l2cap_sm_random_go(proc);
+        if (rc != 0) {
+            *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+            return rc;
+        }
+        proc->state = BLE_L2CAP_SM_PROC_STATE_LTK;
     }
 
+    *out_sm_status = 0;
     return 0;
 }
 
@@ -605,8 +633,7 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
 {
     struct ble_hs_conn *conn;
 
-    ble_hs_conn_lock();
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
+    conn = ble_hs_conn_find(proc->conn_handle);
     if (conn != NULL) {
         if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
             *iat = BLE_ADDR_TYPE_PUBLIC; /* XXX: Support random addresses. */
@@ -622,7 +649,6 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
             memcpy(ia, conn->bhc_addr, 6);
         }
     }
-    ble_hs_conn_unlock();
 
     if (conn == NULL) {
         return BLE_HS_ENOTCONN;
@@ -642,7 +668,7 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
 }
 
 static int
-ble_l2cap_sm_confirm_kick(struct ble_l2cap_sm_proc *proc)
+ble_l2cap_sm_confirm_go(struct ble_l2cap_sm_proc *proc)
 {
     struct ble_l2cap_sm_pair_confirm cmd;
     uint8_t preq[BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ];
@@ -654,271 +680,150 @@ ble_l2cap_sm_confirm_kick(struct ble_l2cap_sm_proc *proc)
     uint8_t rat;
     int rc;
 
-    ble_l2cap_sm_gen_pair_rand(proc->phase_1_2.rand_our);
+    rc = ble_l2cap_sm_gen_pair_rand(proc->phase_1_2.rand_our);
+    if (rc != 0) {
+        return rc;
+    }
 
     rc = ble_l2cap_sm_confirm_prepare_args(proc, k, preq, pres, &iat, &rat,
                                            ia, ra);
     if (rc != 0) {
-        ble_l2cap_sm_set_fail_state(proc, BLE_L2CAP_SM_ERR_UNSPECIFIED);
-        return BLE_HS_EAGAIN;
+        return rc;
     }
 
     rc = ble_l2cap_sm_alg_c1(k, proc->phase_1_2.rand_our, preq, pres, iat, rat,
                              ia, ra, cmd.value);
     if (rc != 0) {
-        ble_l2cap_sm_set_fail_state(proc, BLE_L2CAP_SM_ERR_UNSPECIFIED);
-        return BLE_HS_EAGAIN;
+        return rc;
     }
 
-    rc = ble_l2cap_sm_pair_confirm_tx(proc->fsm_proc.conn_handle, &cmd);
+    rc = ble_l2cap_sm_pair_confirm_tx(proc->conn_handle, &cmd);
     if (rc != 0) {
-        ble_l2cap_sm_set_fail_state(proc, BLE_L2CAP_SM_ERR_UNSPECIFIED);
-        return BLE_HS_EAGAIN;
+        return rc;
     }
 
-    if (!(proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR)) {
-        proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_RANDOM;
-    }
+    ble_l2cap_sm_proc_set_timer(proc);
 
     return 0;
 }
 
 static int
 ble_l2cap_sm_confirm_handle(struct ble_l2cap_sm_proc *proc,
-                            struct ble_l2cap_sm_pair_confirm *cmd)
+                            struct ble_l2cap_sm_pair_confirm *cmd,
+                            uint8_t *out_sm_status)
 {
     int rc;
 
     memcpy(proc->phase_1_2.confirm_their, cmd->value, 16);
 
     if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
-        proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_RANDOM;
-        ble_l2cap_sm_proc_set_pending(proc);
+        rc = ble_l2cap_sm_random_go(proc);
+        if (rc != 0) {
+            *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+            return rc;
+        }
     } else {
-        rc = ble_l2cap_sm_request_tk(proc);
+        /* XXX: If MITM is used, request TK from application. */
+
+        rc = ble_l2cap_sm_confirm_go(proc);
         if (rc != 0) {
-            ble_l2cap_sm_set_fail_state(proc, rc);
+            *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
             return rc;
         }
     }
 
+    proc->state = BLE_L2CAP_SM_PROC_STATE_RANDOM;
+
     return 0;
 }
 
 /*****************************************************************************
- * $random                                                                  *
+ * $pair                                                                     *
  *****************************************************************************/
 
 static int
-ble_l2cap_sm_random_kick(struct ble_l2cap_sm_proc *proc)
+ble_l2cap_sm_pair_go(struct ble_l2cap_sm_proc *proc)
 {
-    struct ble_l2cap_sm_pair_random cmd;
-    uint8_t key[16];
+    struct ble_l2cap_sm_pair_cmd cmd;
+    int is_req;
     int rc;
 
-    memcpy(cmd.value, proc->phase_1_2.rand_our, 16);
-    rc = ble_l2cap_sm_pair_random_tx(proc->fsm_proc.conn_handle, &cmd);
-    if (rc != 0) {
-        ble_l2cap_sm_set_fail_state(proc, BLE_L2CAP_SM_ERR_UNSPECIFIED);
-        return BLE_HS_EAGAIN;
-    }
-
-    if (!(proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR)) {
-        /* Generate the key. */
-        rc = ble_l2cap_sm_alg_s1(proc->phase_1_2.tk, proc->phase_1_2.rand_our,
-                                 proc->phase_1_2.rand_their, key);
-        if (rc != 0) {
-            ble_l2cap_sm_gap_event(proc, rc, 0);
-            return rc;
-        }
-        memcpy(proc->hci.key, key, sizeof key);
-
-        proc->hci.handle = BLE_HCI_SCHED_HANDLE_NONE;
-        proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_LTK;
-    }
-
-    return 0;
-}
+    is_req = proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR;
 
-static int
-ble_l2cap_sm_random_handle(struct ble_l2cap_sm_proc *proc,
-                           struct ble_l2cap_sm_pair_random *cmd)
-{
-    uint8_t preq[BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ];
-    uint8_t pres[BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ];
-    uint8_t confirm_val[16];
-    uint8_t key[16];
-    uint8_t k[16];
-    uint8_t ia[6];
-    uint8_t ra[6];
-    uint8_t iat;
-    uint8_t rat;
-    int rc;
+    cmd.io_cap = ble_hs_cfg.sm_io_cap;
+    cmd.oob_data_flag = ble_hs_cfg.sm_oob_data_flag;
+    cmd.authreq = (ble_hs_cfg.sm_bonding << 0)  |
+                  (ble_hs_cfg.sm_mitm << 2)     |
+                  (ble_hs_cfg.sm_sc << 3)       |
+                  (ble_hs_cfg.sm_keypress << 4);
+    cmd.max_enc_key_size = 16;
 
-    /* Verify peer's random value. */
-    rc = ble_l2cap_sm_confirm_prepare_args(proc, k, preq, pres, &iat, &rat,
-                                           ia, ra);
-    if (rc != 0) {
-        ble_l2cap_sm_set_fail_state(proc, BLE_L2CAP_SM_ERR_UNSPECIFIED);
-        return 0;
+    if (is_req) {
+        cmd.init_key_dist = ble_hs_cfg.sm_our_key_dist;
+        cmd.resp_key_dist = ble_hs_cfg.sm_their_key_dist;
+    } else {
+        cmd.init_key_dist = ble_hs_cfg.sm_their_key_dist;
+        cmd.resp_key_dist = ble_hs_cfg.sm_our_key_dist;
     }
 
-    rc = ble_l2cap_sm_alg_c1(k, cmd->value, preq, pres, iat, rat,
-                             ia, ra, confirm_val);
+    rc = ble_l2cap_sm_pair_cmd_tx(proc->conn_handle, is_req, &cmd);
     if (rc != 0) {
-        ble_l2cap_sm_set_fail_state(proc, BLE_L2CAP_SM_ERR_UNSPECIFIED);
-        return 0;
+        return rc;
     }
 
-    if (memcmp(proc->phase_1_2.confirm_their, confirm_val, 16) != 0) {
-        /* Random number mismatch. */
-        ble_l2cap_sm_set_fail_state(proc, BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH);
-        return 0;
+    if (is_req) {
+        proc->phase_1_2.pair_req = cmd;
+    } else {
+        proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
+        proc->phase_1_2.pair_rsp = cmd;
     }
 
-    memcpy(proc->phase_1_2.rand_their, cmd->value, 16);
-
-    if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
-        /* Generate the key. */
-        rc = ble_l2cap_sm_alg_s1(proc->phase_1_2.tk, proc->phase_1_2.rand_our,
-                                 proc->phase_1_2.rand_their, key);
-        if (rc != 0) {
-            ble_l2cap_sm_gap_event(proc, rc, 0);
-            return rc;
-        }
-        memcpy(proc->hci.key, key, sizeof key);
-        proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_START_ENCRYPT;
-    }
-    ble_l2cap_sm_proc_set_pending(proc);
+    ble_l2cap_sm_proc_set_timer(proc);
 
     return 0;
 }
 
-/*****************************************************************************
- * $fail                                                                    *
- *****************************************************************************/
-
-static int
-ble_l2cap_sm_fail_kick(struct ble_l2cap_sm_proc *proc)
-{
-    struct ble_l2cap_sm_pair_fail cmd;
-
-    cmd.reason = proc->fail.reason;
-    ble_l2cap_sm_pair_fail_tx(proc->fsm_proc.conn_handle, &cmd);
-
-    /* Notify application of failure. */
-    ble_l2cap_sm_gap_event(proc, BLE_HS_SM_US_ERR(cmd.reason), 0);
-
-    return BLE_HS_EDONE;
-}
-
 static int
-ble_l2cap_sm_fail_handle(struct ble_l2cap_sm_proc *proc,
-                         struct ble_l2cap_sm_pair_fail *cmd)
-{
-    ble_l2cap_sm_gap_event(proc, BLE_HS_SM_THEM_ERR(cmd->reason), 0);
-
-    /* Procedure should now be terminated (return nonzero). */
-    return 1;
-}
-
-/*****************************************************************************
- * $hci                                                                      *
- *****************************************************************************/
-
-static int
-ble_l2cap_sm_lt_key_req_reply_tx(void *arg)
+ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
+                             struct ble_l2cap_sm_pair_cmd *req,
+                             uint8_t *out_sm_status)
 {
-    struct hci_lt_key_req_reply cmd;
-    struct ble_l2cap_sm_proc *proc;
     int rc;
 
-    proc = arg;
-
-    BLE_HS_DBG_ASSERT(proc->fsm_proc.op == BLE_L2CAP_SM_PROC_OP_LTK_TXED);
-
-    /* Indicate that the HCI reservation has been serviced.  If there is a
-     * failure, we shouldn't try to cancel the reservation.
-     */
-    proc->hci.handle = BLE_HCI_SCHED_HANDLE_NONE;
-
-    cmd.conn_handle = proc->fsm_proc.conn_handle;
-    memcpy(cmd.long_term_key, proc->hci.key, 16);
-
-    ble_hci_sched_set_ack_cb(ble_l2cap_sm_rx_lt_key_req_reply_ack, proc);
-
-    rc = host_hci_cmd_le_lt_key_req_reply(&cmd);
-    return rc;
-}
-
-static int
-ble_l2cap_sm_lt_key_req_kick(struct ble_l2cap_sm_proc *proc)
-{
-    int rc;
+    proc->phase_1_2.pair_req = *req;
 
-    rc = ble_hci_sched_enqueue(ble_l2cap_sm_lt_key_req_reply_tx, proc,
-                               &proc->hci.handle);
+    rc = ble_l2cap_sm_pair_go(proc);
     if (rc != 0) {
-        ble_l2cap_sm_gap_event(proc, rc, 0);
-        return BLE_HS_EDONE;
+        *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+        return rc;
     }
 
-    proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_LTK_TXED;
+    proc->state = BLE_L2CAP_SM_PROC_STATE_CONFIRM;
 
     return 0;
 }
 
 static int
-ble_l2cap_sm_lt_key_req_handle(struct ble_l2cap_sm_proc *proc,
-                               struct hci_le_lt_key_req *evt)
-{
-    ble_l2cap_sm_proc_set_pending(proc);
-    return 0;
-}
-
-static int
-ble_l2cap_sm_start_encrypt_tx(void *arg)
+ble_l2cap_sm_pair_rsp_handle(struct ble_l2cap_sm_proc *proc,
+                             struct ble_l2cap_sm_pair_cmd *rsp,
+                             uint8_t *out_sm_status)
 {
-    struct ble_l2cap_sm_proc *proc;
-    struct hci_start_encrypt cmd;
     int rc;
 
-    proc = arg;
-
-    BLE_HS_DBG_ASSERT(proc->fsm_proc.op ==
-                      BLE_L2CAP_SM_PROC_OP_START_ENCRYPT_TXED);
-
-    /* Indicate that the HCI reservation has been serviced.  If there is a
-     * failure, we shouldn't try to cancel the reservation.
-     */
-    proc->hci.handle = BLE_HCI_SCHED_HANDLE_NONE;
-
-    cmd.connection_handle = proc->fsm_proc.conn_handle;
-    cmd.encrypted_diversifier = ble_l2cap_sm_gen_ediv();
-    cmd.random_number = ble_l2cap_sm_gen_start_rand();
-    memcpy(cmd.long_term_key, proc->hci.key, sizeof cmd.long_term_key);
-
-    ble_hci_sched_set_ack_cb(ble_l2cap_sm_rx_start_encrypt_ack, proc);
+    proc->phase_1_2.pair_rsp = *rsp;
 
-    rc = host_hci_cmd_le_start_encrypt(&cmd);
-    return rc;
-}
+    /* XXX: Assume legacy "Just Works" for now. */
+    proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
 
-static int
-ble_l2cap_sm_start_encrypt_kick(struct ble_l2cap_sm_proc *proc)
-{
-    int rc;
+    /* XXX: If MITM is used, request TK from application. */
 
-    rc = ble_hci_sched_enqueue(ble_l2cap_sm_start_encrypt_tx, proc,
-                               &proc->hci.handle);
+    proc->state = BLE_L2CAP_SM_PROC_STATE_CONFIRM;
+    rc = ble_l2cap_sm_confirm_go(proc);
     if (rc != 0) {
-        ble_l2cap_sm_gap_event(proc, rc, 0);
-        return BLE_HS_EDONE;
+        *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+        return rc;
     }
 
-    proc->hci.handle = BLE_HCI_SCHED_HANDLE_NONE;
-    proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_START_ENCRYPT_TXED;
-
     return 0;
 }
 
@@ -927,10 +832,12 @@ ble_l2cap_sm_start_encrypt_kick(struct ble_l2cap_sm_proc *proc)
  *****************************************************************************/
 
 static int
-ble_l2cap_sm_rx_pair_req(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
+ble_l2cap_sm_rx_pair_req(uint16_t conn_handle, uint8_t state,
+                         struct os_mbuf **om)
 {
     struct ble_l2cap_sm_pair_cmd req;
     struct ble_l2cap_sm_proc *proc;
+    uint8_t sm_status;
     int rc;
 
     rc = ble_hs_misc_pullup_base(om, BLE_L2CAP_SM_PAIR_CMD_SZ);
@@ -948,36 +855,34 @@ ble_l2cap_sm_rx_pair_req(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
 
     /* XXX: Check connection state; reject if not appropriate. */
 
-    proc = ble_l2cap_sm_proc_extract(
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = conn_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_NONE,
-            .initiator = -1,
-        }
-    );
+    proc = ble_l2cap_sm_proc_extract(conn_handle, BLE_L2CAP_SM_PROC_STATE_NONE,
+                                     -1);
     if (proc != NULL) {
         /* Pairing already in progress; abort old procedure and start new. */
         /* XXX: Check the spec on this. */
-        ble_l2cap_sm_proc_free(&proc->fsm_proc);
+        ble_l2cap_sm_proc_free(proc);
     }
 
-    rc = ble_l2cap_sm_proc_new(conn_handle, BLE_L2CAP_SM_PROC_OP_PAIR,
-                               &proc);
-    if (rc != 0) {
-        return rc;
+    proc = ble_l2cap_sm_proc_alloc();
+    if (proc == NULL) {
+        return BLE_HS_ENOMEM;
     }
+    proc->conn_handle = conn_handle;
+    proc->state = BLE_L2CAP_SM_PROC_STATE_PAIR;
 
-    rc = ble_l2cap_sm_pair_req_handle(proc, &req);
-    ble_fsm_process_rx_status(&ble_l2cap_sm_fsm, &proc->fsm_proc, rc);
+    rc = ble_l2cap_sm_pair_req_handle(proc, &req, &sm_status);
+    ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
 
     return rc;
 }
 
 static int
-ble_l2cap_sm_rx_pair_rsp(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
+ble_l2cap_sm_rx_pair_rsp(uint16_t conn_handle, uint8_t state,
+                         struct os_mbuf **om)
 {
     struct ble_l2cap_sm_pair_cmd rsp;
     struct ble_l2cap_sm_proc *proc;
+    uint8_t sm_status;
     int rc;
 
     rc = ble_hs_misc_pullup_base(om, BLE_L2CAP_SM_PAIR_CMD_SZ);
@@ -993,29 +898,25 @@ ble_l2cap_sm_rx_pair_rsp(uint16_t conn_handle, uint8_t op, struct os_mbuf **om)
                rsp.io_cap, rsp.oob_data_flag, rsp.authreq,
                rsp.max_enc_key_size, rsp.init_key_dist, rsp.resp_key_dist);
 
-    proc = ble_l2cap_sm_proc_extract(
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = conn_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_PAIR,
-            .initiator = 1,
-        }
-    );
+    proc = ble_l2cap_sm_proc_extract(conn_handle, BLE_L2CAP_SM_PROC_STATE_PAIR,
+                                     1);
     if (proc == NULL) {
         return BLE_HS_ENOTCONN;
     }
 
-    rc = ble_l2cap_sm_pair_rsp_handle(proc, &rsp);
-    ble_fsm_process_rx_status(&ble_l2cap_sm_fsm, &proc->fsm_proc, rc);
+    rc = ble_l2cap_sm_pair_rsp_handle(proc, &rsp, &sm_status);
+    ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
 
     return 0;
 }
 
 static int
-ble_l2cap_sm_rx_pair_confirm(uint16_t conn_handle, uint8_t op,
+ble_l2cap_sm_rx_pair_confirm(uint16_t conn_handle, uint8_t state,
                              struct os_mbuf **om)
 {
     struct ble_l2cap_sm_pair_confirm cmd;
     struct ble_l2cap_sm_proc *proc;
+    uint8_t sm_status;
     int rc;
 
     rc = ble_hs_misc_pullup_base(om, BLE_L2CAP_SM_PAIR_CONFIRM_SZ);
@@ -1027,29 +928,25 @@ ble_l2cap_sm_rx_pair_confirm(uint16_t conn_handle, uint8_t op,
 
     BLE_HS_LOG(DEBUG, "rxed sm confirm cmd\n");
 
-    proc = ble_l2cap_sm_proc_extract(
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = conn_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_CONFIRM,
-            .initiator = -1,
-        }
-    );
+    proc = ble_l2cap_sm_proc_extract(conn_handle,
+                                     BLE_L2CAP_SM_PROC_STATE_CONFIRM, -1);
     if (proc == NULL) {
         return BLE_HS_ENOTCONN;
     }
 
-    rc = ble_l2cap_sm_confirm_handle(proc, &cmd);
-    ble_fsm_process_rx_status(&ble_l2cap_sm_fsm, &proc->fsm_proc, rc);
+    rc = ble_l2cap_sm_confirm_handle(proc, &cmd, &sm_status);
+    ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
 
     return 0;
 }
 
 static int
-ble_l2cap_sm_rx_pair_random(uint16_t conn_handle, uint8_t op,
+ble_l2cap_sm_rx_pair_random(uint16_t conn_handle, uint8_t state,
                             struct os_mbuf **om)
 {
     struct ble_l2cap_sm_pair_random cmd;
     struct ble_l2cap_sm_proc *proc;
+    uint8_t sm_status;
     int rc;
 
     rc = ble_hs_misc_pullup_base(om, BLE_L2CAP_SM_PAIR_RANDOM_SZ);
@@ -1061,25 +958,20 @@ ble_l2cap_sm_rx_pair_random(uint16_t conn_handle, uint8_t op,
 
     BLE_HS_LOG(DEBUG, "rxed sm random cmd\n");
 
-    proc = ble_l2cap_sm_proc_extract(
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = conn_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_RANDOM,
-            .initiator = -1,
-        }
-    );
+    proc = ble_l2cap_sm_proc_extract(conn_handle,
+                                     BLE_L2CAP_SM_PROC_STATE_RANDOM, -1);
     if (proc == NULL) {
         return BLE_HS_ENOTCONN;
     }
 
-    rc = ble_l2cap_sm_random_handle(proc, &cmd);
-    ble_fsm_process_rx_status(&ble_l2cap_sm_fsm, &proc->fsm_proc, rc);
+    rc = ble_l2cap_sm_random_handle(proc, &cmd, &sm_status);
+    ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
 
     return 0;
 }
 
 static int
-ble_l2cap_sm_rx_pair_fail(uint16_t conn_handle, uint8_t op,
+ble_l2cap_sm_rx_pair_fail(uint16_t conn_handle, uint8_t state,
                           struct os_mbuf **om)
 {
     struct ble_l2cap_sm_pair_fail cmd;
@@ -1095,19 +987,13 @@ ble_l2cap_sm_rx_pair_fail(uint16_t conn_handle, uint8_t op,
 
     BLE_HS_LOG(DEBUG, "rxed sm fail cmd; reason=%d\n", cmd.reason);
 
-    proc = ble_l2cap_sm_proc_extract(
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = conn_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_NONE,
-            .initiator = -1,
-        }
-    );
+    proc = ble_l2cap_sm_proc_extract(conn_handle, BLE_L2CAP_SM_PROC_STATE_NONE,
+                                     -1);
     if (proc == NULL) {
         return BLE_HS_ENOTCONN;
     }
 
-    rc = ble_l2cap_sm_fail_handle(proc, &cmd);
-    ble_fsm_process_rx_status(&ble_l2cap_sm_fsm, &proc->fsm_proc, rc);
+    ble_l2cap_sm_process_status(proc, BLE_HS_SM_THEM_ERR(cmd.reason), 0, 1, 0);
 
     return 0;
 }
@@ -1116,129 +1002,38 @@ int
 ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt)
 {
     struct ble_l2cap_sm_proc *proc;
+    uint8_t sm_status;
     int rc;
 
-    proc = ble_l2cap_sm_proc_extract(
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = evt->connection_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_LTK,
-            .initiator = 0,
-        }
-    );
+    proc = ble_l2cap_sm_proc_extract(evt->connection_handle,
+                                     BLE_L2CAP_SM_PROC_STATE_LTK, 0);
     if (proc == NULL) {
         return BLE_HS_ENOTCONN;
     }
 
-    rc = ble_l2cap_sm_lt_key_req_handle(proc, evt);
-    ble_fsm_process_rx_status(&ble_l2cap_sm_fsm, &proc->fsm_proc, rc);
+    rc = ble_l2cap_sm_lt_key_req_handle(proc, evt, &sm_status);
+    ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
 
     return 0;
 }
 
-static void
-ble_l2cap_sm_rx_lt_key_req_reply_ack(struct ble_hci_ack *ack, void *arg)
-{
-    struct ble_l2cap_sm_proc *proc;
-    uint16_t conn_handle;
-    int rc;
-
-    proc = arg;
-
-    BLE_HS_DBG_ASSERT(proc->fsm_proc.op == BLE_L2CAP_SM_PROC_OP_LTK_TXED);
-
-    /* Extract the procedure from the state machine while we mess with it. */
-    ble_fsm_lock(&ble_l2cap_sm_fsm);
-    STAILQ_REMOVE(&ble_l2cap_sm_fsm.procs, &proc->fsm_proc, ble_fsm_proc,
-                  next);
-    ble_fsm_unlock(&ble_l2cap_sm_fsm);
-
-    if (ack->bha_status != 0) {
-        rc = ack->bha_status;
-        goto done;
-    }
-
-    if (ack->bha_params_len != BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN) {
-        /* Controller sent something weird; treat this as a failure. */
-        rc = BLE_HS_ECONTROLLER;
-        goto done;
-    }
-
-    conn_handle = le16toh(ack->bha_params + 1);
-    if (conn_handle != proc->fsm_proc.conn_handle) {
-        /* Controller sent something weird; treat this as a failure. */
-        rc = BLE_HS_ECONTROLLER;
-        goto done;
-    }
-
-    proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_ENC_CHANGE;
-    rc = 0;
-
-done:
-    if (rc != 0) {
-        /* Report the failure to the application. */
-        ble_l2cap_sm_gap_event(proc, rc, 0);
-    }
-    ble_fsm_process_rx_status(&ble_l2cap_sm_fsm, &proc->fsm_proc, rc);
-}
-
-static void
-ble_l2cap_sm_rx_start_encrypt_ack(struct ble_hci_ack *ack, void *arg)
-{
-    struct ble_l2cap_sm_proc *proc;
-    int rc;
-
-    proc = arg;
-
-    BLE_HS_DBG_ASSERT(proc->fsm_proc.op ==
-                      BLE_L2CAP_SM_PROC_OP_START_ENCRYPT_TXED);
-
-    /* Extract the procedure from the state machine while we mess with it. */
-    ble_fsm_lock(&ble_l2cap_sm_fsm);
-    STAILQ_REMOVE(&ble_l2cap_sm_fsm.procs, &proc->fsm_proc, ble_fsm_proc,
-                  next);
-    ble_fsm_unlock(&ble_l2cap_sm_fsm);
-
-    if (ack->bha_status != 0) {
-        rc = ack->bha_status;
-        goto done;
-    }
-
-    proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_ENC_CHANGE;
-    rc = 0;
-
-done:
-    if (rc != 0) {
-        /* Report the failure to the application. */
-        ble_l2cap_sm_gap_event(proc, rc, 0);
-    }
-    ble_fsm_process_rx_status(&ble_l2cap_sm_fsm, &proc->fsm_proc, rc);
-}
-
 void
 ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
 {
     struct ble_l2cap_sm_proc *proc;
+    int enc_enabled;
 
-    proc = ble_l2cap_sm_proc_extract(
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = evt->connection_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_ENC_CHANGE,
-            .initiator = -1,
-        }
-    );
+    proc = ble_l2cap_sm_proc_extract(evt->connection_handle,
+                                     BLE_L2CAP_SM_PROC_STATE_ENC_CHANGE, -1);
     if (proc == NULL) {
         return;
     }
 
-    if (evt->status != 0) {
-        ble_l2cap_sm_gap_event(proc, BLE_HS_HCI_ERR(evt->status), 0);
-    } else {
-        ble_l2cap_sm_gap_event(proc, 0,
-                               evt->encryption_enabled & 0x01 /* LE bit. */);
-    }
+    enc_enabled = evt->encryption_enabled & 0x01; /* LE bit. */
+    ble_l2cap_sm_gap_event(proc, BLE_HS_HCI_ERR(evt->status), enc_enabled);
 
     /* The pairing procedure is now complete. */
-    ble_l2cap_sm_proc_free(&proc->fsm_proc);
+    ble_l2cap_sm_proc_free(proc);
 }
 
 /**
@@ -1257,11 +1052,10 @@ ble_l2cap_sm_rx(uint16_t conn_handle, struct os_mbuf **om)
     ble_hs_misc_log_mbuf(*om);
     BLE_HS_LOG(DEBUG, "\n");
 
-    rc = ble_hs_misc_pullup_base(om, 1);
+    rc = os_mbuf_copydata(*om, 0, 1, &op);
     if (rc != 0) {
         return BLE_HS_EBADDATA;
     }
-    op = *(*om)->om_data;
 
     /* Strip L2CAP SM header from the front of the mbuf. */
     os_mbuf_adj(*om, 1);
@@ -1283,25 +1077,22 @@ ble_l2cap_sm_rx(uint16_t conn_handle, struct os_mbuf **om)
 void
 ble_l2cap_sm_heartbeat(void)
 {
-    struct ble_fsm_proc_list exp_list;
+    struct ble_l2cap_sm_proc_list exp_list;
     struct ble_l2cap_sm_proc *proc;
-    struct ble_fsm_proc *fsm_proc;
 
     /* Remove all timed out procedures and insert them into a temporary
      * list.
      */
-    ble_fsm_proc_extract_list(&ble_l2cap_sm_fsm, &exp_list,
-                              ble_l2cap_sm_proc_extract_expired_cb, NULL);
+    ble_l2cap_sm_extract_expired(&exp_list);
 
     /* Notify application of each failure and free the corresponding procedure
      * object.
      */
-    while ((fsm_proc = STAILQ_FIRST(&exp_list)) != NULL) {
-        proc = (struct ble_l2cap_sm_proc *)fsm_proc;
+    while ((proc = STAILQ_FIRST(&exp_list)) != NULL) {
         ble_l2cap_sm_gap_event(proc, BLE_HS_ETIMEOUT, 0);
 
         STAILQ_REMOVE_HEAD(&exp_list, next);
-        ble_l2cap_sm_proc_free(&proc->fsm_proc);
+        ble_l2cap_sm_proc_free(proc);
     }
 }
 
@@ -1314,28 +1105,24 @@ ble_l2cap_sm_initiate(uint16_t conn_handle)
     /* Make sure a pairing operation for this connection is not already in
      * progress.
      */
-    proc = ble_l2cap_sm_proc_extract(
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = conn_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_NONE,
-            .initiator = -1,
-        }
-    );
+    proc = ble_l2cap_sm_proc_extract(conn_handle, BLE_L2CAP_SM_PROC_STATE_NONE,
+                                     -1);
     if (proc != NULL) {
         return BLE_HS_EALREADY;
     }
 
-    rc = ble_l2cap_sm_proc_new(conn_handle, BLE_L2CAP_SM_PROC_OP_PAIR,
-                               &proc);
-    if (rc != 0) {
-        return rc;
+    proc = ble_l2cap_sm_proc_alloc();
+    if (proc == NULL) {
+        return BLE_HS_ENOMEM;
     }
-
+    proc->conn_handle = conn_handle;
+    proc->state = BLE_L2CAP_SM_PROC_STATE_PAIR;
     proc->flags |= BLE_L2CAP_SM_PROC_F_INITIATOR;
-    STAILQ_INSERT_TAIL(&ble_l2cap_sm_fsm.procs, &proc->fsm_proc, next);
-    ble_l2cap_sm_proc_set_pending(proc);
 
-    return 0;
+    rc = ble_l2cap_sm_pair_go(proc);
+    ble_l2cap_sm_process_status(proc, rc, 0, 0, 0);
+
+    return rc;
 }
 
 /**
@@ -1364,20 +1151,15 @@ ble_l2cap_sm_set_tk(uint16_t conn_handle, uint8_t *tk)
 {
     struct ble_l2cap_sm_proc *proc;
 
-    proc = ble_l2cap_sm_proc_extract(
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = conn_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_CONFIRM,
-            .initiator = -1,
-        }
-    );
+    proc = ble_l2cap_sm_proc_extract(conn_handle,
+                                     BLE_L2CAP_SM_PROC_STATE_CONFIRM, -1);
     if (proc == NULL) {
         return BLE_HS_ENOENT;
     }
 
     memcpy(proc->phase_1_2.tk, tk, 16);
 
-    ble_l2cap_sm_proc_set_pending(proc);
+    /* XXX: Proceed with pairing; send confirm command. */
 
     return 0;
 }
@@ -1385,43 +1167,19 @@ ble_l2cap_sm_set_tk(uint16_t conn_handle, uint8_t *tk)
 void
 ble_l2cap_sm_connection_broken(uint16_t conn_handle)
 {
-    struct ble_fsm_proc_list list;
     struct ble_l2cap_sm_proc *proc;
-    struct ble_fsm_proc *fsm_proc;
-
-    /* Extract all procs associated with the broken connection and insert them
-     * into the temporary list.
-     */
-    ble_fsm_proc_extract_list(
-        &ble_l2cap_sm_fsm, &list, ble_l2cap_sm_proc_extract_cb,
-        &(struct ble_l2cap_sm_extract_arg) {
-            .conn_handle = conn_handle,
-            .op = BLE_L2CAP_SM_PROC_OP_NONE,
-            .initiator = -1,
-        }
-    );
-
-    /* Free each affected procedure object.  There is no need to notify the
-     * application, as it has already been notified of the connection failure.
-     */
-    while ((fsm_proc = STAILQ_FIRST(&list)) != NULL) {
-        proc = (struct ble_l2cap_sm_proc *)fsm_proc;
 
-        STAILQ_REMOVE_HEAD(&list, next);
-        ble_l2cap_sm_proc_free(&proc->fsm_proc);
+    proc = ble_l2cap_sm_proc_extract(conn_handle, BLE_L2CAP_SM_PROC_STATE_NONE,
+                                     -1);
+    if (proc != NULL) {
+        /* Free thw affected procedure object.  There is no need to notify the
+         * application, as it has already been notified of the connection
+         * failure.
+         */
+        ble_l2cap_sm_proc_free(proc);
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
-void
-ble_l2cap_sm_wakeup(void)
-{
-    ble_fsm_wakeup(&ble_l2cap_sm_fsm);
-}
-
 int
 ble_l2cap_sm_init(void)
 {
@@ -1429,11 +1187,7 @@ ble_l2cap_sm_init(void)
 
     free(ble_l2cap_sm_proc_mem);
 
-    rc = ble_fsm_new(&ble_l2cap_sm_fsm, ble_l2cap_sm_proc_kick,
-                     ble_l2cap_sm_proc_free);
-    if (rc != 0) {
-        goto err;
-    }
+    STAILQ_INIT(&ble_l2cap_sm_procs);
 
     if (ble_hs_cfg.max_l2cap_sm_procs > 0) {
         ble_l2cap_sm_proc_mem = malloc(

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_l2cap_sm.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.h b/net/nimble/host/src/ble_l2cap_sm.h
index e56f1df..9ecbeaf 100644
--- a/net/nimble/host/src/ble_l2cap_sm.h
+++ b/net/nimble/host/src/ble_l2cap_sm.h
@@ -90,8 +90,6 @@ void ble_l2cap_sm_dbg_set_next_start_rand(uint64_t next_start_rand);
 int ble_l2cap_sm_dbg_num_procs(void);
 #endif
 
-int ble_l2cap_sm_locked_by_cur_task(void);
-
 struct ble_l2cap_chan *ble_l2cap_sm_create_chan(void);
 
 void ble_l2cap_sm_pair_cmd_parse(void *payload, int len,
@@ -116,8 +114,7 @@ void ble_l2cap_sm_pair_fail_parse(void *payload, int len,
                                   struct ble_l2cap_sm_pair_fail *cmd);
 void ble_l2cap_sm_pair_fail_write(void *payload, int len,
                                   struct ble_l2cap_sm_pair_fail *cmd);
-int ble_l2cap_sm_pair_fail_tx(uint16_t conn_handle,
-                              struct ble_l2cap_sm_pair_fail *cmd);
+int ble_l2cap_sm_pair_fail_tx(uint16_t conn_handle, uint8_t reason);
 
 int ble_l2cap_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out);
 int ble_l2cap_sm_alg_c1(uint8_t *k, uint8_t *r,
@@ -131,7 +128,6 @@ int ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt);
 
 void ble_l2cap_sm_heartbeat(void);
 int ble_l2cap_sm_initiate(uint16_t conn_handle);
-void ble_l2cap_sm_wakeup(void);
 int ble_l2cap_sm_init(void);
 
 #else
@@ -141,8 +137,6 @@ int ble_l2cap_sm_init(void);
 #define ble_l2cap_sm_dbg_num_procs() 0
 #endif
 
-#define ble_l2cap_sm_locked_by_cur_task() 0
-
 #define ble_l2cap_sm_create_chan() NULL
 
 #define ble_l2cap_sm_pair_cmd_tx(conn_handle, is_req, cmd) BLE_HS_ENOTSUP
@@ -160,7 +154,6 @@ int ble_l2cap_sm_init(void);
 #define ble_l2cap_sm_connection_broken(conn_handle)
 
 #define ble_l2cap_sm_heartbeat()
-#define ble_l2cap_sm_wakeup()
 #define ble_l2cap_sm_init() 0
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_l2cap_sm_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm_cmd.c b/net/nimble/host/src/ble_l2cap_sm_cmd.c
index dac8558..843b1e5 100644
--- a/net/nimble/host/src/ble_l2cap_sm_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sm_cmd.c
@@ -35,7 +35,7 @@ ble_l2cap_sm_tx(uint16_t conn_handle, struct os_mbuf *txom)
 
     STATS_INC(ble_l2cap_stats, sm_tx);
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SM,
                                          &conn, &chan);
@@ -46,7 +46,7 @@ ble_l2cap_sm_tx(uint16_t conn_handle, struct os_mbuf *txom)
         rc = ble_l2cap_tx(conn, chan, txom);
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     return rc;
 }
@@ -257,19 +257,22 @@ ble_l2cap_sm_pair_fail_write(void *payload, int len,
 }
 
 int
-ble_l2cap_sm_pair_fail_tx(uint16_t conn_handle,
-                          struct ble_l2cap_sm_pair_fail *cmd)
+ble_l2cap_sm_pair_fail_tx(uint16_t conn_handle, uint8_t reason)
 {
+    struct ble_l2cap_sm_pair_fail cmd;
     struct os_mbuf *txom;
     int rc;
 
+    BLE_HS_DBG_ASSERT(reason > 0 && reason < BLE_L2CAP_SM_ERR_MAX_PLUS_1);
+
     rc = ble_l2cap_sm_init_req(BLE_L2CAP_SM_PAIR_FAIL_SZ, &txom);
     if (rc != 0) {
         rc = BLE_HS_ENOMEM;
         goto done;
     }
 
-    ble_l2cap_sm_pair_fail_write(txom->om_data, txom->om_len, cmd);
+    cmd.reason = reason;
+    ble_l2cap_sm_pair_fail_write(txom->om_data, txom->om_len, &cmd);
 
     rc = ble_l2cap_sm_tx(conn_handle, txom);
     txom = NULL;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 a52d8b6..31eb108 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -31,11 +31,11 @@
 _Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ,
                "struct hci_data_hdr must be 4 bytes");
 
+#define BLE_HCI_TIMEOUT       (OS_TICKS_PER_SEC)
+
 typedef int host_hci_event_fn(uint8_t event_code, uint8_t *data, int len);
 static host_hci_event_fn host_hci_rx_disconn_complete;
 static host_hci_event_fn host_hci_rx_encrypt_change;
-static host_hci_event_fn host_hci_rx_cmd_complete;
-static host_hci_event_fn host_hci_rx_cmd_status;
 static host_hci_event_fn host_hci_rx_num_completed_pkts;
 static host_hci_event_fn host_hci_rx_le_meta;
 
@@ -58,13 +58,8 @@ struct host_hci_stats
     uint32_t unknown_events_rxd;
 };
 
-/** The opcode of the current unacked HCI command; 0 if none. */
-uint16_t host_hci_outstanding_opcode;
-
 #define HOST_HCI_TIMEOUT        50      /* Milliseconds. */
 
-static struct os_callout_func host_hci_timer;
-
 /** Dispatch table for incoming HCI events.  Sorted by event code field. */
 struct host_hci_event_dispatch_entry {
     uint8_t hed_event_code;
@@ -74,8 +69,6 @@ struct host_hci_event_dispatch_entry {
 static const struct host_hci_event_dispatch_entry host_hci_event_dispatch[] = {
     { BLE_HCI_EVCODE_DISCONN_CMP, host_hci_rx_disconn_complete },
     { BLE_HCI_EVCODE_ENCRYPT_CHG, host_hci_rx_encrypt_change },
-    { BLE_HCI_EVCODE_COMMAND_COMPLETE, host_hci_rx_cmd_complete },
-    { BLE_HCI_EVCODE_COMMAND_STATUS, host_hci_rx_cmd_status },
     { BLE_HCI_EVCODE_NUM_COMP_PKTS, host_hci_rx_num_completed_pkts },
     { BLE_HCI_EVCODE_LE_META, host_hci_rx_le_meta },
 };
@@ -101,6 +94,24 @@ static const struct host_hci_le_event_dispatch_entry
 #define HOST_HCI_LE_EVENT_DISPATCH_SZ \
     (sizeof host_hci_le_event_dispatch / sizeof host_hci_le_event_dispatch[0])
 
+uint16_t
+host_hci_opcode_join(uint8_t ogf, uint16_t ocf)
+{
+    return (ogf << 10) | ocf;
+}
+
+uint16_t
+host_hci_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc)
+{
+    BLE_HS_DBG_ASSERT(handle <= 0x0fff);
+    BLE_HS_DBG_ASSERT(pb <= 0x03);
+    BLE_HS_DBG_ASSERT(bc <= 0x03);
+
+    return (handle  << 0)   |
+           (pb      << 12)  |
+           (bc      << 14);
+}
+
 static const struct host_hci_event_dispatch_entry *
 host_hci_dispatch_entry_find(uint8_t event_code)
 {
@@ -133,39 +144,6 @@ host_hci_le_dispatch_entry_find(uint8_t event_code)
     return NULL;
 }
 
-void
-host_hci_timer_set(void)
-{
-    int rc;
-
-    rc = os_callout_reset(&host_hci_timer.cf_c,
-                          HOST_HCI_TIMEOUT * OS_TICKS_PER_SEC / 1000);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-}
-
-static void
-host_hci_timer_stop(void)
-{
-    os_callout_stop(&host_hci_timer.cf_c);
-}
-
-static void
-host_hci_timer_exp(void *arg)
-{
-    struct ble_hci_ack ack;
-
-    BLE_HS_DBG_ASSERT(host_hci_outstanding_opcode != 0);
-
-    ack.bha_opcode = host_hci_outstanding_opcode;
-    ack.bha_status = BLE_HS_ETIMEOUT;
-    ack.bha_params = NULL;
-    ack.bha_params_len = 0;
-
-    host_hci_outstanding_opcode = 0;
-    ble_hci_sched_rx_ack(&ack);
-}
-
-
 static int
 host_hci_rx_disconn_complete(uint8_t event_code, uint8_t *data, int len)
 {
@@ -203,12 +181,13 @@ host_hci_rx_encrypt_change(uint8_t event_code, uint8_t *data, int len)
 }
 
 static int
-host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len)
+host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len,
+                         struct ble_hci_ack *out_ack)
 {
-    struct ble_hci_ack ack;
     uint16_t opcode;
-    uint8_t num_pkts;
     uint8_t *params;
+    uint8_t params_len;
+    uint8_t num_pkts;
 
     if (len < BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN) {
         /* XXX: Increment stat. */
@@ -222,37 +201,33 @@ host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len)
     /* XXX: Process num_pkts field. */
     (void)num_pkts;
 
-    if (opcode != BLE_HCI_OPCODE_NOP &&
-        opcode != host_hci_outstanding_opcode) {
+    out_ack->bha_opcode = opcode;
 
-        STATS_INC(ble_hs_stats, hci_invalid_ack);
-        return BLE_HS_ENOENT;
-    }
-
-    if (opcode == host_hci_outstanding_opcode) {
-        /* Mark the outstanding command as acked. */
-        host_hci_outstanding_opcode = 0;
-        host_hci_timer_stop();
+    params_len = len - BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
+    if (params_len > 0) {
+        out_ack->bha_status = BLE_HS_HCI_ERR(params[0]);
+    } else if (opcode == BLE_HCI_OPCODE_NOP) {
+        out_ack->bha_status = 0;
+    } else {
+        out_ack->bha_status = BLE_HS_ECONTROLLER;
     }
 
-    ack.bha_opcode = opcode;
-    ack.bha_params = params;
-    ack.bha_params_len = len - BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
-    if (ack.bha_params_len > 0) {
-        ack.bha_status = BLE_HS_HCI_ERR(params[0]);
+    /* Don't include the status byte in the parameters blob. */
+    if (params_len > 1) {
+        out_ack->bha_params = params + 1;
+        out_ack->bha_params_len = params_len - 1;
     } else {
-        ack.bha_status = BLE_HS_ECONTROLLER;
+        out_ack->bha_params = NULL;
+        out_ack->bha_params_len = 0;
     }
 
-    ble_hci_sched_rx_ack(&ack);
-
     return 0;
 }
 
 static int
-host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len)
+host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len,
+                       struct ble_hci_ack *out_ack)
 {
-    struct ble_hci_ack ack;
     uint16_t opcode;
     uint8_t num_pkts;
     uint8_t status;
@@ -269,26 +244,10 @@ host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len)
     /* XXX: Process num_pkts field. */
     (void)num_pkts;
 
-    /* XXX: This check might be overaggressive for the command status event. */
-    if (opcode != BLE_HCI_OPCODE_NOP &&
-        opcode != host_hci_outstanding_opcode) {
-
-        STATS_INC(ble_hs_stats, hci_invalid_ack);
-        return BLE_HS_ENOENT;
-    }
-
-    if (opcode == host_hci_outstanding_opcode) {
-        /* Mark the outstanding command as acked. */
-        host_hci_outstanding_opcode = 0;
-        host_hci_timer_stop();
-    }
-
-    ack.bha_opcode = opcode;
-    ack.bha_params = NULL;
-    ack.bha_params_len = 0;
-    ack.bha_status = BLE_HS_HCI_ERR(status);
-
-    ble_hci_sched_rx_ack(&ack);
+    out_ack->bha_opcode = opcode;
+    out_ack->bha_params = NULL;
+    out_ack->bha_params_len = 0;
+    out_ack->bha_status = BLE_HS_HCI_ERR(status);
 
     return 0;
 }
@@ -318,7 +277,9 @@ host_hci_rx_num_completed_pkts(uint8_t event_code, uint8_t *data, int len)
         handle = le16toh(data + off + 2 * i);
         num_pkts = le16toh(data + off + 2 * num_handles + 2 * i);
 
-        ble_hs_conn_rx_num_completed_pkts(handle, num_pkts);
+        /* XXX: Do something with these values. */
+        (void)handle;
+        (void)num_pkts;
     }
 
     return 0;
@@ -596,7 +557,7 @@ host_hci_event_rx(uint8_t *data)
     int rc;
 
     /* Count events received */
-    STATS_INC(ble_hs_stats, hci_cmd);
+    STATS_INC(ble_hs_stats, hci_event);
 
     /* Display to console */
     host_hci_dbg_event_disp(data);
@@ -637,28 +598,197 @@ host_hci_os_event_proc(struct os_event *ev)
     return rc;
 }
 
+static uint8_t *ble_hci_ack_ev;
+static struct os_sem ble_hci_sem;
+
+#if PHONY_HCI_ACKS
+static ble_hci_phony_ack_fn *ble_hci_phony_ack_cb;
+#endif
+
+#if PHONY_HCI_ACKS
+void
+ble_hci_set_phony_ack_cb(ble_hci_phony_ack_fn *cb)
+{
+    ble_hci_phony_ack_cb = cb;
+}
+#endif
+
 /* XXX: For now, put this here */
 int
 ble_hci_transport_ctlr_event_send(uint8_t *hci_ev)
 {
-    os_error_t err;
     struct os_event *ev;
+    os_error_t err;
+    int enqueue;
 
     BLE_HS_DBG_ASSERT(hci_ev != NULL);
 
-    /* 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_cmd_pool, hci_ev);
-        BLE_HS_DBG_ASSERT_EVAL(err == OS_OK);
-        return -1;
+    switch (hci_ev[0]) {
+    case BLE_HCI_EVCODE_COMMAND_COMPLETE:
+    case BLE_HCI_EVCODE_COMMAND_STATUS:
+        if (hci_ev[3] == 0 && hci_ev[4] == 0) {
+            enqueue = 1;
+        } else {
+            if (ble_hci_ack_ev != NULL) {
+                /* The controller sent two acks.  Free the first one. */
+                BLE_HS_DBG_ASSERT(0);
+
+                err = os_memblock_put(&g_hci_cmd_pool, ble_hci_ack_ev);
+                BLE_HS_DBG_ASSERT_EVAL(err == OS_OK);
+            }
+
+            ble_hci_ack_ev = hci_ev;
+            os_sem_release(&ble_hci_sem);
+            enqueue = 0;
+        }
+        break;
+
+    default:
+        enqueue = 1;
+        break;
     }
 
-    /* Fill out the event and post to Link Layer */
-    ev->ev_queued = 0;
-    ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_EVENT;
-    ev->ev_arg = hci_ev;
-    os_eventq_put(&ble_hs_evq, 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_cmd_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);
+    }
+
+    return 0;
+}
+
+static int
+ble_hci_process_ack(uint8_t *params_buf, uint8_t params_buf_len,
+                    struct ble_hci_ack *out_ack)
+{
+    uint8_t event_code;
+    uint8_t param_len;
+    uint8_t event_len;
+    int rc;
+
+    BLE_HS_DBG_ASSERT(ble_hci_ack_ev != NULL);
+
+    /* Count events received */
+    STATS_INC(ble_hs_stats, hci_event);
+
+    /* Display to console */
+    host_hci_dbg_event_disp(ble_hci_ack_ev);
+
+    event_code = ble_hci_ack_ev[0];
+    param_len = ble_hci_ack_ev[1];
+    event_len = param_len + 2;
+
+    /* Clear ack fields up front to silence spurious gcc warnings. */
+    memset(out_ack, 0, sizeof *out_ack);
+
+    switch (event_code) {
+    case BLE_HCI_EVCODE_COMMAND_COMPLETE:
+        rc = host_hci_rx_cmd_complete(event_code, ble_hci_ack_ev, event_len,
+                                      out_ack);
+        break;
+
+    case BLE_HCI_EVCODE_COMMAND_STATUS:
+        rc = host_hci_rx_cmd_status(event_code, ble_hci_ack_ev, event_len,
+                                    out_ack);
+        break;
+
+    default:
+        BLE_HS_DBG_ASSERT(0);
+        rc = BLE_HS_EUNKNOWN;
+        break;
+    }
+
+    if (rc == 0) {
+        if (params_buf == NULL) {
+            out_ack->bha_params_len = 0;
+        } else {
+            if (out_ack->bha_params_len > params_buf_len) {
+                out_ack->bha_params_len = params_buf_len;
+                rc = BLE_HS_EMSGSIZE;
+            }
+            memcpy(params_buf, out_ack->bha_params, out_ack->bha_params_len);
+        }
+        out_ack->bha_params = params_buf;
+    }
+
+    os_memblock_put(&g_hci_cmd_pool, ble_hci_ack_ev);
+    ble_hci_ack_ev = NULL;
+
+    return rc;
+}
+
+static int
+ble_hci_wait_for_ack(void)
+{
+    int rc;
+
+#if PHONY_HCI_ACKS
+    if (ble_hci_phony_ack_cb == NULL) {
+        rc = BLE_HS_ETIMEOUT;
+    } else {
+        BLE_HS_DBG_ASSERT(ble_hci_ack_ev == NULL);
+        ble_hci_ack_ev = os_memblock_get(&g_hci_cmd_pool);
+        if (ble_hci_ack_ev == NULL) {
+            rc = BLE_HS_ENOMEM;
+        } else {
+            rc = ble_hci_phony_ack_cb(ble_hci_ack_ev, 260);
+        }
+    }
+#else
+    rc = os_sem_pend(&ble_hci_sem, BLE_HCI_TIMEOUT);
+#endif
+
+    return rc;
+}
+
+int
+ble_hci_tx_cmd(void *cmd, void *evt_buf, uint8_t evt_buf_len,
+               uint8_t *out_evt_buf_len)
+{
+    struct ble_hci_ack ack;
+    int rc;
+
+    rc = host_hci_cmd_send_buf(cmd);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = ble_hci_wait_for_ack();
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = ble_hci_process_ack(evt_buf, evt_buf_len, &ack);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (out_evt_buf_len != NULL) {
+        *out_evt_buf_len = ack.bha_params_len;
+    }
+
+    return ack.bha_status;
+}
+
+int
+ble_hci_tx_cmd_empty_ack(void *cmd)
+{
+    int rc;
+
+    rc = ble_hci_tx_cmd(cmd, NULL, 0, NULL);
+    if (rc != 0) {
+        return rc;
+    }
 
     return 0;
 }
@@ -717,7 +847,7 @@ host_hci_data_rx(struct os_mbuf *om)
         } else {
             handle = BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc);
 
-            ble_hs_conn_lock();
+            ble_hs_lock();
 
             conn = ble_hs_conn_find(handle);
             if (conn == NULL) {
@@ -727,7 +857,7 @@ host_hci_data_rx(struct os_mbuf *om)
                 om = NULL;
             }
 
-            ble_hs_conn_unlock();
+            ble_hs_unlock();
         }
     }
 
@@ -746,24 +876,6 @@ host_hci_data_rx(struct os_mbuf *om)
     return rc;
 }
 
-uint16_t
-host_hci_opcode_join(uint8_t ogf, uint16_t ocf)
-{
-    return (ogf << 10) | ocf;
-}
-
-uint16_t
-host_hci_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc)
-{
-    BLE_HS_DBG_ASSERT(handle <= 0x0fff);
-    BLE_HS_DBG_ASSERT(pb <= 0x03);
-    BLE_HS_DBG_ASSERT(bc <= 0x03);
-
-    return (handle  << 0)   |
-           (pb      << 12)  |
-           (bc      << 14);
-}
-
 static struct os_mbuf *
 host_hci_data_hdr_prepend(struct os_mbuf *om, uint16_t handle, uint8_t pb_flag)
 {
@@ -820,8 +932,8 @@ host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *om)
 void
 host_hci_init(void)
 {
-    host_hci_outstanding_opcode = 0;
+    int rc;
 
-    os_callout_func_init(&host_hci_timer, &ble_hs_evq,
-                         host_hci_timer_exp, NULL);
+    rc = os_sem_init(&ble_hci_sem, 0);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 dd7e14d..180571d 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -63,9 +63,6 @@ host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, void *cmddata)
     uint8_t *cmd;
     uint16_t opcode;
 
-    /* Don't allow multiple commands "in flight." */
-    BLE_HS_DBG_ASSERT(host_hci_outstanding_opcode == 0);
-
     rc = -1;
     cmd = os_memblock_get(&g_hci_cmd_pool);
     if (cmd) {
@@ -78,15 +75,11 @@ host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, void *cmddata)
         rc = host_hci_cmd_transport(cmd);
         BLE_HS_LOG(DEBUG, "host_hci_cmd_send: ogf=0x%02x ocf=0x%02x len=%d\n",
                    ogf, ocf, len);
-        if (rc == 0) {
-            host_hci_outstanding_opcode = opcode;
-        }
+        ble_hs_misc_log_flat_buf(cmd, len + BLE_HCI_CMD_HDR_LEN);
+        BLE_HS_LOG(DEBUG, "\n");
     }
 
-    /* Cancel ack callback if transmission failed. */
-    if (rc != 0) {
-        ble_hci_sched_set_ack_cb(NULL, NULL);
-    } else {
+    if (rc == 0) {
         STATS_INC(ble_hs_stats, hci_cmd);
     }
 
@@ -463,13 +456,34 @@ host_hci_cmd_rd_bd_addr(void)
     return rc;
 }
 
+static void
+host_hci_cmd_body_set_event_mask(uint64_t event_mask, uint8_t *dst)
+{
+    htole64(dst, event_mask);
+}
+
+void
+host_hci_cmd_build_set_event_mask(uint64_t event_mask,
+                                  uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_EVENT_MASK_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_CTLR_BASEBAND,
+                       BLE_HCI_OCF_CB_SET_EVENT_MASK,
+                       BLE_HCI_SET_EVENT_MASK_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    host_hci_cmd_body_set_event_mask(event_mask, dst);
+}
+
 int
 host_hci_cmd_set_event_mask(uint64_t event_mask)
 {
     int rc;
     uint8_t cmd[BLE_HCI_SET_EVENT_MASK_LEN];
 
-    htole64(cmd, event_mask);
+    host_hci_cmd_body_set_event_mask(event_mask, cmd);
     rc = host_hci_cmd_send(BLE_HCI_OGF_CTLR_BASEBAND,
                            BLE_HCI_OCF_CB_SET_EVENT_MASK,
                            BLE_HCI_SET_EVENT_MASK_LEN,
@@ -524,13 +538,35 @@ host_hci_cmd_rd_rem_version(uint16_t handle)
     return rc;
 }
 
+static void
+host_hci_cmd_body_le_set_event_mask(uint64_t event_mask, uint8_t *dst)
+{
+    htole64(dst, event_mask);
+}
+
+void
+host_hci_cmd_build_le_set_event_mask(uint64_t event_mask,
+                                     uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_LE_EVENT_MASK_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE,
+                       BLE_HCI_OCF_LE_SET_EVENT_MASK,
+                       BLE_HCI_SET_LE_EVENT_MASK_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    host_hci_cmd_body_le_set_event_mask(event_mask, dst);
+}
+
 int
 host_hci_cmd_le_set_event_mask(uint64_t event_mask)
 {
+    uint8_t cmd[BLE_HCI_SET_LE_EVENT_MASK_LEN];
+
     int rc;
-    uint8_t cmd[sizeof(uint64_t)];
 
-    htole64(cmd, event_mask);
+    host_hci_cmd_body_le_set_event_mask(event_mask, cmd);
     rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_EVENT_MASK, sizeof(uint64_t),
                               cmd);
 
@@ -545,6 +581,21 @@ host_hci_cmd_le_set_event_mask(uint64_t event_mask)
  *
  * @return int
  */
+void
+host_hci_cmd_build_le_read_buffer_size(uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CMD_HDR_LEN);
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_BUF_SIZE, 0, dst);
+}
+
+/**
+ * LE Read buffer size
+ *  
+ * OGF = 0x08 (LE) 
+ * OCF = 0x0002 
+ * 
+ * @return int 
+ */
 int
 host_hci_cmd_le_read_buffer_size(void)
 {
@@ -642,6 +693,17 @@ host_hci_cmd_le_write_sugg_datalen(uint16_t txoctets, uint16_t txtime)
 /**
  * OGF=LE, OCF=0x0003
  */
+void
+host_hci_cmd_build_le_read_loc_supp_feat(uint8_t *dst, uint8_t dst_len)
+{
+    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CMD_HDR_LEN);
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT,
+                       0, dst);
+}
+
+/**
+ * OGF=LE, OCF=0x0003
+ */
 int
 host_hci_cmd_le_read_loc_supp_feat(void)
 {
@@ -668,7 +730,7 @@ host_hci_cmd_le_read_rem_used_feat(uint16_t handle)
 }
 
 static void
-host_hci_cmd_le_body_set_adv_enable(uint8_t enable, uint8_t *dst)
+host_hci_cmd_body_le_set_adv_enable(uint8_t enable, uint8_t *dst)
 {
     dst[0] = enable;
 }
@@ -684,7 +746,7 @@ host_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst,
                        BLE_HCI_SET_ADV_ENABLE_LEN, dst);
     dst += BLE_HCI_CMD_HDR_LEN;
 
-    host_hci_cmd_le_body_set_adv_enable(enable, dst);
+    host_hci_cmd_body_le_set_adv_enable(enable, dst);
 }
 
 int
@@ -693,7 +755,7 @@ host_hci_cmd_le_set_adv_enable(uint8_t enable)
     int rc;
     uint8_t cmd[BLE_HCI_SET_ADV_ENABLE_LEN];
 
-    host_hci_cmd_le_body_set_adv_enable(enable, cmd);
+    host_hci_cmd_body_le_set_adv_enable(enable, cmd);
     rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_SET_ADV_ENABLE,
                               BLE_HCI_SET_ADV_ENABLE_LEN, cmd);
 
@@ -936,7 +998,7 @@ host_hci_cmd_le_create_connection(struct hci_create_conn *hcc)
 }
 
 void
-host_hci_cmd_le_build_clear_whitelist(uint8_t *dst, int dst_len)
+host_hci_cmd_build_le_clear_whitelist(uint8_t *dst, int dst_len)
 {
     BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CMD_HDR_LEN);
     host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CLEAR_WHITE_LIST,
@@ -1031,6 +1093,14 @@ host_hci_cmd_le_rmv_from_whitelist(uint8_t *addr, uint8_t addr_type)
     return rc;
 }
 
+void
+host_hci_cmd_build_reset(uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CMD_HDR_LEN);
+    host_hci_write_hdr(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_RESET,
+                       0, dst);
+}
+
 /**
  * Reset the controller and link manager.
  *
@@ -1143,6 +1213,42 @@ host_hci_cmd_le_conn_update(struct hci_conn_update *hcu)
     return 0;
 }
 
+static void
+host_hci_cmd_body_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr,
+                                      uint8_t *dst)
+{
+    htole16(dst + 0, hkr->conn_handle);
+    memcpy(dst + 2, hkr->long_term_key, sizeof hkr->long_term_key);
+}
+
+/**
+ * Sends the long-term key (LTK) to the controller.
+ *
+ * Note: This function expects the 128-bit key to be in little-endian byte
+ * order.
+ *
+ * OGF = 0x08 (LE)
+ * OCF = 0x001a
+ *
+ * @param key
+ * @param pt
+ *
+ * @return int
+ */
+void
+host_hci_cmd_build_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr,
+                                       uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_LT_KEY_REQ_REPLY_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY,
+                       BLE_HCI_LT_KEY_REQ_REPLY_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    host_hci_cmd_body_le_lt_key_req_reply(hkr, dst);
+}
+
 /**
  * Sends the long-term key (LTK) to the controller.
  *
@@ -1163,14 +1269,39 @@ host_hci_cmd_le_lt_key_req_reply(struct hci_lt_key_req_reply *hkr)
     uint8_t cmd[BLE_HCI_LT_KEY_REQ_REPLY_LEN];
     int rc;
 
-    htole16(cmd + 0, hkr->conn_handle);
-    memcpy(cmd + 2, hkr->long_term_key, sizeof hkr->long_term_key);
-
+    host_hci_cmd_body_le_lt_key_req_reply(hkr, cmd);
     rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY,
                               sizeof cmd, cmd);
     return rc;
 }
 
+static void
+host_hci_cmd_body_le_conn_param_reply(struct hci_conn_param_reply *hcr,
+                                      uint8_t *dst)
+{
+    htole16(dst + 0, hcr->handle);
+    htole16(dst + 2, hcr->conn_itvl_min);
+    htole16(dst + 4, hcr->conn_itvl_max);
+    htole16(dst + 6, hcr->conn_latency);
+    htole16(dst + 8, hcr->supervision_timeout);
+    htole16(dst + 10, hcr->min_ce_len);
+    htole16(dst + 12, hcr->max_ce_len);
+}
+
+void
+host_hci_cmd_build_le_conn_param_reply(struct hci_conn_param_reply *hcr,
+                                       uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_CONN_PARAM_REPLY_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_REM_CONN_PARAM_RR,
+                       BLE_HCI_CONN_PARAM_REPLY_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    host_hci_cmd_body_le_conn_param_reply(hcr, dst);
+}
+
 int
 host_hci_cmd_le_lt_key_req_neg_reply(uint16_t handle)
 {
@@ -1202,14 +1333,36 @@ host_hci_cmd_le_conn_param_reply(struct hci_conn_param_reply *hcr)
     return rc;
 }
 
+static void
+host_hci_cmd_body_le_conn_param_neg_reply(struct hci_conn_param_neg_reply *hcn,
+                                          uint8_t *dst)
+{
+    htole16(dst + 0, hcn->handle);
+    dst[2] = hcn->reason;
+}
+
+
+void
+host_hci_cmd_build_le_conn_param_neg_reply(
+    struct hci_conn_param_neg_reply *hcn, uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_CONN_PARAM_NEG_REPLY_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR,
+                       BLE_HCI_CONN_PARAM_NEG_REPLY_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    host_hci_cmd_body_le_conn_param_neg_reply(hcn, dst);
+}
+
 int
 host_hci_cmd_le_conn_param_neg_reply(struct hci_conn_param_neg_reply *hcn)
 {
     uint8_t cmd[BLE_HCI_CONN_PARAM_NEG_REPLY_LEN];
     int rc;
 
-    htole16(cmd + 0, hcn->handle);
-    cmd[2] = hcn->reason;
+    host_hci_cmd_body_le_conn_param_neg_reply(hcn, cmd);
 
     rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR,
                               BLE_HCI_CONN_PARAM_NEG_REPLY_LEN, cmd);
@@ -1284,12 +1437,50 @@ host_hci_cmd_le_encrypt(uint8_t *key, uint8_t *pt)
  *
  * @return int
  */
+void
+host_hci_cmd_build_le_rand(uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CMD_HDR_LEN);
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RAND, 0, dst);
+}
+
+/**
+ * Get random data
+ *  
+ * OGF = 0x08 (LE) 
+ * OCF = 0x0018
+ *
+ * @return int
+ */
 int
 host_hci_cmd_le_rand(void)
 {
     return host_hci_le_cmd_send(BLE_HCI_OCF_LE_RAND, 0, NULL);
 }
 
+static void
+host_hci_cmd_body_le_start_encrypt(struct hci_start_encrypt *cmd, uint8_t *dst)
+{
+    htole16(dst + 0, cmd->connection_handle);
+    htole64(dst + 2, cmd->random_number);
+    htole16(dst + 10, cmd->encrypted_diversifier);
+    memcpy(dst + 12, cmd->long_term_key, sizeof cmd->long_term_key);
+}
+
+void
+host_hci_cmd_build_le_start_encrypt(struct hci_start_encrypt *cmd,
+                                    uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_START_ENCRYPT_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_START_ENCRYPT,
+                       BLE_HCI_LE_START_ENCRYPT_LEN, dst);
+    dst += BLE_HCI_CMD_HDR_LEN;
+
+    host_hci_cmd_body_le_start_encrypt(cmd, dst);
+}
+
 /**
  * Enables encryption on a connection.
  *
@@ -1303,10 +1494,7 @@ host_hci_cmd_le_start_encrypt(struct hci_start_encrypt *cmd)
 {
     uint8_t buf[BLE_HCI_LE_START_ENCRYPT_LEN];
 
-    htole16(buf + 0, cmd->connection_handle);
-    htole64(buf + 2, cmd->random_number);
-    htole16(buf + 10, cmd->encrypted_diversifier);
-    memcpy(buf + 12, cmd->long_term_key, sizeof cmd->long_term_key);
+    host_hci_cmd_body_le_start_encrypt(cmd, buf);
 
     return host_hci_le_cmd_send(BLE_HCI_OCF_LE_START_ENCRYPT, sizeof buf, buf);
 }


[37/50] [abbrv] incubator-mynewt-core git commit: add better comments to the spi api

Posted by ma...@apache.org.
add better comments to the spi api


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

Branch: refs/heads/master
Commit: ddcd177b42d4e5ca0de3159c15dd94961ace9375
Parents: c2959dc
Author: Paul Dietrich <pa...@yahoo.com>
Authored: Fri Apr 22 13:19:24 2016 -0700
Committer: Paul Dietrich <pa...@yahoo.com>
Committed: Fri Apr 22 13:19:24 2016 -0700

----------------------------------------------------------------------
 hw/hal/include/hal/hal_spi.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ddcd177b/hw/hal/include/hal/hal_spi.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_spi.h b/hw/hal/include/hal/hal_spi.h
index 6bfbde4..a483563 100644
--- a/hw/hal/include/hal/hal_spi.h
+++ b/hw/hal/include/hal/hal_spi.h
@@ -64,11 +64,15 @@ struct hal_spi_settings {
 struct hal_spi *
 hal_spi_init(enum system_device_id sysid);
 
-/* configure the spi */
+/* configure the spi., Reutrns 0 on success, negative on error */
 int 
 hal_spi_config(struct hal_spi *pspi, struct hal_spi_settings *psettings);
 
-/* do a blocking master spi transfer */
+/* Do a blocking master spi transfer of one SPI data word. 
+ * The data to send is an 8 or 9-bit pattern (depending on configuration) 
+ * stored in <tx>.  NOTE: This does not send multiple bytes. The argument is 
+ * a 16-bit number to allow up to 9-bit SPI data words.
+ * Returns the data received from the remote device or negative on error. */
 int 
 hal_spi_master_transfer(struct hal_spi *psdi, uint16_t tx);
 


[49/50] [abbrv] incubator-mynewt-core git commit: MYNEWT-85: Fix BLE timing for start of connection events. MYNEWT-283: Slave anchor point now set correctly on CRC error.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/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 cecbe60..609242c 100644
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <assert.h>
 #include "os/os.h"
+#include "ble/xcvr.h"
 #include "bsp/cmsis_nvic.h"
 #include "nimble/ble.h"
 #include "nimble/nimble_opt.h"
@@ -48,6 +49,7 @@
 /* Maximum length of frames */
 #define NRF_MAXLEN              (255)
 #define NRF_BALEN               (3)     /* For base address of 3 bytes */
+#define NRF_RX_START_OFFSET     (5)
 
 /* Maximum tx power */
 #define NRF_TX_PWR_MAX_DBM      (4)
@@ -63,6 +65,7 @@ struct ble_phy_obj
     uint8_t phy_transition;
     uint8_t phy_rx_started;
     uint8_t phy_encrypted;
+    uint8_t phy_tx_pyld_len;
     uint32_t phy_access_address;
     struct os_mbuf *rxpdu;
     void *txend_arg;
@@ -89,6 +92,7 @@ STATS_SECT_START(ble_phy_stats)
     STATS_SECT_ENTRY(rx_aborts)
     STATS_SECT_ENTRY(rx_valid)
     STATS_SECT_ENTRY(rx_crc_err)
+    STATS_SECT_ENTRY(rx_late)
     STATS_SECT_ENTRY(no_bufs)
     STATS_SECT_ENTRY(radio_state_errs)
     STATS_SECT_ENTRY(rx_hw_err)
@@ -106,6 +110,7 @@ STATS_NAME_START(ble_phy_stats)
     STATS_NAME(ble_phy_stats, rx_aborts)
     STATS_NAME(ble_phy_stats, rx_valid)
     STATS_NAME(ble_phy_stats, rx_crc_err)
+    STATS_NAME(ble_phy_stats, rx_late)
     STATS_NAME(ble_phy_stats, no_bufs)
     STATS_NAME(ble_phy_stats, radio_state_errs)
     STATS_NAME(ble_phy_stats, rx_hw_err)
@@ -220,8 +225,7 @@ nrf_wait_disabled(void)
 }
 
 /**
- * Setup transceiver for receive
- *
+ * Setup transceiver for receive.
  */
 static void
 ble_phy_rx_xcvr_setup(void)
@@ -245,6 +249,9 @@ ble_phy_rx_xcvr_setup(void)
     NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
 #endif
 
+    /* We dont want to trigger TXEN on output compare match */
+    NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
+
     /* Reset the rx started flag. Used for the wait for response */
     g_ble_phy_data.phy_rx_started = 0;
     g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
@@ -280,7 +287,7 @@ ble_phy_tx_end_isr(void)
 
     /* Log the event */
     ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
-               g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
+               g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[1]);
 
     /* Clear events and clear interrupt on disabled event */
     NRF_RADIO->EVENTS_DISABLED = 0;
@@ -313,14 +320,16 @@ ble_phy_tx_end_isr(void)
         }
 
         /*
-         * Enable the wait for response timer. Note that cc #2 on
-         * timer 0 contains the transmit end time
+         * Enable the wait for response timer. Note that cc #1 on
+         * timer 0 contains the transmit start time
          */
-        wfr_time = NRF_TIMER0->CC[2];
+        wfr_time = NRF_TIMER0->CC[1] - BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
+        wfr_time += BLE_TX_DUR_USECS_M(g_ble_phy_data.phy_tx_pyld_len);
         wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
         ble_ll_wfr_enable(wfr_time);
     } else {
-        /* Better not be going from rx to tx! */
+        /* Disable automatic TXEN */
+        NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
         assert(transition == BLE_PHY_TRANSITION_NONE);
     }
 
@@ -331,147 +340,165 @@ ble_phy_tx_end_isr(void)
 }
 
 static void
-ble_phy_isr(void)
+ble_phy_rx_end_isr(void)
 {
     int rc;
-    uint8_t crcok;
-    uint32_t irq_en;
-    uint32_t state;
     uint8_t *dptr;
+    uint8_t crcok;
     struct os_mbuf *rxpdu;
     struct ble_mbuf_hdr *ble_hdr;
 
-    /* Read irq register to determine which interrupts are enabled */
-    irq_en = NRF_RADIO->INTENCLR;
+    /* Clear events and clear interrupt */
+    NRF_RADIO->EVENTS_END = 0;
+    NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk;
 
-    /* Check for disabled event. This only happens for transmits now */
-    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
-        ble_phy_tx_end_isr();
-    }
+    /* Disable automatic RXEN */
+    NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
 
-    /* We get this if we have started to receive a frame */
-    if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) {
-        /* Clear events and clear interrupt */
-        NRF_RADIO->EVENTS_ADDRESS = 0;
-        NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk;
+    /* Set RSSI and CRC status flag in header */
+    ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+    assert(NRF_RADIO->EVENTS_RSSIEND != 0);
+    ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
 
-        assert(g_ble_phy_data.rxpdu != NULL);
+    dptr = g_ble_phy_data.rxpdu->om_data;
+
+    /* Count PHY crc errors and valid packets */
+    crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
+    if (!crcok) {
+        STATS_INC(ble_phy_stats, rx_crc_err);
+    } else {
+        STATS_INC(ble_phy_stats, rx_valid);
+        ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+        if (g_ble_phy_data.phy_encrypted) {
+            /* Only set MIC failure flag if frame is not zero length */
+            if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
+                ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE;
+            }
 
-        /* Wait to get 1st byte of frame */
-        while (1) {
-            state = NRF_RADIO->STATE;
-            if (NRF_RADIO->EVENTS_BCMATCH != 0) {
-                break;
+            /*
+             * XXX: not sure how to deal with this. This should not
+             * be a MIC failure but we should not hand it up. I guess
+             * this is just some form of rx error and that is how we
+             * handle it? For now, just set CRC error flags
+             */
+            if (NRF_CCM->EVENTS_ERROR) {
+                STATS_INC(ble_phy_stats, rx_hw_err);
+                ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
             }
 
             /*
-             * If state is disabled, we should have the BCMATCH. If not,
-             * something is wrong!
+             * XXX: This is a total hack work-around for now but I dont
+             * know what else to do. If ENDCRYPT is not set and we are
+             * encrypted we need to not trust this frame and drop it.
              */
-            if (state == RADIO_STATE_STATE_Disabled) {
-                NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
-                NRF_RADIO->SHORTS = 0;
-                goto phy_isr_exit;
+            if (NRF_CCM->EVENTS_ENDCRYPT == 0) {
+                STATS_INC(ble_phy_stats, rx_hw_err);
+                ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
             }
         }
+#endif
+    }
 
-        /* Initialize flags, channel and state in ble header at rx start */
-        ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
-        ble_hdr->rxinfo.flags = ble_ll_state_get();
-        ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
-        ble_hdr->rxinfo.handle = 0;
-
-        /* Call Link Layer receive start function */
-        rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
-        if (rc >= 0) {
-            /* Set rx started flag and enable rx end ISR */
-            g_ble_phy_data.phy_rx_started = 1;
-            NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
-        } else {
-            /* Disable PHY */
-            ble_phy_disable();
-            irq_en = 0;
-            STATS_INC(ble_phy_stats, rx_aborts);
-        }
+    /* Call Link Layer receive payload function */
+    rxpdu = g_ble_phy_data.rxpdu;
+    g_ble_phy_data.rxpdu = NULL;
 
-        /* Count rx starts */
-        STATS_INC(ble_phy_stats, rx_starts);
+    /*
+     * XXX: This is a horrible ugly hack to deal with the RAM S1 byte
+     * that is not sent over the air but is present here. Simply move the
+     * data pointer to deal with it. Fix this later. Do this in the nrf52
+     */
+    dptr[2] = dptr[1];
+    dptr[1] = dptr[0];
+    rxpdu->om_data += 1;
+
+    rc = ble_ll_rx_end(rxpdu, ble_hdr);
+    if (rc < 0) {
+        ble_phy_disable();
     }
+}
 
-    /* Receive packet end (we dont enable this for transmit) */
-    if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) {
-        /* Clear events and clear interrupt */
-        NRF_RADIO->EVENTS_END = 0;
-        NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk;
-
-        /* Set RSSI and CRC status flag in header */
-        ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
-        assert(NRF_RADIO->EVENTS_RSSIEND != 0);
-        ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
-        ble_hdr->end_cputime = NRF_TIMER0->CC[2];
-        dptr = g_ble_phy_data.rxpdu->om_data;
-
-        /* Count PHY crc errors and valid packets */
-        crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
-        if (!crcok) {
-            STATS_INC(ble_phy_stats, rx_crc_err);
-        } else {
-            STATS_INC(ble_phy_stats, rx_valid);
-            ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-            if (g_ble_phy_data.phy_encrypted) {
-                /* Only set MIC failure flag if frame is not zero length */
-                if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
-                    ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE;
-                }
-
-                /*
-                 * XXX: not sure how to deal with this. This should not
-                 * be a MIC failure but we should not hand it up. I guess
-                 * this is just some form of rx error and that is how we
-                 * handle it? For now, just set CRC error flags
-                 */
-                if (NRF_CCM->EVENTS_ERROR) {
-                    STATS_INC(ble_phy_stats, rx_hw_err);
-                    ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
-                }
-
-                /*
-                 * XXX: This is a total hack work-around for now but I dont
-                 * know what else to do. If ENDCRYPT is not set and we are
-                 * encrypted we need to not trust this frame and drop it.
-                 */
-                if (NRF_CCM->EVENTS_ENDCRYPT == 0) {
-                    STATS_INC(ble_phy_stats, rx_hw_err);
-                    ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
-                }
-            }
-#endif
-        }
+static void
+ble_phy_rx_start_isr(void)
+{
+    int rc;
+    uint32_t state;
+    struct ble_mbuf_hdr *ble_hdr;
+
+    /* Clear events and clear interrupt */
+    NRF_RADIO->EVENTS_ADDRESS = 0;
+    NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk;
+
+    assert(g_ble_phy_data.rxpdu != NULL);
 
-        /* Call Link Layer receive payload function */
-        rxpdu = g_ble_phy_data.rxpdu;
-        g_ble_phy_data.rxpdu = NULL;
+    /* Wait to get 1st byte of frame */
+    while (1) {
+        state = NRF_RADIO->STATE;
+        if (NRF_RADIO->EVENTS_BCMATCH != 0) {
+            break;
+        }
 
         /*
-         * XXX: This is a horrible ugly hack to deal with the RAM S1 byte
-         * that is not sent over the air but is present here. Simply move the
-         * data pointer to deal with it. Fix this later. Do this in the nrf52
+         * If state is disabled, we should have the BCMATCH. If not,
+         * something is wrong!
          */
-        dptr[2] = dptr[1];
-        dptr[1] = dptr[0];
-        rxpdu->om_data += 1;
-
-        rc = ble_ll_rx_end(rxpdu, ble_hdr);
-        if (rc < 0) {
-            /* Disable the PHY. */
-            ble_phy_disable();
+        if (state == RADIO_STATE_STATE_Disabled) {
+            NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
+            NRF_RADIO->SHORTS = 0;
+            return;
         }
     }
 
-phy_isr_exit:
+    /* Initialize flags, channel and state in ble header at rx start */
+    ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+    ble_hdr->rxinfo.flags = ble_ll_state_get();
+    ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
+    ble_hdr->rxinfo.handle = 0;
+    ble_hdr->beg_cputime = NRF_TIMER0->CC[1] -
+        BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
+
+    /* Call Link Layer receive start function */
+    rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
+    if (rc >= 0) {
+        /* Set rx started flag and enable rx end ISR */
+        g_ble_phy_data.phy_rx_started = 1;
+        NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
+    } else {
+        /* Disable PHY */
+        ble_phy_disable();
+        STATS_INC(ble_phy_stats, rx_aborts);
+    }
+
+    /* Count rx starts */
+    STATS_INC(ble_phy_stats, rx_starts);
+}
+
+static void
+ble_phy_isr(void)
+{
+    uint32_t irq_en;
+
+    /* Read irq register to determine which interrupts are enabled */
+    irq_en = NRF_RADIO->INTENCLR;
+
+    /* Check for disabled event. This only happens for transmits now */
+    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
+        ble_phy_tx_end_isr();
+    }
+
+    /* We get this if we have started to receive a frame */
+    if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) {
+        ble_phy_rx_start_isr();
+    }
+
+    /* Receive packet end (we dont enable this for transmit) */
+    if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) {
+        ble_phy_rx_end_isr();
+    }
+
     /* Ensures IRQ is cleared */
-    state = NRF_RADIO->SHORTS;
+    irq_en = NRF_RADIO->SHORTS;
 
     /* Count # of interrupts */
     STATS_INC(ble_phy_stats, phy_isrs);
@@ -538,11 +565,8 @@ ble_phy_init(void)
     /* Configure IFS */
     NRF_RADIO->TIFS = BLE_LL_IFS;
 
-    /*
-     * Enable the pre-programmed PPI to capture the time when a receive
-     * or transmit ends
-     */
-    NRF_PPI->CHENSET = PPI_CHEN_CH27_Msk;
+    /* Captures tx/rx start in timer0 capture 1 */
+    NRF_PPI->CHENSET = PPI_CHEN_CH26_Msk;
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
     NRF_CCM->INTENCLR = 0xffffffff;
@@ -603,8 +627,12 @@ ble_phy_rx(void)
     /* Setup for rx */
     ble_phy_rx_xcvr_setup();
 
-    /* Start the receive task in the radio */
-    NRF_RADIO->TASKS_RXEN = 1;
+    /* Start the receive task in the radio if not automatically going to rx */
+    if ((NRF_PPI->CHEN & PPI_CHEN_CH21_Msk) == 0) {
+        NRF_RADIO->TASKS_RXEN = 1;
+    }
+
+    ble_ll_log(BLE_LL_LOG_ID_PHY_RX, g_ble_phy_data.phy_encrypted, 0, 0);
 
     return 0;
 }
@@ -656,11 +684,76 @@ ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg)
     g_ble_phy_data.txend_arg = arg;
 }
 
+/**
+ * Called to set the start time of a transmission.
+ *
+ * This function is called to set the start time when we are not going from
+ * rx to tx automatically.
+ *
+ * NOTE: care must be taken when calling this function. The channel should
+ * already be set.
+ *
+ * @param cputime
+ *
+ * @return int
+ */
+int
+ble_phy_tx_set_start_time(uint32_t cputime)
+{
+    int rc;
+
+    NRF_TIMER0->CC[0] = cputime;
+    NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk;
+    NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
+    if ((int32_t)(cputime_get32() - cputime) >= 0) {
+        STATS_INC(ble_phy_stats, tx_late);
+        ble_phy_disable();
+        rc =  BLE_PHY_ERR_TX_LATE;
+    } else {
+        rc = 0;
+    }
+    return rc;
+}
+
+/**
+ * Called to set the start time of a reception
+ *
+ * This function acts a bit differently than transmit. If we are late getting
+ * here we will still attempt to receive.
+ *
+ * NOTE: care must be taken when calling this function. The channel should
+ * already be set.
+ *
+ * @param cputime
+ *
+ * @return int
+ */
+int
+ble_phy_rx_set_start_time(uint32_t cputime)
+{
+    int rc;
+
+    NRF_TIMER0->CC[0] = cputime;
+    NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
+    NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk;
+    if ((int32_t)(cputime_get32() - cputime) >= 0) {
+        STATS_INC(ble_phy_stats, rx_late);
+        NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
+        NRF_RADIO->TASKS_RXEN = 1;
+        rc =  BLE_PHY_ERR_TX_LATE;
+    } else {
+        rc = 0;
+    }
+    return rc;
+}
+
+
 int
-ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
+ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
 {
     int rc;
     uint8_t *dptr;
+    uint8_t payload_len;
     uint32_t state;
     uint32_t shortcuts;
     struct ble_mbuf_hdr *ble_hdr;
@@ -668,37 +761,18 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
     /* Better have a pdu! */
     assert(txpdu != NULL);
 
-    /* If radio is not disabled, */
+    /*
+     * This check is to make sure that the radio is not in a state where
+     * it is moving to disabled state. If so, let it get there.
+     */
     nrf_wait_disabled();
 
-    if (beg_trans == BLE_PHY_TRANSITION_RX_TX) {
-        if ((NRF_RADIO->SHORTS & RADIO_SHORTS_DISABLED_TXEN_Msk) == 0) {
-            assert(0);
-        }
-        /* Radio better be in TXRU state or we are in bad shape */
-        state = RADIO_STATE_STATE_TxRu;
-    } else {
-        /* Radio should be in disabled state */
-        state = RADIO_STATE_STATE_Disabled;
-    }
-
-    if (NRF_RADIO->STATE != state) {
-        ble_phy_disable();
-        STATS_INC(ble_phy_stats, radio_state_errs);
-        return BLE_PHY_ERR_RADIO_STATE;
-    }
+    ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
+    payload_len = ble_hdr->txinfo.pyld_len;
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
     if (g_ble_phy_data.phy_encrypted) {
-        /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
-        ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
         dptr = (uint8_t *)&g_ble_phy_enc_buf[0];
-        dptr[0] = ble_hdr->txinfo.hdr_byte;
-        dptr[1] = ble_hdr->txinfo.pyld_len;
-        dptr[2] = 0;
-        dptr += 3;
-
-        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
         NRF_CCM->SHORTS = 1;
         NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
         NRF_CCM->OUTPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
@@ -709,27 +783,18 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
         NRF_PPI->CHENCLR = PPI_CHEN_CH25_Msk;
         NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk;
     } else {
-        /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
-        ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
         dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
-        dptr[0] = ble_hdr->txinfo.hdr_byte;
-        dptr[1] = ble_hdr->txinfo.pyld_len;
-        dptr[2] = 0;
-        dptr += 3;
-
-        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
     }
 #else
-    /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
-    ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
     dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
+#endif
+
+    /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
     dptr[0] = ble_hdr->txinfo.hdr_byte;
-    dptr[1] = ble_hdr->txinfo.pyld_len;
+    dptr[1] = payload_len;
     dptr[2] = 0;
     dptr += 3;
-
     NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
-#endif
 
     /* Clear the ready, end and disabled events */
     NRF_RADIO->EVENTS_READY = 0;
@@ -747,36 +812,26 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
     NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
     NRF_RADIO->SHORTS = shortcuts;
 
-    /* Trigger transmit if our state was disabled */
-    if (state == RADIO_STATE_STATE_Disabled) {
-        NRF_RADIO->TASKS_TXEN = 1;
-    }
+    /* Set transmitted payload length */
+    g_ble_phy_data.phy_tx_pyld_len = payload_len;
 
     /* Set the PHY transition */
     g_ble_phy_data.phy_transition = end_trans;
 
-    /* Read back radio state. If in TXRU, we are fine */
+    /* If we already started transmitting, abort it! */
     state = NRF_RADIO->STATE;
-    if (state == RADIO_STATE_STATE_TxRu) {
+    if (state != RADIO_STATE_STATE_Tx) {
         /* Copy data from mbuf into transmit buffer */
-        os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset,
-                         ble_hdr->txinfo.pyld_len, dptr);
+        os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset, payload_len, dptr);
 
         /* Set phy state to transmitting and count packet statistics */
         g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
         STATS_INC(ble_phy_stats, tx_good);
-        STATS_INCN(ble_phy_stats, tx_bytes,
-                   ble_hdr->txinfo.pyld_len + BLE_LL_PDU_HDR_LEN);
+        STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN);
         rc = BLE_ERR_SUCCESS;
     } else {
-        if (state == RADIO_STATE_STATE_Tx) {
-            STATS_INC(ble_phy_stats, tx_late);
-        } else {
-            STATS_INC(ble_phy_stats, tx_fail);
-        }
-
-        /* Frame failed to transmit */
         ble_phy_disable();
+        STATS_INC(ble_phy_stats, tx_late);
         rc = BLE_PHY_ERR_RADIO_STATE;
     }
 
@@ -916,6 +971,7 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit)
  *  -> Turn off all phy interrupts.
  *  -> Disable internal shortcuts.
  *  -> Disable the radio.
+ *  -> Make sure we wont automatically go to rx/tx on output compare
  *  -> Sets phy state to idle.
  *  -> Clears any pending irqs in the NVIC. Might not be necessary but we do
  *  it as a precaution.
@@ -928,6 +984,7 @@ ble_phy_disable(void)
     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
     NRF_RADIO->SHORTS = 0;
     NRF_RADIO->TASKS_DISABLE = 1;
+    NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk | PPI_CHEN_CH20_Msk;
     NVIC_ClearPendingIRQ(RADIO_IRQn);
     g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/net/nimble/include/nimble/ble.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h
index 894dff4..c0b5b74 100644
--- a/net/nimble/include/nimble/ble.h
+++ b/net/nimble/include/nimble/ble.h
@@ -88,7 +88,7 @@ struct ble_mbuf_hdr
         struct ble_mbuf_hdr_rxinfo rxinfo;
         struct ble_mbuf_hdr_txinfo txinfo;
     };
-    uint32_t end_cputime;
+    uint32_t beg_cputime;
 };
 
 /*


[45/50] [abbrv] incubator-mynewt-core git commit: nrfxx gpio; gpio_toggle() was not changing the value back to 0.

Posted by ma...@apache.org.
nrfxx gpio; gpio_toggle() was not changing the value back to 0.


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

Branch: refs/heads/master
Commit: 546cf5e3c0bc0b48590f9aaf3128b9833d8f9948
Parents: 0187902
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Tue Apr 26 12:02:53 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Tue Apr 26 12:02:53 2016 -0700

----------------------------------------------------------------------
 hw/mcu/nordic/nrf51xxx/src/hal_gpio.c | 2 +-
 hw/mcu/nordic/nrf52xxx/src/hal_gpio.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/546cf5e3/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c b/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c
index 6aac418..bd8414a 100644
--- a/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c
+++ b/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c
@@ -428,7 +428,7 @@ int hal_gpio_read(int pin)
  */
 int hal_gpio_toggle(int pin)
 {
-    int pin_state = (hal_gpio_read(pin) != 1);
+    int pin_state = (hal_gpio_read(pin) == 0);
     hal_gpio_write(pin, pin_state);
     return pin_state;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/546cf5e3/hw/mcu/nordic/nrf52xxx/src/hal_gpio.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_gpio.c b/hw/mcu/nordic/nrf52xxx/src/hal_gpio.c
index 3619753..d803ec0 100644
--- a/hw/mcu/nordic/nrf52xxx/src/hal_gpio.c
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_gpio.c
@@ -428,7 +428,7 @@ int hal_gpio_read(int pin)
  */
 int hal_gpio_toggle(int pin)
 {
-    int pin_state = (hal_gpio_read(pin) != 1);
+    int pin_state = (hal_gpio_read(pin) == 0);
     hal_gpio_write(pin, pin_state);
     return pin_state;
 }


[24/50] [abbrv] incubator-mynewt-core git commit: ble host - clarify locking restrictions.

Posted by ma...@apache.org.
ble host - clarify locking restrictions.


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

Branch: refs/heads/master
Commit: 61458e37bf166ecb85c292485bd72e095cc46b4d
Parents: 3befe37
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 20 12:27:36 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 20 16:11:45 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_att.c           |  37 ++--
 net/nimble/host/src/ble_att_clt.c       | 180 +------------------
 net/nimble/host/src/ble_att_priv.h      |   3 +-
 net/nimble/host/src/ble_att_svr.c       | 156 ++---------------
 net/nimble/host/src/ble_gap.c           | 248 +++++----------------------
 net/nimble/host/src/ble_gattc.c         |  59 +++++--
 net/nimble/host/src/ble_gatts.c         | 105 ------------
 net/nimble/host/src/ble_hs.c            |  47 +++--
 net/nimble/host/src/ble_hs_adv.c        |   2 -
 net/nimble/host/src/ble_hs_atomic.c     |  21 +++
 net/nimble/host/src/ble_hs_atomic.h     |   5 +
 net/nimble/host/src/ble_hs_conn.c       |  68 +-------
 net/nimble/host/src/ble_hs_conn.h       |   1 -
 net/nimble/host/src/ble_hs_misc.c       |   8 -
 net/nimble/host/src/ble_hs_priv.h       |  12 +-
 net/nimble/host/src/ble_l2cap.c         |  41 -----
 net/nimble/host/src/ble_l2cap_sig.c     |  29 +++-
 net/nimble/host/src/ble_l2cap_sig_cmd.c |   4 -
 net/nimble/host/src/ble_l2cap_sm.c      |  43 +++--
 net/nimble/host/src/test/ble_os_test.c  |  48 ++++--
 20 files changed, 270 insertions(+), 847 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att.c b/net/nimble/host/src/ble_att.c
index 74679f7..379ed48 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -22,7 +22,7 @@
 #include "bsp/bsp.h"
 #include "ble_hs_priv.h"
 
-bssnz_t uint8_t ble_att_flat_buf[BLE_ATT_ATTR_MAX_LEN];
+static bssnz_t uint8_t ble_att_flat_buf[BLE_ATT_ATTR_MAX_LEN];
 
 static uint16_t ble_att_preferred_mtu;
 
@@ -125,9 +125,6 @@ STATS_NAME_START(ble_att_stats)
     STATS_NAME(ble_att_stats, write_cmd_tx)
 STATS_NAME_END(ble_att_stats)
 
-/**
- * Lock restrictions: None.
- */
 static const struct ble_att_rx_dispatch_entry *
 ble_att_rx_dispatch_entry_find(uint8_t op)
 {
@@ -148,9 +145,6 @@ ble_att_rx_dispatch_entry_find(uint8_t op)
     return NULL;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 int
 ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
                        struct ble_l2cap_chan **out_chan)
@@ -396,6 +390,17 @@ ble_att_inc_rx_stat(uint8_t att_op)
     }
 }
 
+/**
+ * Retrieves a pointer to the global ATT flat buffer.  This buffer is only used
+ * by the host parent task, so users can assume exclusive access.
+ */
+uint8_t *
+ble_att_get_flat_buf(void)
+{
+    BLE_HS_DBG_ASSERT(ble_hs_is_app_task());
+    return ble_att_flat_buf;
+}
+
 uint16_t
 ble_att_mtu(uint16_t conn_handle)
 {
@@ -417,9 +422,6 @@ ble_att_mtu(uint16_t conn_handle)
     return mtu;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 static int
 ble_att_rx(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -447,9 +449,6 @@ ble_att_rx(uint16_t conn_handle, struct os_mbuf **om)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 void
 ble_att_set_notify_cb(ble_att_svr_notify_fn *cb, void *cb_arg)
 {
@@ -457,9 +456,6 @@ ble_att_set_notify_cb(ble_att_svr_notify_fn *cb, void *cb_arg)
     ble_att_svr_notify_cb_arg = cb_arg;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 void
 ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu)
 {
@@ -470,9 +466,6 @@ ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu)
     chan->blc_peer_mtu = peer_mtu;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_att_set_preferred_mtu(uint16_t mtu)
 {
@@ -490,9 +483,6 @@ ble_att_set_preferred_mtu(uint16_t mtu)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 struct ble_l2cap_chan *
 ble_att_create_chan(void)
 {
@@ -511,9 +501,6 @@ ble_att_create_chan(void)
     return chan;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_att_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_att_clt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_clt.c b/net/nimble/host/src/ble_att_clt.c
index 19af956..1a95bdc 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -26,9 +26,6 @@
 #include "host/ble_uuid.h"
 #include "ble_hs_priv.h"
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_init_req(uint16_t initial_sz, struct os_mbuf **out_txom)
 {
@@ -58,10 +55,6 @@ err:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_att_clt_append_blob(uint16_t conn_handle, struct os_mbuf *txom,
                         void *blob, int blob_len)
@@ -93,13 +86,11 @@ ble_att_clt_append_blob(uint16_t conn_handle, struct os_mbuf *txom,
     return 0;
 }
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_copy_attr_to_flatbuf(struct os_mbuf *om, void **out_attr_val,
                                  uint16_t *out_attr_len)
 {
+    uint8_t *flat_buf;
     uint16_t attr_len;
 
     /* Make sure the attribute value isn't too big. */
@@ -111,8 +102,9 @@ ble_att_clt_copy_attr_to_flatbuf(struct os_mbuf *om, void **out_attr_val,
     }
 
     /* Copy the attribute data into the global ATT flat buffer. */
-    os_mbuf_copydata(om, 0, attr_len, ble_att_flat_buf);
-    *out_attr_val = ble_att_flat_buf;
+    flat_buf = ble_att_get_flat_buf();
+    os_mbuf_copydata(om, 0, attr_len, flat_buf);
+    *out_attr_val = flat_buf;
     *out_attr_len = attr_len;
     return 0;
 }
@@ -145,10 +137,6 @@ ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
  * $error response                                                           *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -170,9 +158,6 @@ ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **om)
  * $mtu exchange                                                             *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_mtu_req(struct ble_att_mtu_cmd *req,
                           struct os_mbuf **out_txom)
@@ -199,10 +184,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_mtu(uint16_t conn_handle, struct ble_att_mtu_cmd *req)
 {
@@ -237,10 +218,6 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, struct ble_att_mtu_cmd *req)
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -274,9 +251,6 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
  * $find information                                                         *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_find_info_req(struct ble_att_find_info_req *req,
                                 struct os_mbuf **out_txom)
@@ -295,10 +269,6 @@ ble_att_clt_build_find_info_req(struct ble_att_find_info_req *req,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_find_info(uint16_t conn_handle,
                          struct ble_att_find_info_req *req)
@@ -382,10 +352,6 @@ ble_att_clt_parse_find_info_entry(struct os_mbuf **rxom, uint8_t rsp_format,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -429,9 +395,6 @@ done:
  * $find by type value                                                       *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_find_type_value_req(struct ble_att_find_type_value_req *req,
                                       void *attribute_value, int value_len,
@@ -456,10 +419,6 @@ ble_att_clt_build_find_type_value_req(struct ble_att_find_type_value_req *req,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_find_type_value(uint16_t conn_handle,
                                struct ble_att_find_type_value_req *req,
@@ -492,9 +451,6 @@ ble_att_clt_tx_find_type_value(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_parse_find_type_value_hinfo(
     struct os_mbuf **om, struct ble_att_find_type_value_hinfo *dst)
@@ -512,10 +468,6 @@ ble_att_clt_parse_find_type_value_hinfo(
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -554,9 +506,6 @@ ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom)
  * $read by type                                                             *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_read_type_req(struct ble_att_read_type_req *req,
                                 void *uuid128, struct os_mbuf **out_txom)
@@ -589,10 +538,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_read_type(uint16_t conn_handle,
                          struct ble_att_read_type_req *req,
@@ -624,9 +569,6 @@ ble_att_clt_tx_read_type(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_clt_parse_read_type_adata(struct os_mbuf **om, int data_len,
                                   struct ble_att_read_type_adata *adata)
@@ -645,10 +587,6 @@ ble_att_clt_parse_read_type_adata(struct os_mbuf **om, int data_len,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -692,9 +630,6 @@ done:
  * $read                                                                     *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_read_req(struct ble_att_read_req *req,
                            struct os_mbuf **out_txom)
@@ -721,10 +656,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_read(uint16_t conn_handle, struct ble_att_read_req *req)
 {
@@ -752,10 +683,6 @@ ble_att_clt_tx_read(uint16_t conn_handle, struct ble_att_read_req *req)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -784,9 +711,6 @@ ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom)
  * $read blob                                                                *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_read_blob_req(struct ble_att_read_blob_req *req,
                                 struct os_mbuf **out_txom)
@@ -813,10 +737,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_read_blob(uint16_t conn_handle,
                          struct ble_att_read_blob_req *req)
@@ -845,10 +765,6 @@ ble_att_clt_tx_read_blob(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -877,9 +793,6 @@ ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom)
  * $read multiple                                                            *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_read_mult_req(uint16_t *att_handles, int num_att_handles,
                                 struct os_mbuf **out_txom)
@@ -920,10 +833,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t *att_handles,
                          int num_att_handles)
@@ -952,10 +861,6 @@ ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t *att_handles,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -984,9 +889,6 @@ ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom)
  * $read by group type                                                       *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_read_group_type_req(struct ble_att_read_group_type_req *req,
                                       void *uuid128, struct os_mbuf **out_txom)
@@ -1018,10 +920,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_read_group_type(uint16_t conn_handle,
                                struct ble_att_read_group_type_req *req,
@@ -1055,9 +953,6 @@ ble_att_clt_tx_read_group_type(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_clt_parse_read_group_type_adata(
     struct os_mbuf **om, int data_len,
@@ -1082,10 +977,6 @@ ble_att_clt_parse_read_group_type_adata(
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1129,10 +1020,6 @@ done:
  * $write                                                                    *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_att_clt_build_write_req_or_cmd(uint16_t conn_handle,
                                    struct ble_att_write_req *req,
@@ -1170,10 +1057,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_att_clt_tx_write_req_or_cmd(uint16_t conn_handle,
                                 struct ble_att_write_req *req,
@@ -1197,10 +1080,6 @@ ble_att_clt_tx_write_req_or_cmd(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_write_req(uint16_t conn_handle, struct ble_att_write_req *req,
                          void *value, uint16_t value_len)
@@ -1216,10 +1095,6 @@ ble_att_clt_tx_write_req(uint16_t conn_handle, struct ble_att_write_req *req,
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_write_cmd(uint16_t conn_handle,
                          struct ble_att_write_req *req,
@@ -1236,10 +1111,6 @@ ble_att_clt_tx_write_cmd(uint16_t conn_handle,
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1256,10 +1127,6 @@ ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
  * $prepare write request                                                    *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_att_clt_build_prep_write_req(uint16_t conn_handle,
                                  struct ble_att_prep_write_cmd *req,
@@ -1293,10 +1160,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_prep_write(uint16_t conn_handle,
                           struct ble_att_prep_write_cmd *req,
@@ -1337,10 +1200,6 @@ ble_att_clt_tx_prep_write(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1381,9 +1240,6 @@ done:
  * $execute write request                                                    *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_exec_write_req(struct ble_att_exec_write_req *req,
                                  struct os_mbuf **out_txom)
@@ -1410,10 +1266,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_exec_write(uint16_t conn_handle,
                           struct ble_att_exec_write_req *req)
@@ -1442,10 +1294,6 @@ ble_att_clt_tx_exec_write(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1468,10 +1316,6 @@ ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
  * $handle value notification                                                *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_att_clt_build_notify_req(uint16_t conn_handle,
                              struct ble_att_notify_req *req,
@@ -1505,10 +1349,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_notify(uint16_t conn_handle, struct ble_att_notify_req *req,
                       void *value, uint16_t value_len)
@@ -1542,10 +1382,6 @@ ble_att_clt_tx_notify(uint16_t conn_handle, struct ble_att_notify_req *req,
  * $handle value indication                                                  *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_att_clt_build_indicate_req(uint16_t conn_handle,
                                struct ble_att_indicate_req *req,
@@ -1579,10 +1415,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_indicate(uint16_t conn_handle,
                         struct ble_att_indicate_req *req,
@@ -1613,10 +1445,6 @@ ble_att_clt_tx_indicate(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_att_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_priv.h b/net/nimble/host/src/ble_att_priv.h
index 3a0bc6d..77b5935 100644
--- a/net/nimble/host/src/ble_att_priv.h
+++ b/net/nimble/host/src/ble_att_priv.h
@@ -141,12 +141,11 @@ SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry);
 
 /*** @gen */
 
-extern uint8_t ble_att_flat_buf[BLE_ATT_ATTR_MAX_LEN];
-
 struct ble_l2cap_chan *ble_att_create_chan(void);
 int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
                            struct ble_l2cap_chan **out_chan);
 void ble_att_inc_tx_stat(uint8_t att_op);
+uint8_t *ble_att_get_flat_buf(void);
 uint16_t ble_att_mtu(uint16_t conn_handle);
 void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu);
 int ble_att_init(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index 8f647e2..c64d6f9 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -37,9 +37,6 @@ static struct os_mempool ble_att_svr_prep_entry_pool;
 ble_att_svr_notify_fn *ble_att_svr_notify_cb;
 void *ble_att_svr_notify_cb_arg;
 
-/**
- * Lock restrictions: None.
- */
 static struct ble_att_svr_entry *
 ble_att_svr_entry_alloc(void)
 {
@@ -56,8 +53,6 @@ ble_att_svr_entry_alloc(void)
 /**
  * Allocate the next handle id and return it.
  *
- * Lock restrictions: None.
- *
  * @return A new 16-bit handle ID.
  */
 static uint16_t
@@ -71,8 +66,6 @@ ble_att_svr_next_id(void)
 /**
  * Register a host attribute with the BLE stack.
  *
- * Lock restrictions: None.
- *
  * @param ha                    A filled out ble_att structure to register
  * @param handle_id             A pointer to a 16-bit handle ID, which will be
  *                                  the handle that is allocated.
@@ -107,9 +100,6 @@ ble_att_svr_register(uint8_t *uuid, uint8_t flags, uint16_t *handle_id,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_att_svr_register_uuid16(uint16_t uuid16, uint8_t flags,
                             uint16_t *handle_id, ble_att_svr_access_fn *cb,
@@ -131,9 +121,6 @@ ble_att_svr_register_uuid16(uint16_t uuid16, uint8_t flags,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 uint16_t
 ble_att_svr_prev_handle(void)
 {
@@ -143,8 +130,6 @@ ble_att_svr_prev_handle(void)
 /**
  * Find a host attribute by handle id.
  *
- * Lock restrictions: None.
- *
  * @param handle_id             The handle_id to search for
  * @param ha_ptr                On input: Indicates the starting point of the
  *                                  walk; null means start at the beginning of
@@ -176,8 +161,6 @@ ble_att_svr_find_by_handle(uint16_t handle_id)
 /**
  * Find a host attribute by UUID.
  *
- * Lock restrictions: None.
- *
  * @param uuid                  The ble_uuid_t to search for
  * @param ha_ptr                On input: Indicates the starting point of the
  *                                  walk; null means start at the beginning of
@@ -230,9 +213,6 @@ ble_att_svr_pullup_req_base(struct os_mbuf **om, int base_len,
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_read(uint16_t conn_handle, struct ble_att_svr_entry *entry,
                  struct ble_att_svr_access_ctxt *ctxt, uint8_t *out_att_err)
@@ -275,9 +255,6 @@ err:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle,
                         struct ble_att_svr_access_ctxt *ctxt,
@@ -300,9 +277,6 @@ ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_write(uint16_t conn_handle, struct ble_att_svr_entry *entry,
                   struct ble_att_svr_access_ctxt *ctxt, uint8_t *out_att_err)
@@ -310,7 +284,7 @@ ble_att_svr_write(uint16_t conn_handle, struct ble_att_svr_entry *entry,
     uint8_t att_err;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (conn_handle != BLE_HS_CONN_HANDLE_NONE &&
         !(entry->ha_flags & HA_FLAG_PERM_WRITE)) {
@@ -363,9 +337,6 @@ ble_att_svr_write_handle(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_tx_error_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                          uint8_t req_op, uint16_t handle, uint8_t error_code)
@@ -430,7 +401,6 @@ err:
  * @param err_handle            If an error is transmitted, this is the value
  *                                  of the error message's attribute handle
  *                                  field.
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
  */
 static int
 ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
@@ -482,9 +452,6 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct os_mbuf **out_txom,
                           uint8_t *att_err)
@@ -535,9 +502,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -583,8 +547,6 @@ done:
  * Fills the supplied mbuf with the variable length Information Data field of a
  * Find Information ATT response.
  *
- * Lock restrictions: None.
- *
  * @param req                   The Find Information request being responded
  *                                  to.
  * @param om                    The destination mbuf where the Information
@@ -678,9 +640,6 @@ done:
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_find_info_rsp(uint16_t conn_handle,
                                 struct ble_att_find_info_req *req,
@@ -737,9 +696,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -796,8 +752,6 @@ done:
  * Processes a single non-matching attribute entry while filling a
  * Find-By-Type-Value-Response.
  *
- * Lock restrictions: None.
- *
  * @param om                    The response mbuf.
  * @param first                 Pointer to the first matching handle ID in the
  *                                  current group of IDs.  0 if there is not a
@@ -858,8 +812,6 @@ ble_att_svr_fill_type_value_no_match(struct os_mbuf *om, uint16_t *first,
  * Processes a single matching attribute entry while filling a
  * Find-By-Type-Value-Response.
  *
- * Lock restrictions: None.
- *
  * @param om                    The response mbuf.
  * @param first                 Pointer to the first matching handle ID in the
  *                                  current group of IDs.  0 if there is not a
@@ -913,8 +865,6 @@ ble_att_svr_fill_type_value_match(struct os_mbuf *om, uint16_t *first,
  * Fills the supplied mbuf with the variable length Handles-Information-List
  * field of a Find-By-Type-Value ATT response.
  *
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- *
  * @param req                   The Find-By-Type-Value-Request being responded
  *                                  to.
  * @param rxom                  The mbuf containing the received request.
@@ -1010,9 +960,6 @@ done:
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle,
                                       struct ble_att_find_type_value_req *req,
@@ -1061,9 +1008,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1119,9 +1063,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_read_type_rsp(uint16_t conn_handle,
                                 struct ble_att_read_type_req *req,
@@ -1248,9 +1189,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1333,8 +1271,6 @@ done:
 }
 
 /**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
@@ -1391,9 +1327,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1445,8 +1378,6 @@ done:
 }
 
 /**
- * Lock restrictions: None.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
@@ -1494,9 +1425,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1561,9 +1489,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_read_mult_rsp(uint16_t conn_handle,
                                 struct os_mbuf **rxom,
@@ -1658,9 +1583,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1704,9 +1626,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_svr_is_valid_group_type(uint8_t *uuid128)
 {
@@ -1718,9 +1637,6 @@ ble_att_svr_is_valid_group_type(uint8_t *uuid128)
            uuid16 == BLE_ATT_UUID_SECONDARY_SERVICE;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_service_uuid(struct ble_att_svr_entry *entry, uint16_t *uuid16,
                          uint8_t *uuid128)
@@ -1752,9 +1668,6 @@ ble_att_svr_service_uuid(struct ble_att_svr_entry *entry, uint16_t *uuid16,
     }
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_svr_read_group_type_entry_write(struct os_mbuf *om, uint16_t mtu,
                                         uint16_t start_group_handle,
@@ -1791,8 +1704,6 @@ ble_att_svr_read_group_type_entry_write(struct os_mbuf *om, uint16_t mtu,
 }
 
 /**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- *
  * @return                      0 on success; BLE_HS error code on failure.
  */
 static int
@@ -1975,9 +1886,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2052,9 +1960,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_svr_build_write_rsp(struct os_mbuf **out_txom, uint8_t *att_err)
 {
@@ -2085,9 +1990,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2119,7 +2021,7 @@ ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
     /* Strip the request base from the front of the mbuf. */
     os_mbuf_adj(*rxom, BLE_ATT_WRITE_REQ_BASE_SZ);
 
-    ctxt.attr_data = ble_att_flat_buf;
+    ctxt.attr_data = ble_att_get_flat_buf();
     ctxt.data_len = OS_MBUF_PKTLEN(*rxom);
     os_mbuf_copydata(*rxom, 0, ctxt.data_len, ctxt.attr_data);
     rc = ble_att_svr_write_handle(conn_handle, req.bawq_handle, &ctxt,
@@ -2143,9 +2045,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2169,7 +2068,7 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom)
     /* Strip the request base from the front of the mbuf. */
     os_mbuf_adj(*rxom, BLE_ATT_WRITE_REQ_BASE_SZ);
 
-    ctxt.attr_data = ble_att_flat_buf;
+    ctxt.attr_data = ble_att_get_flat_buf();
     ctxt.data_len = OS_MBUF_PKTLEN(*rxom);
     os_mbuf_copydata(*rxom, 0, ctxt.data_len, ctxt.attr_data);
     rc = ble_att_svr_write_handle(conn_handle, req.bawq_handle, &ctxt,
@@ -2181,9 +2080,6 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom)
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_write_local(uint16_t attr_handle, void *data, uint16_t data_len)
 {
@@ -2200,9 +2096,6 @@ ble_att_svr_write_local(uint16_t attr_handle, void *data, uint16_t data_len)
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_att_svr_prep_free(struct ble_att_prep_entry *entry)
 {
@@ -2210,9 +2103,6 @@ ble_att_svr_prep_free(struct ble_att_prep_entry *entry)
     os_memblock_put(&ble_att_svr_prep_entry_pool, entry);
 }
 
-/**
- * Lock restrictions: None.
- */
 static struct ble_att_prep_entry *
 ble_att_svr_prep_alloc(void)
 {
@@ -2233,9 +2123,6 @@ ble_att_svr_prep_alloc(void)
     return entry;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 static struct ble_att_prep_entry *
 ble_att_svr_prep_find_prev(struct ble_att_svr_conn *basc, uint16_t handle,
                            uint16_t offset)
@@ -2259,9 +2146,6 @@ ble_att_svr_prep_find_prev(struct ble_att_svr_conn *basc, uint16_t handle,
     return prev;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 void
 ble_att_svr_prep_clear(struct ble_att_svr_conn *basc)
 {
@@ -2274,8 +2158,6 @@ ble_att_svr_prep_clear(struct ble_att_svr_conn *basc)
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- *
  * @return                      0 on success; ATT error code on failure.
  */
 static int
@@ -2316,8 +2198,6 @@ ble_att_svr_prep_validate(struct ble_att_svr_conn *basc, uint16_t *err_handle)
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- *
  * @return                      0 on success; ATT error code on failure.
  */
 static int
@@ -2327,6 +2207,7 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
     struct ble_att_prep_entry *entry;
     struct ble_att_prep_entry *next;
     struct ble_att_svr_entry *attr;
+    uint8_t *flat_buf;
     uint8_t att_err;
     int buf_off;
     int rc;
@@ -2339,6 +2220,8 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
         return rc;
     }
 
+    flat_buf = ble_att_get_flat_buf();
+
     /* Contents are valid; perform the writes. */
     buf_off = 0;
     entry = SLIST_FIRST(&conn->bhc_att_svr.basc_prep_list);
@@ -2347,7 +2230,7 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
 
         rc = os_mbuf_copydata(entry->bape_value, 0,
                               OS_MBUF_PKTLEN(entry->bape_value),
-                              ble_att_flat_buf + buf_off);
+                              flat_buf + buf_off);
         BLE_HS_DBG_ASSERT_EVAL(rc == 0);
         buf_off += OS_MBUF_PKTLEN(entry->bape_value);
 
@@ -2359,7 +2242,7 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
                 return BLE_ATT_ERR_INVALID_HANDLE;
             }
 
-            ctxt.attr_data = ble_att_flat_buf;
+            ctxt.attr_data = flat_buf;
             ctxt.data_len = buf_off;
             rc = ble_att_svr_write(conn->bhc_handle, attr, &ctxt, &att_err);
             if (rc != 0) {
@@ -2376,9 +2259,6 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2522,8 +2402,6 @@ done:
 }
 
 /**
- * Lock restrictions: None.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
@@ -2556,9 +2434,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2619,9 +2494,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2652,7 +2524,7 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom)
     /* Strip the request base from the front of the mbuf. */
     os_mbuf_adj(*rxom, BLE_ATT_NOTIFY_REQ_BASE_SZ);
 
-    attr_data = ble_att_flat_buf;
+    attr_data = ble_att_get_flat_buf();
     attr_len = OS_MBUF_PKTLEN(*rxom);
     os_mbuf_copydata(*rxom, 0, attr_len, attr_data);
 
@@ -2669,8 +2541,6 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom)
 }
 
 /**
- * Lock restrictions: None.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
@@ -2701,9 +2571,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2740,7 +2607,7 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom)
     /* Strip the request base from the front of the mbuf. */
     os_mbuf_adj(*rxom, BLE_ATT_INDICATE_REQ_BASE_SZ);
 
-    attr_data = ble_att_flat_buf;
+    attr_data = ble_att_get_flat_buf();
     attr_len = OS_MBUF_PKTLEN(*rxom);
     os_mbuf_copydata(*rxom, 0, attr_len, attr_data);
 
@@ -2774,9 +2641,6 @@ ble_att_svr_free_mem(void)
     ble_att_svr_entry_mem = NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_att_svr_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 5a556d1..33ef101 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -26,11 +26,40 @@
 #include "host/host_hci.h"
 #include "ble_hs_priv.h"
 
-#define BLE_GAP_OP_NULL                                 0
+/**
+ * GAP - Generic Access Profile.
+ *
+ * Design overview:
+ *
+ * GAP procedures are initiated by the application via function calls.  Such
+ * functions return when either of the following happens:
+ *
+ * (1) The procedure completes (success or failure).
+ * (2) The procedure cannot proceed until a BLE peer responds.
+ *
+ * For (1), the result of the procedure if fully indicated by the function
+ * return code.
+ * For (2), the procedure result is indicated by an application-configured
+ * callback.  The callback is executed when the procedure completes.
+ *
+ * Notes on thread-safety:
+ * 1. The ble_hs mutex must never be locked when an application callback is
+ *    executed.  A callback is free to initiate additional host procedures.
+ * 2. Functions called directly by the application never call callbacks.
+ *    Generally, these functions lock the ble_hs mutex at the start, and only
+ *    unlock it at return.
+ * 3. Functions which do call callbacks (receive handlers and timer
+ *    expirations) generally only lock the mutex long enough to modify
+ *    affected state and make copies of data needed for the callback.  A copy
+ *    of various pieces of data is called a "snapshot" (struct
+ *    ble_gap_snapshot).  The sole purpose of snapshots is to allow callbacks
+ *    to be executed after unlocking the mutex.
+ */
 
+/** GAP procedure op codes. */
+#define BLE_GAP_OP_NULL                                 0
 #define BLE_GAP_OP_M_DISC                               1
 #define BLE_GAP_OP_M_CONN                               2
-
 #define BLE_GAP_OP_S_ADV                                1
 
 /**
@@ -234,9 +263,6 @@ ble_gap_log_adv(struct hci_adv_params *adv_params)
  * $snapshot                                                                 *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_gap_fill_conn_desc(struct ble_hs_conn *conn,
                        struct ble_gap_conn_desc *desc)
@@ -249,9 +275,6 @@ ble_gap_fill_conn_desc(struct ble_hs_conn *conn,
     desc->supervision_timeout = conn->bhc_supervision_timeout;
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_gap_conn_to_snapshot(struct ble_hs_conn *conn,
                          struct ble_gap_snapshot *snap)
@@ -261,10 +284,6 @@ ble_gap_conn_to_snapshot(struct ble_hs_conn *conn,
     snap->cb_arg = conn->bhc_cb_arg;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_gap_find_snapshot(uint16_t handle, struct ble_gap_snapshot *snap)
 {
@@ -290,17 +309,13 @@ ble_gap_find_snapshot(uint16_t handle, struct ble_gap_snapshot *snap)
  * $misc                                                                     *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_call_conn_cb(int event, int status, struct ble_gap_conn_ctxt *ctxt,
                      ble_gap_conn_fn *cb, void *cb_arg)
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (cb != NULL) {
         rc = cb(event, status, ctxt, cb_arg);
@@ -315,10 +330,6 @@ ble_gap_call_conn_cb(int event, int status, struct ble_gap_conn_ctxt *ctxt,
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static void
 ble_gap_call_slave_cb(int event, int status, int reset_state)
 {
@@ -348,10 +359,6 @@ ble_gap_call_slave_cb(int event, int status, int reset_state)
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_call_master_conn_cb(int event, int status, int reset_state)
 {
@@ -388,10 +395,6 @@ ble_gap_call_master_conn_cb(int event, int status, int reset_state)
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static void
 ble_gap_call_master_disc_cb(int event, int status, struct ble_hs_adv *adv,
                             struct ble_hs_adv_fields *fields, int reset_state)
@@ -428,16 +431,11 @@ ble_gap_call_master_disc_cb(int event, int status, struct ble_hs_adv *adv,
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks gap.
- */
 int
 ble_gap_update_in_progress(uint16_t conn_handle)
 {
     struct ble_hs_conn *conn;
 
-    /* XXX LOCKING */
     conn = ble_hs_conn_find(conn_handle);
     return conn != NULL && conn->bhc_flags & BLE_HS_CONN_F_UPDATE;
 }
@@ -447,7 +445,6 @@ ble_gap_update_set_flag(uint16_t conn_handle, int val)
 {
     struct ble_hs_conn *conn;
 
-    /* XXX LOCKING */
     conn = ble_hs_conn_find(conn_handle);
     if (conn == NULL) {
         return BLE_HS_ENOTCONN;
@@ -461,10 +458,6 @@ ble_gap_update_set_flag(uint16_t conn_handle, int val)
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static void
 ble_gap_update_notify(uint16_t conn_handle, int status)
 {
@@ -495,9 +488,6 @@ ble_gap_master_set_timer(uint32_t ms_from_now)
  * Called when an error is encountered while the master-connection-fsm is
  * active.  Resets the state machine, clears the HCI ack callback, and notifies
  * the host task that the next hci_batch item can be processed.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gap_master_failed(int status)
@@ -527,10 +517,6 @@ ble_gap_update_failed(uint16_t conn_handle, int status)
     ble_gap_update_notify(conn_handle, status);
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks gap.
- */
 static void
 ble_gap_conn_broken(struct ble_gap_snapshot *snap)
 {
@@ -548,10 +534,6 @@ ble_gap_conn_broken(struct ble_gap_snapshot *snap)
     STATS_INC(ble_gap_stats, disconnect);
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 void
 ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt)
 {
@@ -582,10 +564,6 @@ ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt)
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 void
 ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
 {
@@ -597,8 +575,6 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
     struct ble_gap_snapshot snap;
     struct ble_hs_conn *conn;
 
-    ble_hs_misc_assert_not_locked();
-
     STATS_INC(ble_gap_stats, rx_update_complete);
 
     ble_hs_lock();
@@ -628,8 +604,6 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
 
 /**
  * Tells you if the BLE host is in the process of creating a master connection.
- *
- * Lock restrictions: None.
  */
 int
 ble_gap_master_in_progress(void)
@@ -639,8 +613,6 @@ ble_gap_master_in_progress(void)
 
 /**
  * Tells you if the BLE host is in the process of creating a slave connection.
- *
- * Lock restrictions: None.
  */
 int
 ble_gap_slave_in_progress(void)
@@ -648,9 +620,6 @@ ble_gap_slave_in_progress(void)
     return ble_gap_slave.op != BLE_GAP_OP_NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gap_currently_advertising(void)
 {
@@ -663,9 +632,6 @@ ble_gap_currently_advertising(void)
  * FSM is in a state that can accept this event, and the peer device address is
  * valid, the master FSM is reset and success is returned.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @param addr_type             The address type of the peer; one of the
  *                                  following values:
  *                                  o    BLE_ADDR_TYPE_PUBLIC
@@ -710,8 +676,6 @@ ble_gap_accept_master_conn(uint8_t addr_type, uint8_t *addr)
  * FSM is in a state that can accept this event, and the peer device address is
  * valid, the master FSM is reset and success is returned.
  *
- * Lock restrictions: None.
- *
  * @param addr_type             The address type of the peer; one of the
  *                                  following values:
  *                                  o    BLE_ADDR_TYPE_PUBLIC
@@ -757,10 +721,6 @@ ble_gap_accept_slave_conn(uint8_t addr_type, uint8_t *addr)
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 void
 ble_gap_rx_adv_report(struct ble_hs_adv *adv)
 {
@@ -795,9 +755,6 @@ ble_gap_rx_adv_report(struct ble_hs_adv *adv)
 
 /**
  * Processes an incoming connection-complete HCI event.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
@@ -875,6 +832,7 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
     }
 
     /* We verified that there is a free connection when the procedure began. */
+    /* XXX: Revisit this; ensure this is guaranteed. */
     conn = ble_hs_conn_alloc();
     BLE_HS_DBG_ASSERT(conn != NULL);
 
@@ -905,10 +863,6 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
                             struct ble_gap_upd_params *params)
@@ -917,8 +871,6 @@ ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
     struct ble_gap_snapshot snap;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
-
     rc = ble_gap_find_snapshot(conn_handle, &snap);
     if (rc != 0) {
         return rc;
@@ -938,9 +890,6 @@ ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
 
 /**
  * Called by the ble_hs heartbeat timer.  Handles timed out master procedures.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 void
 ble_gap_heartbeat(void)
@@ -980,9 +929,6 @@ ble_gap_heartbeat(void)
  * $white list                                                               *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gap_wl_busy(void)
 {
@@ -997,10 +943,6 @@ ble_gap_wl_busy(void)
            ble_gap_master.conn.using_wl;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_wl_tx_add(struct ble_gap_white_entry *entry)
 {
@@ -1021,10 +963,6 @@ ble_gap_wl_tx_add(struct ble_gap_white_entry *entry)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_wl_tx_clear(void)
 {
@@ -1040,10 +978,6 @@ ble_gap_wl_tx_clear(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_wl_set(struct ble_gap_white_entry *white_list,
                uint8_t white_list_count)
@@ -1103,10 +1037,6 @@ err:
  * $stop advertise                                                           *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_disable_tx(void)
 {
@@ -1122,10 +1052,6 @@ ble_gap_adv_disable_tx(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_adv_stop(void)
 {
@@ -1163,9 +1089,6 @@ err:
  * $advertise                                                                *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_gap_adv_itvls(uint8_t disc_mode, uint8_t conn_mode,
                   uint16_t *out_itvl_min, uint16_t *out_itvl_max)
@@ -1192,10 +1115,6 @@ ble_gap_adv_itvls(uint8_t disc_mode, uint8_t conn_mode,
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_enable_tx(void)
 {
@@ -1212,10 +1131,6 @@ ble_gap_adv_enable_tx(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_rsp_data_tx(void)
 {
@@ -1237,10 +1152,6 @@ ble_gap_adv_rsp_data_tx(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_data_tx(void)
 {
@@ -1302,10 +1213,6 @@ ble_gap_adv_data_tx(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_params_tx(struct hci_adv_params *adv_params)
 {
@@ -1347,9 +1254,6 @@ ble_gap_adv_params_tx(struct hci_adv_params *adv_params)
  * Enables the specified discoverable mode and connectable mode, and initiates
  * the advertising process.
  *
- * Lock restrictions:
- *     o Caller unlocks gap.
- *
  * @param discoverable_mode     One of the following constants:
  *                                  o BLE_GAP_DISC_MODE_NON
  *                                      (non-discoverable; 3.C.9.2.2).
@@ -1503,9 +1407,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields)
 {
@@ -1539,9 +1440,6 @@ ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields)
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gap_adv_rsp_set_fields(struct ble_hs_adv_fields *rsp_fields)
 {
@@ -1571,10 +1469,6 @@ ble_gap_adv_rsp_set_fields(struct ble_hs_adv_fields *rsp_fields)
  * $discovery procedures                                                     *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_disc_tx_disable(void)
 {
@@ -1590,10 +1484,6 @@ ble_gap_disc_tx_disable(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_disc_tx_enable(void)
 {
@@ -1609,10 +1499,6 @@ ble_gap_disc_tx_enable(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_disc_tx_params(uint8_t scan_type, uint8_t filter_policy)
 {
@@ -1640,9 +1526,6 @@ ble_gap_disc_tx_params(uint8_t scan_type, uint8_t filter_policy)
  * Performs the Limited or General Discovery Procedures, as described in
  * vol. 3, part C, section 9.2.5 / 9.2.6.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      0 on success; nonzero on failure.
  */
 int
@@ -1725,18 +1608,6 @@ done:
  * $connection establishment procedures                                      *
  *****************************************************************************/
 
-/**
- * Processes an HCI acknowledgement (either command status or command complete)
- * while a master connection is being established.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_conn_create_tx(int addr_type, uint8_t *addr,
                        struct ble_gap_crt_params *params)
@@ -1790,9 +1661,6 @@ ble_gap_conn_create_tx(int addr_type, uint8_t *addr,
  *                                  o BLE_GAP_ADDR_TYPE_WL
  * @param addr                  The address of the peer to connect to.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      0 on success; nonzero on failure.
  */
 int
@@ -1860,10 +1728,6 @@ done:
  * $terminate connection procedure                                           *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_terminate(uint16_t conn_handle)
 {
@@ -1905,10 +1769,6 @@ done:
  * $cancel                                                                   *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_cancel(void)
 {
@@ -1992,10 +1852,6 @@ ble_gap_tx_param_neg_reply(uint16_t conn_handle, uint8_t reject_reason)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 void
 ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
 {
@@ -2010,14 +1866,12 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
     uint8_t reject_reason;
     int rc;
 
-    ble_hs_lock();
-
     reject_reason = 0; /* Silence warning. */
 
     rc = ble_gap_find_snapshot(evt->connection_handle, &snap);
     if (rc != 0) {
         /* We are not connected to the sender. */
-        goto done;;
+        return;
     }
 
     peer_params.itvl_min = evt->itvl_min;
@@ -2027,7 +1881,10 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
     peer_params.min_ce_len = 0;
     peer_params.max_ce_len = 0;
 
-    /* By default, the application will just XXX */
+    /* Copy the peer params into the self params to make it easy on the
+     * application.  The application callback will change only the fields which
+     * it finds unsuitable.
+     */
     self_params = peer_params;
 
     memset(&ctxt, 0, sizeof ctxt);
@@ -2050,15 +1907,8 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
     } else {
         ble_gap_tx_param_neg_reply(evt->connection_handle, reject_reason);
     }
-
-done:
-    ble_hs_unlock();
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks gap.
- */
 static int
 ble_gap_update_tx(uint16_t conn_handle, struct ble_gap_upd_params *params)
 {
@@ -2087,11 +1937,6 @@ ble_gap_update_tx(uint16_t conn_handle, struct ble_gap_upd_params *params)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- *     o Caller unlocks gap.
- */
 int
 ble_gap_update_params(uint16_t conn_handle, struct ble_gap_upd_params *params)
 {
@@ -2145,21 +1990,13 @@ int
 ble_gap_security_initiate(uint16_t conn_handle)
 {
     ble_hs_conn_flags_t conn_flags;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_lock();
-
-    conn = ble_hs_conn_find(conn_handle);
-    if (conn != NULL) {
-        conn_flags = conn->bhc_flags;
+    rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags);
+    if (rc != 0) {
+        return rc;
     }
 
-    ble_hs_unlock();
-
-    if (conn == NULL) {
-        return BLE_HS_ENOTCONN;
-    }
     if (!(conn_flags & BLE_HS_CONN_F_MASTER)) {
         return BLE_HS_EROLE;
     }
@@ -2203,9 +2040,6 @@ ble_gap_security_event(uint16_t conn_handle, int status,
  * $init                                                                     *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gap_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_gattc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gattc.c b/net/nimble/host/src/ble_gattc.c
index 64502f3..bee3c39 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -17,6 +17,31 @@
  * under the License.
  */
 
+/**
+ * GATT client - Generic Attribute Profile; client operations.
+ *
+ * Design overview:
+ *
+ * GATT client procedures are initiated by the application via function calls.
+ * Such functions return when either of the following happens:
+ *
+ * (1) The procedure completes (success or failure).
+ * (2) The procedure cannot proceed until a BLE peer responds.
+ *
+ * For (1), the result of the procedure if fully indicated by the function
+ * return code.
+ * For (2), the procedure result is indicated by an application-configured
+ * callback.  The callback is executed when the procedure completes.
+ *
+ * Notes on thread-safety:
+ * 1. The ble_hs mutex must never be locked when an application callback is
+ *    executed.  A callback is free to initiate additional host procedures.
+ * 2. The only resource protected by the mutex is the list of active procedures
+ *    (ble_gattc_procs).  Thread-safety is achieved by locking the mutex during
+ *    removal and insertion operations.  Procedure objects are only modified
+ *    while they are not in the list.
+ */
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -840,7 +865,7 @@ ble_gattc_mtu_cb(struct ble_gattc_proc *proc, int status, uint16_t att_handle,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, mtu_fail);
@@ -944,7 +969,7 @@ ble_gattc_disc_all_svcs_cb(struct ble_gattc_proc *proc,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_svcs_fail);
@@ -1141,7 +1166,7 @@ ble_gattc_disc_svc_uuid_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_svc_uuid_fail);
@@ -1319,7 +1344,7 @@ ble_gattc_find_inc_svcs_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, find_inc_svcs_fail);
@@ -1606,7 +1631,7 @@ ble_gattc_disc_all_chrs_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_chrs_fail);
@@ -1814,12 +1839,12 @@ ble_gattc_disc_chr_uuid_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_chrs_uuid_fail);
     }
 
-    ble_hs_misc_assert_not_locked();
-
     if (proc->disc_chr_uuid.cb == NULL) {
         rc = 0;
     } else {
@@ -2033,12 +2058,12 @@ ble_gattc_disc_all_dscs_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_dscs_fail);
     }
 
-    ble_hs_misc_assert_not_locked();
-
     if (proc->disc_all_dscs.cb == NULL) {
         rc = 0;
     } else {
@@ -2214,7 +2239,7 @@ ble_gattc_read_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_fail);
@@ -2334,7 +2359,7 @@ ble_gattc_read_uuid_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_uuid_fail);
@@ -2476,7 +2501,7 @@ ble_gattc_read_long_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_long_fail);
@@ -2641,7 +2666,7 @@ ble_gattc_read_mult_cb(struct ble_gattc_proc *proc, int status,
     struct ble_gatt_attr attr;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_mult_fail);
@@ -2785,7 +2810,7 @@ ble_gattc_write_cb(struct ble_gattc_proc *proc, int status,
     struct ble_gatt_attr attr;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, write_fail);
@@ -2889,7 +2914,7 @@ ble_gattc_write_long_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, write_long_fail);
@@ -3100,7 +3125,7 @@ ble_gattc_write_reliable_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, write_reliable_fail);
@@ -3376,7 +3401,7 @@ ble_gattc_indicate_cb(struct ble_gattc_proc *proc, int status,
     struct ble_gatt_attr attr;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, indicate_fail);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatts.c b/net/nimble/host/src/ble_gatts.c
index 73bee78..4ef5f21 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -64,9 +64,6 @@ STATS_NAME_START(ble_gatts_stats)
     STATS_NAME(ble_gatts_stats, dsc_writes)
 STATS_NAME_END(ble_gatts_stats)
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_svc_access(uint16_t conn_handle, uint16_t attr_handle,
                      uint8_t *uuid128, uint8_t op,
@@ -94,9 +91,6 @@ ble_gatts_svc_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_inc_access(uint16_t conn_handle, uint16_t attr_handle,
                      uint8_t *uuid128, uint8_t op,
@@ -129,9 +123,6 @@ ble_gatts_inc_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint16_t
 ble_gatts_chr_clt_cfg_allowed(const struct ble_gatt_chr_def *chr)
 {
@@ -148,9 +139,6 @@ ble_gatts_chr_clt_cfg_allowed(const struct ble_gatt_chr_def *chr)
     return flags;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint8_t
 ble_gatts_att_flags_from_chr_flags(ble_gatt_chr_flags chr_flags)
 {
@@ -167,9 +155,6 @@ ble_gatts_att_flags_from_chr_flags(ble_gatt_chr_flags chr_flags)
     return att_flags;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint8_t
 ble_gatts_chr_properties(const struct ble_gatt_chr_def *chr)
 {
@@ -207,9 +192,6 @@ ble_gatts_chr_properties(const struct ble_gatt_chr_def *chr)
     return properties;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_chr_def_access(uint16_t conn_handle, uint16_t attr_handle,
                          uint8_t *uuid128, uint8_t op,
@@ -243,9 +225,6 @@ ble_gatts_chr_def_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_chr_is_sane(const struct ble_gatt_chr_def *chr)
 {
@@ -262,9 +241,6 @@ ble_gatts_chr_is_sane(const struct ble_gatt_chr_def *chr)
     return 1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint8_t
 ble_gatts_chr_op(uint8_t att_op)
 {
@@ -298,9 +274,6 @@ ble_gatts_chr_inc_val_stat(uint8_t gatt_op)
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_gatts_chr_val_access(uint16_t conn_handle, uint16_t attr_handle,
                          uint8_t *uuid128, uint8_t att_op,
@@ -339,9 +312,6 @@ ble_gatts_chr_val_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_find_svc(const struct ble_gatt_svc_def *svc)
 {
@@ -356,9 +326,6 @@ ble_gatts_find_svc(const struct ble_gatt_svc_def *svc)
     return -1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_svc_incs_satisfied(const struct ble_gatt_svc_def *svc)
 {
@@ -380,9 +347,6 @@ ble_gatts_svc_incs_satisfied(const struct ble_gatt_svc_def *svc)
     return 1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_inc(struct ble_gatts_svc_entry *entry)
 {
@@ -401,9 +365,6 @@ ble_gatts_register_inc(struct ble_gatts_svc_entry *entry)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint8_t
 ble_gatts_dsc_op(uint8_t att_op)
 {
@@ -437,9 +398,6 @@ ble_gatts_dsc_inc_stat(uint8_t gatt_op)
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_gatts_dsc_access(uint16_t conn_handle, uint16_t attr_handle,
                      uint8_t *uuid128, uint8_t att_op,
@@ -472,9 +430,6 @@ ble_gatts_dsc_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_dsc_is_sane(const struct ble_gatt_dsc_def *dsc)
 {
@@ -489,9 +444,6 @@ ble_gatts_dsc_is_sane(const struct ble_gatt_dsc_def *dsc)
     return 1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_dsc(const struct ble_gatt_dsc_def *dsc,
                        const struct ble_gatt_chr_def *chr,
@@ -526,9 +478,6 @@ ble_gatts_register_dsc(const struct ble_gatt_dsc_def *dsc,
 
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_clt_cfg_find_idx(struct ble_gatts_clt_cfg *cfgs,
                            uint16_t chr_def_handle)
@@ -546,9 +495,6 @@ ble_gatts_clt_cfg_find_idx(struct ble_gatts_clt_cfg *cfgs,
     return -1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static struct ble_gatts_clt_cfg *
 ble_gatts_clt_cfg_find(struct ble_gatts_clt_cfg *cfgs,
                        uint16_t chr_def_handle)
@@ -563,9 +509,6 @@ ble_gatts_clt_cfg_find(struct ble_gatts_clt_cfg *cfgs,
     }
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 static int
 ble_gatts_clt_cfg_access_locked(struct ble_hs_conn *conn, uint16_t attr_handle,
                                 uint8_t *uuid128, uint8_t att_op,
@@ -627,9 +570,6 @@ ble_gatts_clt_cfg_access_locked(struct ble_hs_conn *conn, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle,
                          uint8_t *uuid128, uint8_t op,
@@ -654,9 +594,6 @@ ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle,
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
 {
@@ -679,9 +616,6 @@ ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_chr(const struct ble_gatt_chr_def *chr,
                        ble_gatt_register_fn *register_cb, void *cb_arg)
@@ -750,9 +684,6 @@ ble_gatts_register_chr(const struct ble_gatt_chr_def *chr,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_svc_type_to_uuid(uint8_t svc_type, uint16_t *out_uuid16)
 {
@@ -770,9 +701,6 @@ ble_gatts_svc_type_to_uuid(uint8_t svc_type, uint16_t *out_uuid16)
     }
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_svc_is_sane(const struct ble_gatt_svc_def *svc)
 {
@@ -789,9 +717,6 @@ ble_gatts_svc_is_sane(const struct ble_gatt_svc_def *svc)
     return 1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_svc(const struct ble_gatt_svc_def *svc,
                        uint16_t *out_handle,
@@ -861,9 +786,6 @@ ble_gatts_register_svc(const struct ble_gatt_svc_def *svc,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_round(int *out_num_registered, ble_gatt_register_fn *cb,
                          void *cb_arg)
@@ -907,9 +829,6 @@ ble_gatts_register_round(int *out_num_registered, ble_gatt_register_fn *cb,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs,
                         ble_gatt_register_fn *cb, void *cb_arg)
@@ -942,9 +861,6 @@ ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 void
 ble_gatts_conn_deinit(struct ble_gatts_conn *gatts_conn)
 {
@@ -958,18 +874,12 @@ ble_gatts_conn_deinit(struct ble_gatts_conn *gatts_conn)
     }
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_clt_cfg_size(void)
 {
     return ble_gatts_num_cfgable_chrs * sizeof (struct ble_gatts_clt_cfg);
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_clt_cfg_init(void)
 {
@@ -1037,9 +947,6 @@ ble_gatts_clt_cfg_init(void)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gatts_conn_init(struct ble_gatts_conn *gatts_conn)
 {
@@ -1069,9 +976,6 @@ ble_gatts_conn_init(struct ble_gatts_conn *gatts_conn)
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 void
 ble_gatts_send_notifications(struct ble_hs_conn *conn)
 {
@@ -1111,9 +1015,6 @@ ble_gatts_send_notifications(struct ble_hs_conn *conn)
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 void
 ble_gatts_chr_updated(uint16_t chr_def_handle)
 {
@@ -1151,9 +1052,6 @@ ble_gatts_chr_updated(uint16_t chr_def_handle)
     ble_hs_unlock();
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_gatts_free_mem(void)
 {
@@ -1164,9 +1062,6 @@ ble_gatts_free_mem(void)
     ble_gatts_svc_entries = NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gatts_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 e05a9e9..4d62a94 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -44,7 +44,7 @@ struct log ble_hs_log;
 struct os_mempool g_hci_cmd_pool;
 static void *ble_hs_hci_cmd_buf;
 
-/* XXX: this might be transport layer*/
+/* XXX: this might be transport layer */
 #define HCI_OS_EVENT_BUF_SIZE   (sizeof(struct os_event))
 
 struct os_mempool g_hci_os_event_pool;
@@ -67,6 +67,7 @@ static struct os_callout_func ble_hs_event_co;
 /* Host HCI Task Events */
 static struct os_eventq ble_hs_evq;
 static struct os_eventq *ble_hs_app_evq;
+static struct os_task *ble_hs_app_task;
 
 static struct os_mqueue ble_hs_rx_q;
 static struct os_mqueue ble_hs_tx_q;
@@ -83,16 +84,39 @@ STATS_NAME_START(ble_hs_stats)
     STATS_NAME(ble_hs_stats, hci_unknown_event)
 STATS_NAME_END(ble_hs_stats)
 
+int
+ble_hs_locked(void)
+{
+    return ble_hs_mutex.mu_level > 0;
+}
+
+int
+ble_hs_locked_by_cur_task(void)
+{
+    struct os_task *owner;
+
+    owner = ble_hs_mutex.mu_owner;
+    return owner != NULL && owner == os_sched_get_current_task();
+}
+
+int
+ble_hs_thread_safe(void)
+{
+    return !os_started() || ble_hs_locked_by_cur_task();
+}
+
+int
+ble_hs_is_app_task(void)
+{
+    return os_sched_get_current_task() == ble_hs_app_task;
+}
+
 void
 ble_hs_lock(void)
 {
-    struct os_task *owner;
     int rc;
 
-    owner = ble_hs_mutex.mu_owner;
-    if (owner != NULL) {
-        BLE_HS_DBG_ASSERT_EVAL(owner != os_sched_get_current_task());
-    }
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     rc = os_mutex_pend(&ble_hs_mutex, 0xffffffff);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
@@ -107,12 +131,6 @@ ble_hs_unlock(void)
     BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
 }
 
-int
-ble_hs_locked(void)
-{
-    return ble_hs_mutex.mu_level > 0;
-}
-
 void
 ble_hs_process_tx_data_queue(void)
 {
@@ -150,9 +168,6 @@ ble_hs_heartbeat_timer_reset(void)
 /**
  * Called once a second by the ble_hs heartbeat timer.  Handles unresponsive
  * timeouts and periodic retries in case of resource shortage.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_hs_heartbeat(void *unused)
@@ -218,6 +233,8 @@ ble_hs_start(void)
 {
     int rc;
 
+    ble_hs_app_task = os_sched_get_current_task();
+
     ble_hs_heartbeat_timer_reset();
 
     rc = ble_hs_startup_go();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_hs_adv.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_adv.c b/net/nimble/host/src/ble_hs_adv.c
index faf63b0..ef038a7 100644
--- a/net/nimble/host/src/ble_hs_adv.c
+++ b/net/nimble/host/src/ble_hs_adv.c
@@ -106,8 +106,6 @@ ble_hs_adv_set_array32(uint8_t type, uint8_t num_elems, uint32_t *elems,
 /**
  * Sets the significant part of the data in outgoing advertisements.
  *
- * Lock restrictions: None.
- *
  * @return                      0 on success;  on failure.
  */
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 4aeabe6..a09eaad 100644
--- a/net/nimble/host/src/ble_hs_atomic.c
+++ b/net/nimble/host/src/ble_hs_atomic.c
@@ -43,3 +43,24 @@ ble_hs_atomic_conn_insert(struct ble_hs_conn *conn)
     ble_hs_conn_insert(conn);
     ble_hs_unlock();
 }
+
+int
+ble_hs_atomic_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags)
+{
+    struct ble_hs_conn *conn;
+    int rc;
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_find(conn_handle);
+    if (conn == NULL) {
+        rc = BLE_HS_ENOTCONN;
+    } else {
+        rc = 0;
+        *out_flags = conn->bhc_flags;
+    }
+
+    ble_hs_unlock();
+
+    return rc;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_hs_atomic.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic.h b/net/nimble/host/src/ble_hs_atomic.h
index 5bb3665..29852f8 100644
--- a/net/nimble/host/src/ble_hs_atomic.h
+++ b/net/nimble/host/src/ble_hs_atomic.h
@@ -20,6 +20,11 @@
 #ifndef H_BLE_HS_ATOMIC_
 #define H_BLE_HS_ATOMIC_
 
+#include "ble_hs_conn.h"
+
 int ble_hs_atomic_conn_delete(uint16_t conn_handle);
+void ble_hs_atomic_conn_insert(struct ble_hs_conn *conn);
+int ble_hs_atomic_conn_flags(uint16_t conn_handle,
+                             ble_hs_conn_flags_t *out_flags);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_hs_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.c b/net/nimble/host/src/ble_hs_conn.c
index 7c505ba..8d22739 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -28,9 +28,6 @@ static struct os_mempool ble_hs_conn_pool;
 
 static os_membuf_t *ble_hs_conn_elem_mem;
 
-/**
- * Lock restrictions: none.
- */
 int
 ble_hs_conn_can_alloc(void)
 {
@@ -41,9 +38,6 @@ ble_hs_conn_can_alloc(void)
     return ble_hs_conn_pool.mp_num_free >= 1;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 struct ble_l2cap_chan *
 ble_hs_conn_chan_find(struct ble_hs_conn *conn, uint16_t cid)
 {
@@ -65,10 +59,6 @@ ble_hs_conn_chan_find(struct ble_hs_conn *conn, uint16_t cid)
     return NULL;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex if connection has been
- * inserted.
- */
 int
 ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -100,9 +90,6 @@ ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     return 0;
 }
 
-/**
- * Lock restrictions: none.
- */
 struct ble_hs_conn *
 ble_hs_conn_alloc(void)
 {
@@ -165,9 +152,6 @@ err:
     return NULL;
 }
 
-/**
- * Lock restrictions: none.
- */
 static void
 ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -179,9 +163,6 @@ ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     ble_l2cap_chan_free(chan);
 }
 
-/**
- * Lock restrictions: none.
- */
 void
 ble_hs_conn_free(struct ble_hs_conn *conn)
 {
@@ -210,9 +191,6 @@ ble_hs_conn_free(struct ble_hs_conn *conn)
     STATS_INC(ble_hs_stats, conn_delete);
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 void
 ble_hs_conn_insert(struct ble_hs_conn *conn)
 {
@@ -220,13 +198,12 @@ ble_hs_conn_insert(struct ble_hs_conn *conn)
     return;
 #endif
 
+    BLE_HS_DBG_ASSERT(ble_hs_thread_safe());
+
     BLE_HS_DBG_ASSERT_EVAL(ble_hs_conn_find(conn->bhc_handle) == NULL);
     SLIST_INSERT_HEAD(&ble_hs_conns, conn, bhc_next);
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 void
 ble_hs_conn_remove(struct ble_hs_conn *conn)
 {
@@ -234,12 +211,11 @@ ble_hs_conn_remove(struct ble_hs_conn *conn)
     return;
 #endif
 
+    BLE_HS_DBG_ASSERT(ble_hs_thread_safe());
+
     SLIST_REMOVE(&ble_hs_conns, conn, ble_hs_conn, bhc_next);
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 struct ble_hs_conn *
 ble_hs_conn_find(uint16_t conn_handle)
 {
@@ -249,6 +225,8 @@ ble_hs_conn_find(uint16_t conn_handle)
 
     struct ble_hs_conn *conn;
 
+    BLE_HS_DBG_ASSERT(ble_hs_thread_safe());
+
     SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
         if (conn->bhc_handle == conn_handle) {
             return conn;
@@ -268,34 +246,7 @@ ble_hs_conn_exists(uint16_t conn_handle)
 }
 
 /**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
-int
-ble_hs_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags)
-{
-    struct ble_hs_conn *conn;
-    int rc;
-
-    ble_hs_lock();
-
-    conn = ble_hs_conn_find(conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        rc = 0;
-        *out_flags = conn->bhc_flags;
-    }
-
-    ble_hs_unlock();
-
-    return rc;
-}
-
-/**
  * Retrieves the first connection in the list.
- *
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
  */
 struct ble_hs_conn *
 ble_hs_conn_first(void)
@@ -304,12 +255,10 @@ ble_hs_conn_first(void)
     return NULL;
 #endif
 
+    BLE_HS_DBG_ASSERT(ble_hs_thread_safe());
     return SLIST_FIRST(&ble_hs_conns);
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_hs_conn_free_mem(void)
 {
@@ -317,9 +266,6 @@ ble_hs_conn_free_mem(void)
     ble_hs_conn_elem_mem = NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 int 
 ble_hs_conn_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_hs_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.h b/net/nimble/host/src/ble_hs_conn.h
index 0dd7bf6..c470c3d 100644
--- a/net/nimble/host/src/ble_hs_conn.h
+++ b/net/nimble/host/src/ble_hs_conn.h
@@ -64,7 +64,6 @@ void ble_hs_conn_insert(struct ble_hs_conn *conn);
 void ble_hs_conn_remove(struct ble_hs_conn *conn);
 struct ble_hs_conn *ble_hs_conn_find(uint16_t conn_handle);
 int ble_hs_conn_exists(uint16_t conn_handle);
-int ble_hs_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags);
 struct ble_hs_conn *ble_hs_conn_first(void);
 struct ble_l2cap_chan *ble_hs_conn_chan_find(struct ble_hs_conn *conn,
                                              uint16_t cid);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_hs_misc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_misc.c b/net/nimble/host/src/ble_hs_misc.c
index ab130bb..82941d6 100644
--- a/net/nimble/host/src/ble_hs_misc.c
+++ b/net/nimble/host/src/ble_hs_misc.c
@@ -67,16 +67,8 @@ ble_hs_misc_log_flat_buf(void *data, int len)
     }
 }
 
-void
-ble_hs_misc_assert_not_locked(void)
-{
-    assert(!ble_hs_locked());
-}
-
 /**
  * Allocates an mbuf for use by the nimble host.
- *
- * Lock restrictions: None.
  */
 struct os_mbuf *
 ble_hs_misc_pkthdr(void)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 9bd3632..23df932 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -26,14 +26,15 @@
 #include "ble_att_priv.h"
 #include "ble_gap_priv.h"
 #include "ble_gatt_priv.h"
+#include "ble_hci_util.h"
 #include "ble_hs_adv_priv.h"
+#include "ble_hs_atomic.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_endian.h"
 #include "ble_hs_startup.h"
 #include "ble_l2cap_priv.h"
 #include "ble_l2cap_sig.h"
 #include "ble_l2cap_sm.h"
-#include "ble_hci_util.h"
 #include "host/ble_hs.h"
 #include "log/log.h"
 #include "nimble/nimble_opt.h"
@@ -92,15 +93,14 @@ int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid,
                                     struct ble_hs_conn **out_conn,
                                     struct ble_l2cap_chan **out_chan);
 
-int ble_hs_atomic_conn_delete(uint16_t conn_handle);
-void ble_hs_atomic_conn_insert(struct ble_hs_conn *conn);
-
 void ble_hs_cfg_init(struct ble_hs_cfg *cfg);
 
+int ble_hs_locked(void);
+int ble_hs_locked_by_cur_task(void);
+int ble_hs_thread_safe(void);
+int ble_hs_is_app_task(void);
 void ble_hs_lock(void);
 void ble_hs_unlock(void);
-int ble_hs_locked(void);
-void ble_hs_misc_assert_not_locked(void);
 
 struct os_mbuf *ble_hs_misc_pkthdr(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_l2cap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap.c b/net/nimble/host/src/ble_l2cap.c
index 40bf225..65b3fc2 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -46,9 +46,6 @@ STATS_NAME_START(ble_l2cap_stats)
     STATS_NAME(ble_l2cap_stats, sm_rx)
 STATS_NAME_END(ble_l2cap_stats)
 
-/**
- * Lock restrictions: None.
- */
 struct ble_l2cap_chan *
 ble_l2cap_chan_alloc(void)
 {
@@ -66,9 +63,6 @@ ble_l2cap_chan_alloc(void)
     return chan;
 }
 
-/**
- * Lock restrictions: None.
- */
 void
 ble_l2cap_chan_free(struct ble_l2cap_chan *chan)
 {
@@ -84,10 +78,6 @@ ble_l2cap_chan_free(struct ble_l2cap_chan *chan)
     STATS_INC(ble_l2cap_stats, chan_delete);
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 uint16_t
 ble_l2cap_chan_mtu(struct ble_l2cap_chan *chan)
 {
@@ -109,9 +99,6 @@ ble_l2cap_chan_mtu(struct ble_l2cap_chan *chan)
     return mtu;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_l2cap_parse_hdr(struct os_mbuf *om, int off,
                     struct ble_l2cap_hdr *l2cap_hdr)
@@ -129,9 +116,6 @@ ble_l2cap_parse_hdr(struct os_mbuf *om, int off,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 struct os_mbuf *
 ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len)
 {
@@ -150,10 +134,6 @@ ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len)
     return om;
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 static void
 ble_l2cap_forget_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -162,10 +142,6 @@ ble_l2cap_forget_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     chan->blc_rx_len = 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 static void
 ble_l2cap_discard_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -173,10 +149,6 @@ ble_l2cap_discard_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     ble_l2cap_forget_rx(conn, chan);
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 static int
 ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                      struct os_mbuf *om,
@@ -211,10 +183,6 @@ ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 int
 ble_l2cap_rx(struct ble_hs_conn *conn,
              struct hci_data_hdr *hci_hdr,
@@ -288,9 +256,6 @@ err:
  * Transmits the L2CAP payload contained in the specified mbuf.  The supplied
  * mbuf is consumed, regardless of the outcome of the function call.
  * 
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- *
  * @param chan                  The L2CAP channel to transmit over.
  * @param om                    The data to transmit.
  *
@@ -324,9 +289,6 @@ err:
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_l2cap_free_mem(void)
 {
@@ -334,9 +296,6 @@ ble_l2cap_free_mem(void)
     ble_l2cap_chan_mem = NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_l2cap_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_l2cap_sig.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig.c b/net/nimble/host/src/ble_l2cap_sig.c
index 2f6b692..ff98426 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -17,6 +17,31 @@
  * under the License.
  */
 
+/**
+ * L2CAP Signaling (channel ID = 5).
+ *
+ * Design overview:
+ *
+ * L2CAP sig procedures are initiated by the application via function calls.
+ * Such functions return when either of the following happens:
+ *
+ * (1) The procedure completes (success or failure).
+ * (2) The procedure cannot proceed until a BLE peer responds.
+ *
+ * For (1), the result of the procedure if fully indicated by the function
+ * return code.
+ * For (2), the procedure result is indicated by an application-configured
+ * callback.  The callback is executed when the procedure completes.
+ *
+ * Notes on thread-safety:
+ * 1. The ble_hs mutex must never be locked when an application callback is
+ *    executed.  A callback is free to initiate additional host procedures.
+ * 2. The only resource protected by the mutex is the list of active procedures
+ *    (ble_l2cap_sig_procs).  Thread-safety is achieved by locking the mutex
+ *    during removal and insertion operations.  Procedure objects are only
+ *    modified while they are not in the list.
+ */
+
 #include <string.h>
 #include <errno.h>
 #include "console/console.h"
@@ -241,7 +266,7 @@ ble_l2cap_sig_rx_noop(uint16_t conn_handle,
 static void
 ble_l2cap_sig_update_call_cb(struct ble_l2cap_sig_proc *proc, int status)
 {
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_l2cap_stats, update_fail);
@@ -382,7 +407,7 @@ ble_l2cap_sig_update(uint16_t conn_handle,
 
     STATS_INC(ble_l2cap_stats, update_init);
 
-    rc = ble_hs_conn_flags(conn_handle, &conn_flags);
+    rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags);
     if (rc != 0) {
         return rc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_l2cap_sig_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_cmd.c b/net/nimble/host/src/ble_l2cap_sig_cmd.c
index 290dc43..7e12180 100644
--- a/net/nimble/host/src/ble_l2cap_sig_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sig_cmd.c
@@ -52,10 +52,6 @@ ble_l2cap_sig_init_cmd(uint8_t op, uint8_t id, uint8_t payload_len,
     return 0;
 }
 
-/**
- * Locking restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom)
 {



[18/50] [abbrv] incubator-mynewt-core git commit: ble host - fix security bug

Posted by ma...@apache.org.
ble host - fix security bug

The master (initiator) was overwriting its ltk while verifying the
slave's response.


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

Branch: refs/heads/master
Commit: 9131d1e4cc55cd49a417182c9c205ca9c2320bb3
Parents: 7235e90
Author: Christopher Collins <cc...@apache.org>
Authored: Tue Apr 19 20:01:01 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Apr 19 20:01:01 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_hs.c       |  2 -
 net/nimble/host/src/ble_l2cap_sm.c | 67 ++++++++++++++-------------------
 2 files changed, 29 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9131d1e4/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 2de2bf9..8a65c00 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -157,8 +157,6 @@ ble_hs_heartbeat_timer_reset(void)
 static void
 ble_hs_heartbeat(void *unused)
 {
-    ble_hs_misc_assert_not_locked();
-
     ble_gattc_heartbeat();
     ble_gap_heartbeat();
     ble_l2cap_sig_heartbeat();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9131d1e4/net/nimble/host/src/ble_l2cap_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.c b/net/nimble/host/src/ble_l2cap_sm.c
index a2e5785..e385ac6 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -51,23 +51,15 @@ struct ble_l2cap_sm_proc {
     uint8_t pair_alg;
     uint8_t state;
 
-
     /* XXX: Minimum security requirements. */
 
-    union {
-        struct {
-            struct ble_l2cap_sm_pair_cmd pair_req;
-            struct ble_l2cap_sm_pair_cmd pair_rsp;
-            uint8_t tk[16];
-            uint8_t confirm_their[16];
-            uint8_t rand_our[16];
-            uint8_t rand_their[16];
-        } phase_1_2;
-
-        struct {
-            uint8_t key[16];
-        } hci;
-    };
+    struct ble_l2cap_sm_pair_cmd pair_req;
+    struct ble_l2cap_sm_pair_cmd pair_rsp;
+    uint8_t tk[16];
+    uint8_t confirm_their[16];
+    uint8_t rand_our[16];
+    uint8_t rand_their[16];
+    uint8_t ltk[16];
 };
 
 STAILQ_HEAD(ble_l2cap_sm_proc_list, ble_l2cap_sm_proc);
@@ -236,13 +228,12 @@ ble_l2cap_sm_gen_key(struct ble_l2cap_sm_proc *proc)
     uint8_t key[16];
     int rc;
 
-    rc = ble_l2cap_sm_alg_s1(proc->phase_1_2.tk, proc->phase_1_2.rand_our,
-                             proc->phase_1_2.rand_their, key);
+    rc = ble_l2cap_sm_alg_s1(proc->tk, proc->rand_our, proc->rand_their, key);
     if (rc != 0) {
         return rc;
     }
 
-    memcpy(proc->hci.key, key, sizeof key);
+    memcpy(proc->ltk, key, sizeof key);
 
     return 0;
 }
@@ -522,7 +513,7 @@ ble_l2cap_sm_lt_key_req_handle(struct ble_l2cap_sm_proc *proc,
 {
     int rc;
 
-    rc = ble_l2cap_sm_lt_key_req_reply_tx(proc->conn_handle, proc->hci.key);
+    rc = ble_l2cap_sm_lt_key_req_reply_tx(proc->conn_handle, proc->ltk);
     if (rc != 0) {
         *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
         return rc;
@@ -543,7 +534,7 @@ ble_l2cap_sm_random_go(struct ble_l2cap_sm_proc *proc)
     struct ble_l2cap_sm_pair_random cmd;
     int rc;
 
-    memcpy(cmd.value, proc->phase_1_2.rand_our, 16);
+    memcpy(cmd.value, proc->rand_our, 16);
     rc = ble_l2cap_sm_pair_random_tx(proc->conn_handle, &cmd);
     if (rc != 0) {
         return rc;
@@ -584,14 +575,14 @@ ble_l2cap_sm_random_handle(struct ble_l2cap_sm_proc *proc,
         return rc;
     }
 
-    if (memcmp(proc->phase_1_2.confirm_their, confirm_val, 16) != 0) {
+    if (memcmp(proc->confirm_their, confirm_val, 16) != 0) {
         /* Random number mismatch. */
         rc = BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH);
         *out_sm_status = BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH;
         return rc;
     }
 
-    memcpy(proc->phase_1_2.rand_their, cmd->value, 16);
+    memcpy(proc->rand_their, cmd->value, 16);
 
     /* Generate the key. */
     rc = ble_l2cap_sm_gen_key(proc);
@@ -602,7 +593,7 @@ ble_l2cap_sm_random_handle(struct ble_l2cap_sm_proc *proc,
 
     if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
         /* Send the start-encrypt HCI command to the controller. */
-        rc = ble_l2cap_sm_start_encrypt_tx(proc->conn_handle, proc->hci.key);
+        rc = ble_l2cap_sm_start_encrypt_tx(proc->conn_handle, proc->ltk);
         if (rc != 0) {
             *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
             return rc;
@@ -654,15 +645,15 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
         return BLE_HS_ENOTCONN;
     }
 
-    memcpy(k, proc->phase_1_2.tk, sizeof proc->phase_1_2.tk);
+    memcpy(k, proc->tk, sizeof proc->tk);
 
     ble_l2cap_sm_pair_cmd_write(
         preq, BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ, 1,
-        &proc->phase_1_2.pair_req);
+        &proc->pair_req);
 
     ble_l2cap_sm_pair_cmd_write(
         pres, BLE_L2CAP_SM_HDR_SZ + BLE_L2CAP_SM_PAIR_CMD_SZ, 0,
-        &proc->phase_1_2.pair_rsp);
+        &proc->pair_rsp);
 
     return 0;
 }
@@ -680,18 +671,13 @@ ble_l2cap_sm_confirm_go(struct ble_l2cap_sm_proc *proc)
     uint8_t rat;
     int rc;
 
-    rc = ble_l2cap_sm_gen_pair_rand(proc->phase_1_2.rand_our);
-    if (rc != 0) {
-        return rc;
-    }
-
     rc = ble_l2cap_sm_confirm_prepare_args(proc, k, preq, pres, &iat, &rat,
                                            ia, ra);
     if (rc != 0) {
         return rc;
     }
 
-    rc = ble_l2cap_sm_alg_c1(k, proc->phase_1_2.rand_our, preq, pres, iat, rat,
+    rc = ble_l2cap_sm_alg_c1(k, proc->rand_our, preq, pres, iat, rat,
                              ia, ra, cmd.value);
     if (rc != 0) {
         return rc;
@@ -714,7 +700,7 @@ ble_l2cap_sm_confirm_handle(struct ble_l2cap_sm_proc *proc,
 {
     int rc;
 
-    memcpy(proc->phase_1_2.confirm_their, cmd->value, 16);
+    memcpy(proc->confirm_their, cmd->value, 16);
 
     if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
         rc = ble_l2cap_sm_random_go(proc);
@@ -772,10 +758,15 @@ ble_l2cap_sm_pair_go(struct ble_l2cap_sm_proc *proc)
     }
 
     if (is_req) {
-        proc->phase_1_2.pair_req = cmd;
+        proc->pair_req = cmd;
     } else {
         proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
-        proc->phase_1_2.pair_rsp = cmd;
+        proc->pair_rsp = cmd;
+    }
+
+    rc = ble_l2cap_sm_gen_pair_rand(proc->rand_our);
+    if (rc != 0) {
+        return rc;
     }
 
     ble_l2cap_sm_proc_set_timer(proc);
@@ -790,7 +781,7 @@ ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
 {
     int rc;
 
-    proc->phase_1_2.pair_req = *req;
+    proc->pair_req = *req;
 
     rc = ble_l2cap_sm_pair_go(proc);
     if (rc != 0) {
@@ -810,7 +801,7 @@ ble_l2cap_sm_pair_rsp_handle(struct ble_l2cap_sm_proc *proc,
 {
     int rc;
 
-    proc->phase_1_2.pair_rsp = *rsp;
+    proc->pair_rsp = *rsp;
 
     /* XXX: Assume legacy "Just Works" for now. */
     proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
@@ -1157,7 +1148,7 @@ ble_l2cap_sm_set_tk(uint16_t conn_handle, uint8_t *tk)
         return BLE_HS_ENOENT;
     }
 
-    memcpy(proc->phase_1_2.tk, tk, 16);
+    memcpy(proc->tk, tk, 16);
 
     /* XXX: Proceed with pairing; send confirm command. */
 


[10/50] [abbrv] incubator-mynewt-core git commit: ble host - major changes.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatts.c b/net/nimble/host/src/ble_gatts.c
index 007958b..73bee78 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -639,7 +639,7 @@ ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle,
     struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     conn = ble_hs_conn_find(conn_handle);
     if (conn == NULL) {
@@ -649,7 +649,7 @@ ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle,
                                              ctxt, arg);
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     return rc;
 }
@@ -1129,7 +1129,7 @@ ble_gatts_chr_updated(uint16_t chr_def_handle)
         return;
     }
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     for (conn = ble_hs_conn_first();
          conn != NULL;
@@ -1148,7 +1148,7 @@ ble_gatts_chr_updated(uint16_t chr_def_handle)
         }
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_block.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_block.c b/net/nimble/host/src/ble_hci_block.c
deleted file mode 100644
index e8112c1..0000000
--- a/net/nimble/host/src/ble_hci_block.c
+++ /dev/null
@@ -1,229 +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.
- */
-
-/**
- * Provides a blocking HCI send interface.  These functions must not be called
- * from the ble_hs task.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "os/os.h"
-#include "ble_hs_priv.h"
-
-#define BLE_HCI_BLOCK_TIMEOUT       (OS_TICKS_PER_SEC)
-
-/** Protects resources from 2+ application tasks. */
-static struct os_mutex ble_hci_block_mutex;
-
-/** Used to block on expected HCI acknowledgements. */
-static struct os_sem ble_hci_block_sem;
-
-/** Global state corresponding to the current blocking operation. */
-static void *ble_hci_block_cmd;
-static void *ble_hci_block_evt_buf;
-static uint8_t ble_hci_block_evt_buf_len;
-static struct ble_hci_block_result *ble_hci_block_result;
-static uint8_t ble_hci_block_handle;
-static int ble_hci_block_status;
-
-/**
- * Used when the client passes a null result pointer (doesn't care about the
- * event data).
- */
-static struct ble_hci_block_result ble_hci_block_result_anon;
-
-#if PHONY_HCI_ACKS
-static uint8_t ble_hci_block_phony_ack_buf[256];
-static ble_hci_block_phony_ack_fn *ble_hci_block_phony_ack_cb;
-#endif
-
-/**
- * Copies the parameters from an acknowledgement into the application event
- * buffer.
- */
-static void
-ble_hci_block_copy_evt_data(void *src_data, uint8_t src_data_len)
-{
-    if (ble_hci_block_evt_buf_len > src_data_len) {
-        ble_hci_block_result->evt_buf_len = ble_hci_block_evt_buf_len;
-    } else {
-        ble_hci_block_result->evt_buf_len = src_data_len;
-    }
-    ble_hci_block_result->evt_total_len = src_data_len;
-
-    if (ble_hci_block_result->evt_buf_len > 0) {
-        memcpy(ble_hci_block_evt_buf, src_data,
-               ble_hci_block_result->evt_buf_len);
-    }
-}
-
-/**
- * Callback that gets executed upon receiving an HCI acknowledgement.
- */
-static void
-ble_hci_block_ack_cb(struct ble_hci_ack *ack, void *arg)
-{
-    uint8_t *ack_params;
-    uint8_t ack_params_len;
-
-    BLE_HS_DBG_ASSERT(ack->bha_hci_handle == ble_hci_block_handle);
-
-    ack_params = ack->bha_params;
-    ack_params_len = ack->bha_params_len;
-    if (ack->bha_params_len > 0) {
-        /* +1/-1 to ignore the status byte. */
-        ack_params++;
-        ack_params_len--;
-    }
-    ble_hci_block_copy_evt_data(ack_params, ack_params_len);
-    ble_hci_block_status = ack->bha_status;
-
-    /* Wake the application task up now that the acknowledgement has been
-     * received.
-     */
-    os_sem_release(&ble_hci_block_sem);
-}
-
-/**
- * Callback that gets executed when an HCI tx reservation is services.
- * Transmits the HCI command specifed by the client task.
- */
-static int
-ble_hci_block_tx_cb(void *arg)
-{
-    int rc;
-
-    ble_hci_sched_set_ack_cb(ble_hci_block_ack_cb, NULL);
-
-    rc = host_hci_cmd_send_buf(ble_hci_block_cmd);
-    if (rc != 0) {
-        os_sem_release(&ble_hci_block_sem);
-        return rc;
-    }
-
-    return 0;
-}
-
-#if PHONY_HCI_ACKS
-void
-ble_hci_block_set_phony_ack_cb(ble_hci_block_phony_ack_fn *cb)
-{
-    ble_hci_block_phony_ack_cb = cb;
-}
-#endif
-
-
-static int
-ble_hci_block_wait_for_ack(void)
-{
-#if PHONY_HCI_ACKS
-    int rc;
-
-    if (!os_started()) {
-        /* Force the pending HCI command to transmit. */
-        ble_hci_sched_wakeup();
-    }
-    if (ble_hci_block_phony_ack_cb == NULL) {
-        return BLE_HS_ETIMEOUT;
-    } else {
-        rc = ble_hci_block_phony_ack_cb(ble_hci_block_cmd,
-                                        ble_hci_block_phony_ack_buf,
-                                        sizeof ble_hci_block_phony_ack_buf);
-        if (rc == 0) {
-            rc = host_hci_event_rx(ble_hci_block_phony_ack_buf);
-            if (rc == 0) {
-                rc = ble_hci_block_status;
-            }
-        }
-
-        return rc;
-    }
-#else
-    int rc;
-
-    rc = os_sem_pend(&ble_hci_block_sem, BLE_HCI_BLOCK_TIMEOUT);
-    switch (rc) {
-    case 0:
-        rc = ble_hci_block_status;
-        break;
-
-    case OS_NOT_STARTED:
-        rc = BLE_HS_EOS;
-        break;
-
-    case OS_TIMEOUT:
-        rc = BLE_HS_ETIMEOUT;
-        break;
-
-    default:
-        BLE_HS_DBG_ASSERT(0);
-        rc = BLE_HS_EOS;
-        break;
-    }
-
-    return rc;
-#endif
-}
-
-/**
- * Performs a blocking HCI send.  Must not be called from the ble_hs task.
- */
-int
-ble_hci_block_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len,
-                 struct ble_hci_block_result *result)
-{
-    int rc;
-
-    BLE_HS_DBG_ASSERT(os_sched_get_current_task() != &ble_hs_task);
-
-    os_mutex_pend(&ble_hci_block_mutex, OS_WAIT_FOREVER);
-
-    ble_hci_block_cmd = cmd;
-    ble_hci_block_evt_buf = evt_buf;
-    ble_hci_block_evt_buf_len = evt_buf_len;
-
-    if (result != NULL) {
-        ble_hci_block_result = result;
-    } else {
-        ble_hci_block_result = &ble_hci_block_result_anon;
-    }
-    memset(ble_hci_block_result, 0, sizeof *ble_hci_block_result);
-
-    rc = ble_hci_sched_enqueue(ble_hci_block_tx_cb, NULL,
-                               &ble_hci_block_handle);
-    if (rc == 0) {
-        rc = ble_hci_block_wait_for_ack();
-    }
-
-    os_mutex_release(&ble_hci_block_mutex);
-    return rc;
-}
-
-void
-ble_hci_block_init(void)
-{
-    int rc;
-
-    rc = os_mutex_init(&ble_hci_block_mutex);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-
-    rc = os_sem_init(&ble_hci_block_sem, 0);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_sched.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_sched.c b/net/nimble/host/src/ble_hci_sched.c
deleted file mode 100644
index 068e986..0000000
--- a/net/nimble/host/src/ble_hci_sched.c
+++ /dev/null
@@ -1,474 +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.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "os/queue.h"
-#include "os/os_mempool.h"
-#include "ble_hs_priv.h"
-
-struct ble_hci_sched_entry {
-    STAILQ_ENTRY(ble_hci_sched_entry) next;
-
-    ble_hci_sched_tx_fn *tx_cb;
-    void *tx_cb_arg;
-
-    uint8_t handle;
-};
-
-static STAILQ_HEAD(, ble_hci_sched_entry) ble_hci_sched_list;
-
-static void *ble_hci_sched_entry_mem;
-static struct os_mempool ble_hci_sched_entry_pool;
-static struct ble_hci_sched_entry *ble_hci_sched_cur_entry;
-static uint8_t ble_hci_sched_prev_handle;
-
-static ble_hci_sched_ack_fn *ble_hci_sched_ack_cb;
-static void *ble_hci_sched_ack_arg;
-
-static struct os_mutex ble_hci_sched_mutex;
-
-static void
-ble_hci_sched_lock(void)
-{
-    struct os_task *owner;
-    int rc;
-
-    owner = ble_hci_sched_mutex.mu_owner;
-    BLE_HS_DBG_ASSERT_EVAL(owner == NULL ||
-                           owner != os_sched_get_current_task());
-
-    rc = os_mutex_pend(&ble_hci_sched_mutex, 0xffffffff);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-static void
-ble_hci_sched_unlock(void)
-{
-    int rc;
-
-    rc = os_mutex_release(&ble_hci_sched_mutex);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-int
-ble_hci_sched_locked_by_cur_task(void)
-{
-    struct os_task *owner;
-
-    owner = ble_hci_sched_mutex.mu_owner;
-    return owner != NULL && owner == os_sched_get_current_task();
-}
-
-/**
- * Lock restrictions: none.
- */
-static struct ble_hci_sched_entry *
-ble_hci_sched_entry_alloc(void)
-{
-    struct ble_hci_sched_entry *entry;
-
-    entry = os_memblock_get(&ble_hci_sched_entry_pool);
-    if (entry != NULL) {
-        memset(entry, 0, sizeof *entry);
-    }
-
-    return entry;
-}
-
-/**
- * Lock restrictions: none.
- */
-static void
-ble_hci_sched_entry_free(struct ble_hci_sched_entry *entry)
-{
-    int rc;
-
-    rc = os_memblock_put(&ble_hci_sched_entry_pool, entry);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-}
-
-/**
- * Removes the specified entry from the HCI reservation list.
- *
- * Lock restrictions:
- *     o Caller locks hci_sched.
- */
-static void
-ble_hci_sched_entry_remove(struct ble_hci_sched_entry *entry,
-                           struct ble_hci_sched_entry *prev)
-{
-    if (os_started()) {
-        BLE_HS_DBG_ASSERT(ble_hci_sched_locked_by_cur_task());
-    }
-
-    if (prev == NULL) {
-        BLE_HS_DBG_ASSERT(STAILQ_FIRST(&ble_hci_sched_list) == entry);
-        STAILQ_REMOVE_HEAD(&ble_hci_sched_list, next);
-    } else {
-        BLE_HS_DBG_ASSERT(STAILQ_NEXT(prev, next) == prev);
-        STAILQ_NEXT(prev, next) = STAILQ_NEXT(prev, next);
-    }
-}
-
-/**
- * Generates an HCI handle for a newly-allocated entry.
- *
- * Lock restrictions:
- *     o Caller unlocks hci_sched.
- *
- * @return                      A new HCI handle.
- */
-static uint8_t
-ble_hci_sched_new_handle(void)
-{
-    uint8_t handle;
-
-    ble_hci_sched_lock();
-
-    ble_hci_sched_prev_handle++;
-    if (ble_hci_sched_prev_handle == BLE_HCI_SCHED_HANDLE_NONE) {
-        ble_hci_sched_prev_handle++;
-    }
-
-    handle = ble_hci_sched_prev_handle;
-
-    ble_hci_sched_unlock();
-
-    return handle;
-}
-
-/**
- * Schedules an HCI transmit slot.  When it is the slot's turn to transmit,
- * the specified callback is executed.  The expectation is for the callback to
- * transmit an HCI command via the functions in host_hci_cmd.c.
- *
- * Lock restrictions:
- *     o Caller unlocks hci_sched.
- *
- * @param tx_cb                 Callback that gets executed when a transmit
- *                                  slot is available; should send a single
- *                                  HCI command.
- * @param tx_cb_arg             Argument that gets passed to the tx callback.
- * @param out_hci_handle        On success, the HCI slot handle gets written
- *                                  here.  This handle can be used to cancel
- *                                  the HCI slot reservation.  You can pass
- *                                  null here if you won't need to cancel.
- *
- * @return                      0 on success; BLE_HS_E[...] on failure.
- */
-int
-ble_hci_sched_enqueue(ble_hci_sched_tx_fn *tx_cb, void *tx_cb_arg,
-                      uint8_t *out_hci_handle)
-{
-    struct ble_hci_sched_entry *entry;
-
-    entry = ble_hci_sched_entry_alloc();
-    if (entry == NULL) {
-        return BLE_HS_ENOMEM;
-    }
-
-    entry->handle = ble_hci_sched_new_handle();
-    entry->tx_cb = tx_cb;
-    entry->tx_cb_arg = tx_cb_arg;
-
-    if (out_hci_handle != NULL) {
-        *out_hci_handle = entry->handle;
-    }
-
-    ble_hci_sched_lock();
-    STAILQ_INSERT_TAIL(&ble_hci_sched_list, entry, next);
-    ble_hci_sched_unlock();
-
-    if (ble_hci_sched_cur_entry == NULL) {
-        ble_hs_kick_hci();
-    }
-
-    return 0;
-}
-
-/**
- * Cancels the HCI slot reservation with the specified handle.  If the slot
- * being cancelled is already in progress, the HCI ack callback is reset, and
- * the next HCI slot is initiated (if there is one).
- *
- * Lock restrictions:
- *     o Caller unlocks hci_sched.
- *
- * @param handle                The handle of the slot to cancel.
- *
- * @return                      0 on success; BLE_HS_E[...] on failure.
- */
-int
-ble_hci_sched_cancel(uint8_t handle)
-{
-    struct ble_hci_sched_entry *entry;
-    struct ble_hci_sched_entry *prev;
-    int do_kick;
-    int rc;
-
-    ble_hci_sched_lock();
-
-    if (ble_hci_sched_cur_entry != NULL &&
-        ble_hci_sched_cur_entry->handle == handle) {
-
-        /* User is cancelling an in-progress operation. */
-        entry = ble_hci_sched_cur_entry;
-        ble_hci_sched_cur_entry = NULL;
-        ble_hci_sched_set_ack_cb(NULL, NULL);
-        do_kick = !STAILQ_EMPTY(&ble_hci_sched_list);
-    } else {
-        do_kick = 0;
-
-        prev = NULL;
-        STAILQ_FOREACH(entry, &ble_hci_sched_list, next) {
-            if (entry->handle == handle) {
-                ble_hci_sched_entry_remove(entry, prev);
-                break;
-            }
-
-            prev = entry;
-        }
-    }
-
-    ble_hci_sched_unlock();
-
-    if (entry == NULL) {
-        rc = BLE_HS_ENOENT;
-    } else {
-        ble_hci_sched_entry_free(entry);
-        rc = 0;
-    }
-
-    if (do_kick) {
-        ble_hs_kick_hci();
-    }
-
-    return rc;
-}
-
-/**
- * Executes the specified scheduled HCI transmit slot.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
- * @return                      0 on success; nonzero on failure.
- */
-static int
-ble_hci_sched_tx(struct ble_hci_sched_entry *entry)
-{
-    int rc;
-
-    ble_hs_misc_assert_no_locks();
-
-    rc = entry->tx_cb(entry->tx_cb_arg);
-    if (rc == 0) {
-        ble_hci_sched_cur_entry = entry;
-    }
-
-    return rc;
-}
-
-/**
- * Executes the next scheduled HCI transmit slot if there is one.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
- * @return                      0 if no more slots should be executed (either a
- *                                  transmit succeeded or there are no more
- *                                  reserved slots);
- *                              BLE_HS_EAGAIN if the next slot should be
- *                                  executed.
- */
-static int
-ble_hci_sched_process_next(void)
-{
-    struct ble_hci_sched_entry *entry;
-    int rc;
-
-    BLE_HS_DBG_ASSERT(ble_hci_sched_cur_entry == NULL);
-
-    ble_hci_sched_lock();
-
-    entry = STAILQ_FIRST(&ble_hci_sched_list);
-    if (entry != NULL) {
-        STAILQ_REMOVE_HEAD(&ble_hci_sched_list, next);
-    }
-
-    ble_hci_sched_unlock();
-
-    if (entry == NULL) {
-        rc = 0;
-    } else {
-        rc = ble_hci_sched_tx(entry);
-        if (rc != 0) {
-            ble_hci_sched_entry_free(entry);
-            rc = BLE_HS_EAGAIN;
-        }
-    }
-
-    return rc;
-}
-
-/**
- * Executes the next scheduled HCI transmit slot if there is one.  If a
- * transmit fails (i.e., the user callback returns nonzero), the corresponding
- * slot is freed and the next slot is executed.  This process repeats until
- * either:
- *     o A transmit succeeds, or
- *     o There are no more scheduled transmit slots.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-void
-ble_hci_sched_wakeup(void)
-{
-    int rc;
-
-    do {
-        rc = ble_hci_sched_process_next();
-    } while (rc == BLE_HS_EAGAIN);
-}
-
-/**
- * Called when the controller has acknowledged the current HCI command.
- * Acknowledgment occurs via either a command-complete or command-status HCI
- * event.
- *
- * Lock restrictions:
- *     o Caller unlocks hci_sched.
- */
-static void
-ble_hci_sched_transaction_complete(void)
-{
-    struct ble_hci_sched_entry *entry;
-
-    ble_hci_sched_lock();
-
-    entry = ble_hci_sched_cur_entry;
-    ble_hci_sched_cur_entry = NULL;
-
-    ble_hci_sched_unlock();
-
-    if (entry != NULL) {
-        ble_hci_sched_entry_free(entry);
-    }
-
-    if (!STAILQ_EMPTY(&ble_hci_sched_list)) {
-        ble_hs_kick_hci();
-    }
-}
-
-void
-ble_hci_sched_rx_ack(struct ble_hci_ack *ack)
-{
-    ble_hci_sched_ack_fn *cb;
-
-    if (ble_hci_sched_ack_cb != NULL) {
-        cb = ble_hci_sched_ack_cb;
-        ble_hci_sched_ack_cb = NULL;
-
-        ack->bha_hci_handle = ble_hci_sched_prev_handle;
-        cb(ack, ble_hci_sched_ack_arg);
-    }
-
-    ble_hci_sched_transaction_complete();
-}
-
-void
-ble_hci_sched_set_ack_cb(ble_hci_sched_ack_fn *cb, void *arg)
-{
-    /* Don't allow the current callback to be replaced with another. */
-    BLE_HS_DBG_ASSERT(ble_hci_sched_ack_cb == NULL || cb == NULL);
-
-    ble_hci_sched_ack_cb = cb;
-    ble_hci_sched_ack_arg = arg;
-}
-
-/**
- * This is really only useful for unit testing.
- *
- * Lock restrictions: none.
- */
-ble_hci_sched_ack_fn *
-ble_hci_sched_get_ack_cb(void)
-{
-    return ble_hci_sched_ack_cb;
-}
-
-/**
- * Lock restrictions: none.
- */
-static void
-ble_hci_sched_free_mem(void)
-{
-    free(ble_hci_sched_entry_mem);
-    ble_hci_sched_entry_mem = NULL;
-}
-
-/**
- * Lock restrictions: none.
- */
-int
-ble_hci_sched_init(void)
-{
-    int rc;
-
-    ble_hci_sched_free_mem();
-
-    rc = os_mutex_init(&ble_hci_sched_mutex);
-    if (rc != 0) {
-        rc = BLE_HS_EOS;
-        goto err;
-    }
-
-    if (ble_hs_cfg.max_hci_tx_slots > 0) {
-        ble_hci_sched_entry_mem = malloc(
-            OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_tx_slots,
-                             sizeof (struct ble_hci_sched_entry)));
-        if (ble_hci_sched_entry_mem == NULL) {
-            rc = BLE_HS_ENOMEM;
-            goto err;
-        }
-
-        rc = os_mempool_init(&ble_hci_sched_entry_pool,
-                             ble_hs_cfg.max_hci_tx_slots,
-                             sizeof (struct ble_hci_sched_entry),
-                             ble_hci_sched_entry_mem,
-                             "ble_hci_sched_entry_pool");
-        if (rc != 0) {
-            rc = BLE_HS_EOS;
-            goto err;
-        }
-    }
-
-    STAILQ_INIT(&ble_hci_sched_list);
-
-    ble_hci_sched_cur_entry = NULL;
-    ble_hci_sched_set_ack_cb(NULL, NULL);
-
-    return 0;
-
-err:
-    ble_hci_sched_free_mem();
-    return rc;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_sched.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_sched.h b/net/nimble/host/src/ble_hci_sched.h
deleted file mode 100644
index a53f06e..0000000
--- a/net/nimble/host/src/ble_hci_sched.h
+++ /dev/null
@@ -1,47 +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_BLE_HCI_SCHED_
-#define H_BLE_HCI_SCHED_
-
-#define BLE_HCI_SCHED_HANDLE_NONE       0
-
-struct ble_hci_ack {
-    int bha_status;         /* A BLE_HS_E<...> error; NOT a naked HCI code. */
-    uint8_t *bha_params;
-    int bha_params_len;
-    uint16_t bha_opcode;
-    uint8_t bha_hci_handle;
-};
-
-typedef int ble_hci_sched_tx_fn(void *arg);
-typedef void ble_hci_sched_ack_fn(struct ble_hci_ack *ack, void *arg);
-
-int ble_hci_sched_locked_by_cur_task(void);
-
-int ble_hci_sched_enqueue(ble_hci_sched_tx_fn *tx_cb, void *tx_cb_arg,
-                          uint8_t *out_hci_handle);
-int ble_hci_sched_cancel(uint8_t handle);
-void ble_hci_sched_wakeup(void);
-void ble_hci_sched_rx_ack(struct ble_hci_ack *ack);
-void ble_hci_sched_set_ack_cb(ble_hci_sched_ack_fn *cb, void *arg);
-ble_hci_sched_ack_fn *ble_hci_sched_get_ack_cb(void);
-int ble_hci_sched_init(void);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util.c b/net/nimble/host/src/ble_hci_util.c
new file mode 100644
index 0000000..2ff159d
--- /dev/null
+++ b/net/nimble/host/src/ble_hci_util.c
@@ -0,0 +1,78 @@
+/**
+ * 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.
+ */
+
+#include <string.h>
+#include "nimble/hci_common.h"
+#include "host/host_hci.h"
+#include "ble_hs_priv.h"
+
+int
+ble_hci_util_read_adv_tx_pwr(int8_t *out_tx_pwr)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t params_len;
+    int rc;
+
+    host_hci_cmd_build_read_adv_pwr(buf, sizeof buf);
+    rc = ble_hci_tx_cmd(buf, out_tx_pwr, 1, &params_len);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (params_len != 1                     ||
+        *out_tx_pwr < BLE_HCI_ADV_CHAN_TXPWR_MIN ||
+        *out_tx_pwr > BLE_HCI_ADV_CHAN_TXPWR_MAX) {
+
+        return BLE_HS_ECONTROLLER;
+    }
+
+    return 0;
+}
+
+int
+ble_hci_util_rand(void *dst, int len)
+{
+    uint8_t rsp_buf[BLE_HCI_LE_RAND_LEN];
+    uint8_t req_buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t params_len;
+    uint8_t *u8ptr;
+    int chunk_sz;
+    int rc;
+
+    host_hci_cmd_build_le_rand(req_buf, sizeof req_buf);
+
+    u8ptr = dst;
+    while (len > 0) {
+        rc = ble_hci_tx_cmd(req_buf, rsp_buf, sizeof rsp_buf, &params_len);
+        if (rc != 0) {
+            return rc;
+        }
+        if (params_len != sizeof rsp_buf) {
+            return BLE_HS_ECONTROLLER;
+        }
+
+        chunk_sz = min(len, sizeof rsp_buf);
+        memcpy(u8ptr, rsp_buf, chunk_sz);
+
+        len -= chunk_sz;
+        u8ptr += chunk_sz;
+    }
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util.h b/net/nimble/host/src/ble_hci_util.h
new file mode 100644
index 0000000..c259d6d
--- /dev/null
+++ b/net/nimble/host/src/ble_hci_util.h
@@ -0,0 +1,26 @@
+/**
+ * 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_BLE_HCI_UTIL_
+#define H_BLE_HCI_UTIL_
+
+int ble_hci_util_read_adv_tx_pwr(int8_t *out_pwr);
+int ble_hci_util_rand(void *dst, int len);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 0a518d1..2de2bf9 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -40,9 +40,6 @@ static struct log_handler ble_hs_log_console_handler;
 struct ble_hs_dev ble_hs_our_dev;
 struct log ble_hs_log;
 
-struct os_task ble_hs_task;
-static os_stack_t ble_hs_stack[BLE_HS_STACK_SIZE] bssnz_t;
-
 #define HCI_CMD_BUF_SIZE    (260)       /* XXX: temporary, Fix later */
 struct os_mempool g_hci_cmd_pool;
 static void *ble_hs_hci_cmd_buf;
@@ -65,17 +62,17 @@ static void *ble_hs_hci_os_event_buf;
  * shortage.
  */
 static struct os_callout_func ble_hs_heartbeat_timer;
+static struct os_callout_func ble_hs_event_co;
 
 /* Host HCI Task Events */
-struct os_eventq ble_hs_evq;
-static struct os_event ble_hs_kick_hci_ev;
-static struct os_event ble_hs_kick_gatt_ev;
-static struct os_event ble_hs_kick_l2cap_sig_ev;
-static struct os_event ble_hs_kick_l2cap_sm_ev;
+static struct os_eventq ble_hs_evq;
+static struct os_eventq *ble_hs_app_evq;
 
 static struct os_mqueue ble_hs_rx_q;
 static struct os_mqueue ble_hs_tx_q;
 
+static struct os_mutex ble_hs_mutex;
+
 STATS_SECT_DECL(ble_hs_stats) ble_hs_stats;
 STATS_NAME_START(ble_hs_stats)
     STATS_NAME(ble_hs_stats, conn_create)
@@ -87,6 +84,36 @@ STATS_NAME_START(ble_hs_stats)
 STATS_NAME_END(ble_hs_stats)
 
 void
+ble_hs_lock(void)
+{
+    struct os_task *owner;
+    int rc;
+
+    owner = ble_hs_mutex.mu_owner;
+    if (owner != NULL) {
+        BLE_HS_DBG_ASSERT_EVAL(owner != os_sched_get_current_task());
+    }
+
+    rc = os_mutex_pend(&ble_hs_mutex, 0xffffffff);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
+}
+
+void
+ble_hs_unlock(void)
+{
+    int rc;
+
+    rc = os_mutex_release(&ble_hs_mutex);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
+}
+
+int
+ble_hs_locked(void)
+{
+    return ble_hs_mutex.mu_level > 0;
+}
+
+void
 ble_hs_process_tx_data_queue(void)
 {
     struct os_mbuf *om;
@@ -130,28 +157,32 @@ ble_hs_heartbeat_timer_reset(void)
 static void
 ble_hs_heartbeat(void *unused)
 {
-    ble_hs_misc_assert_no_locks();
+    ble_hs_misc_assert_not_locked();
 
     ble_gattc_heartbeat();
     ble_gap_heartbeat();
+    ble_l2cap_sig_heartbeat();
     ble_l2cap_sm_heartbeat();
 
     ble_hs_heartbeat_timer_reset();
 }
 
 static void
-ble_hs_task_handler(void *arg)
+ble_hs_event_handle(void *unused)
 {
-    struct os_event *ev;
     struct os_callout_func *cf;
-    int rc;
+    struct os_event *ev;
+    os_sr_t sr;
 
-    ble_hs_heartbeat_timer_reset();
+    while (1) {
+        OS_ENTER_CRITICAL(sr);
+        ev = STAILQ_FIRST(&ble_hs_evq.evq_list);
+        OS_EXIT_CRITICAL(sr);
 
-    rc = ble_hs_startup_go();
-    assert(rc == 0);
+        if (ev == NULL) {
+            break;
+        }
 
-    while (1) {
         ev = os_eventq_get(&ble_hs_evq);
         switch (ev->ev_type) {
         case OS_EVENT_T_TIMER:
@@ -170,22 +201,6 @@ ble_hs_task_handler(void *arg)
             ble_hs_process_rx_data_queue();
             break;
 
-        case BLE_HS_KICK_HCI_EVENT:
-            ble_hci_sched_wakeup();
-            break;
-
-        case BLE_HS_KICK_GATT_EVENT:
-            ble_gattc_wakeup();
-            break;
-
-        case BLE_HS_KICK_L2CAP_SIG_EVENT:
-            ble_l2cap_sig_wakeup();
-            break;
-
-        case BLE_HS_KICK_L2CAP_SM_EVENT:
-            ble_l2cap_sm_wakeup();
-            break;
-
         default:
             BLE_HS_DBG_ASSERT(0);
             break;
@@ -193,6 +208,24 @@ ble_hs_task_handler(void *arg)
     }
 }
 
+void
+ble_hs_event_enqueue(struct os_event *ev)
+{
+    os_eventq_put(&ble_hs_evq, ev);
+    os_eventq_put(ble_hs_app_evq, &ble_hs_event_co.cf_c.c_ev);
+}
+
+int
+ble_hs_start(void)
+{
+    int rc;
+
+    ble_hs_heartbeat_timer_reset();
+
+    rc = ble_hs_startup_go();
+    return rc;
+}
+
 /**
  * Called when a data packet is received from the controller.  This function
  * consumes the supplied mbuf, regardless of the outcome.
@@ -211,6 +244,7 @@ ble_hs_rx_data(struct os_mbuf *om)
     if (rc != 0) {
         return BLE_HS_EOS;
     }
+    os_eventq_put(ble_hs_app_evq, &ble_hs_event_co.cf_c.c_ev);
 
     return 0;
 }
@@ -224,46 +258,11 @@ ble_hs_tx_data(struct os_mbuf *om)
     if (rc != 0) {
         return BLE_HS_EOS;
     }
+    os_eventq_put(ble_hs_app_evq, &ble_hs_event_co.cf_c.c_ev);
 
     return 0;
 }
 
-/**
- * Wakes the BLE host task so that it can process hci events.
- */
-void
-ble_hs_kick_hci(void)
-{
-    os_eventq_put(&ble_hs_evq, &ble_hs_kick_hci_ev);
-}
-
-/**
- * Wakes the BLE host task so that it can process GATT events.
- */
-void
-ble_hs_kick_gatt(void)
-{
-    os_eventq_put(&ble_hs_evq, &ble_hs_kick_gatt_ev);
-}
-
-/**
- * Wakes the BLE host task so that it can process L2CAP sig events.
- */
-void
-ble_hs_kick_l2cap_sig(void)
-{
-    os_eventq_put(&ble_hs_evq, &ble_hs_kick_l2cap_sig_ev);
-}
-
-/**
- * Wakes the BLE host task so that it can process L2CAP security events.
- */
-void
-ble_hs_kick_l2cap_sm(void)
-{
-    os_eventq_put(&ble_hs_evq, &ble_hs_kick_l2cap_sm_ev);
-}
-
 static void
 ble_hs_free_mem(void)
 {
@@ -278,21 +277,24 @@ ble_hs_free_mem(void)
  * Initializes the host portion of the BLE stack.
  */
 int
-ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
+ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg)
 {
     int rc;
 
     ble_hs_free_mem();
 
+    if (app_evq == NULL) {
+        rc = BLE_HS_EINVAL;
+        goto err;
+    }
+    ble_hs_app_evq = app_evq;
+
     ble_hs_cfg_init(cfg);
 
     log_init();
     log_console_handler_init(&ble_hs_log_console_handler);
     log_register("ble_hs", &ble_hs_log, &ble_hs_log_console_handler);
 
-    os_task_init(&ble_hs_task, "ble_hs", ble_hs_task_handler, NULL, prio,
-                 OS_WAIT_FOREVER, ble_hs_stack, BLE_HS_STACK_SIZE);
-
     ble_hs_hci_cmd_buf = malloc(OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs,
                                                  HCI_CMD_BUF_SIZE));
     if (ble_hs_hci_cmd_buf == NULL) {
@@ -356,11 +358,6 @@ ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
         goto err;
     }
 
-    rc = ble_hci_sched_init();
-    if (rc != 0) {
-        goto err;
-    }
-
     rc = ble_gattc_init();
     if (rc != 0) {
         goto err;
@@ -371,24 +368,6 @@ ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
         goto err;
     }
 
-    ble_hci_block_init();
-
-    ble_hs_kick_hci_ev.ev_queued = 0;
-    ble_hs_kick_hci_ev.ev_type = BLE_HS_KICK_HCI_EVENT;
-    ble_hs_kick_hci_ev.ev_arg = NULL;
-
-    ble_hs_kick_gatt_ev.ev_queued = 0;
-    ble_hs_kick_gatt_ev.ev_type = BLE_HS_KICK_GATT_EVENT;
-    ble_hs_kick_gatt_ev.ev_arg = NULL;
-
-    ble_hs_kick_l2cap_sig_ev.ev_queued = 0;
-    ble_hs_kick_l2cap_sig_ev.ev_type = BLE_HS_KICK_L2CAP_SIG_EVENT;
-    ble_hs_kick_l2cap_sig_ev.ev_arg = NULL;
-
-    ble_hs_kick_l2cap_sm_ev.ev_queued = 0;
-    ble_hs_kick_l2cap_sm_ev.ev_type = BLE_HS_KICK_L2CAP_SM_EVENT;
-    ble_hs_kick_l2cap_sm_ev.ev_arg = NULL;
-
     os_mqueue_init(&ble_hs_rx_q, NULL);
     os_mqueue_init(&ble_hs_tx_q, NULL);
 
@@ -400,8 +379,16 @@ ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
         goto err;
     }
 
-    os_callout_func_init(&ble_hs_heartbeat_timer, &ble_hs_evq,
+    os_callout_func_init(&ble_hs_heartbeat_timer, ble_hs_app_evq,
                          ble_hs_heartbeat, NULL);
+    os_callout_func_init(&ble_hs_event_co, &ble_hs_evq,
+                         ble_hs_event_handle, NULL);
+
+    rc = os_mutex_init(&ble_hs_mutex);
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
 
     return 0;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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
new file mode 100644
index 0000000..4aeabe6
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_atomic.c
@@ -0,0 +1,45 @@
+/**
+ * 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.
+ */
+
+#include "ble_hs_priv.h"
+
+int
+ble_hs_atomic_conn_delete(uint16_t conn_handle)
+{
+    struct ble_hs_conn *conn;
+
+    ble_hs_lock();
+    conn = ble_hs_conn_find(conn_handle);
+    if (conn != NULL) {
+        ble_hs_conn_remove(conn);
+        ble_hs_conn_free(conn);
+
+    }
+    ble_hs_unlock();
+
+    return conn != NULL ? 0 : BLE_HS_ENOTCONN;
+}
+
+void
+ble_hs_atomic_conn_insert(struct ble_hs_conn *conn)
+{
+    ble_hs_lock();
+    ble_hs_conn_insert(conn);
+    ble_hs_unlock();
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_atomic.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic.h b/net/nimble/host/src/ble_hs_atomic.h
new file mode 100644
index 0000000..5bb3665
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_atomic.h
@@ -0,0 +1,25 @@
+/**
+ * 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_BLE_HS_ATOMIC_
+#define H_BLE_HS_ATOMIC_
+
+int ble_hs_atomic_conn_delete(uint16_t conn_handle);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_cfg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_cfg.c b/net/nimble/host/src/ble_hs_cfg.c
index 860ef3c..0aa966a 100644
--- a/net/nimble/host/src/ble_hs_cfg.c
+++ b/net/nimble/host/src/ble_hs_cfg.c
@@ -22,7 +22,6 @@
 const struct ble_hs_cfg ble_hs_cfg_dflt = {
     /** HCI settings. */
     .max_hci_bufs = 8,
-    .max_hci_tx_slots = 8,
 
     /** Connection settings. */
     .max_outstanding_pkts_per_conn = 5,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.c b/net/nimble/host/src/ble_hs_conn.c
index 4d04a24..7c505ba 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -28,41 +28,6 @@ static struct os_mempool ble_hs_conn_pool;
 
 static os_membuf_t *ble_hs_conn_elem_mem;
 
-static struct os_mutex ble_hs_conn_mutex;
-
-void
-ble_hs_conn_lock(void)
-{
-    struct os_task *owner;
-    int rc;
-
-    owner = ble_hs_conn_mutex.mu_owner;
-    if (owner != NULL) {
-        BLE_HS_DBG_ASSERT_EVAL(owner != os_sched_get_current_task());
-    }
-
-    rc = os_mutex_pend(&ble_hs_conn_mutex, 0xffffffff);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-void
-ble_hs_conn_unlock(void)
-{
-    int rc;
-
-    rc = os_mutex_release(&ble_hs_conn_mutex);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-int
-ble_hs_conn_locked_by_cur_task(void)
-{
-    struct os_task *owner;
-
-    owner = ble_hs_conn_mutex.mu_owner;
-    return owner != NULL && owner == os_sched_get_current_task();
-}
-
 /**
  * Lock restrictions: none.
  */
@@ -255,12 +220,8 @@ ble_hs_conn_insert(struct ble_hs_conn *conn)
     return;
 #endif
 
-    ble_hs_conn_lock();
-
     BLE_HS_DBG_ASSERT_EVAL(ble_hs_conn_find(conn->bhc_handle) == NULL);
     SLIST_INSERT_HEAD(&ble_hs_conns, conn, bhc_next);
-
-    ble_hs_conn_unlock();
 }
 
 /**
@@ -297,23 +258,13 @@ ble_hs_conn_find(uint16_t conn_handle)
     return NULL;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_hs_conn_exists(uint16_t conn_handle)
 {
 #if !NIMBLE_OPT_CONNECT
     return 0;
 #endif
-
-    struct ble_hs_conn *conn;
-
-    ble_hs_conn_lock();
-    conn = ble_hs_conn_find(conn_handle);
-    ble_hs_conn_unlock();
-
-    return conn != NULL;
+    return ble_hs_conn_find(conn_handle) != NULL;
 }
 
 /**
@@ -326,7 +277,7 @@ ble_hs_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags)
     struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     conn = ble_hs_conn_find(conn_handle);
     if (conn == NULL) {
@@ -336,7 +287,7 @@ ble_hs_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags)
         *out_flags = conn->bhc_flags;
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     return rc;
 }
@@ -357,65 +308,6 @@ ble_hs_conn_first(void)
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
-static void
-ble_hs_conn_txable_transition(struct ble_hs_conn *conn)
-{
-    ble_gattc_connection_txable(conn->bhc_handle);
-}
-
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
-void
-ble_hs_conn_rx_num_completed_pkts(uint16_t handle, uint16_t num_pkts)
-{
-#if !NIMBLE_OPT_CONNECT
-    return;
-#endif
-
-    struct ble_hs_conn *conn;
-    int could_tx;
-    int can_tx;
-
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(handle);
-    if (conn != NULL) {
-        could_tx = ble_hs_conn_can_tx(conn);
-
-        if (num_pkts > conn->bhc_outstanding_pkts) {
-            num_pkts = conn->bhc_outstanding_pkts;
-        }
-        conn->bhc_outstanding_pkts -= num_pkts;
-
-        can_tx = ble_hs_conn_can_tx(conn);
-
-        if (!could_tx && can_tx) {
-            ble_hs_conn_txable_transition(conn);
-        }
-    }
-
-    ble_hs_conn_unlock();
-}
-
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
-int
-ble_hs_conn_can_tx(struct ble_hs_conn *conn)
-{
-#if !NIMBLE_OPT_CONNECT
-    return 0;
-#endif
-
-    return ble_hs_cfg.max_outstanding_pkts_per_conn == 0 ||
-           conn->bhc_outstanding_pkts <
-                ble_hs_cfg.max_outstanding_pkts_per_conn;
-}
-
-/**
  * Lock restrictions: None.
  */
 static void
@@ -435,12 +327,6 @@ ble_hs_conn_init(void)
 
     ble_hs_conn_free_mem();
 
-    rc = os_mutex_init(&ble_hs_conn_mutex);
-    if (rc != 0) {
-        rc = BLE_HS_EOS;
-        goto err;
-    }
-
     ble_hs_conn_elem_mem = malloc(
         OS_MEMPOOL_BYTES(ble_hs_cfg.max_connections,
                          sizeof (struct ble_hs_conn)));

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.h b/net/nimble/host/src/ble_hs_conn.h
index dc1acc3..0dd7bf6 100644
--- a/net/nimble/host/src/ble_hs_conn.h
+++ b/net/nimble/host/src/ble_hs_conn.h
@@ -30,6 +30,7 @@ struct ble_l2cap_chan;
 typedef uint8_t ble_hs_conn_flags_t;
 
 #define BLE_HS_CONN_F_MASTER        0x01
+#define BLE_HS_CONN_F_UPDATE        0x02
 
 struct ble_hs_conn {
     SLIST_ENTRY(ble_hs_conn) bhc_next;
@@ -56,9 +57,6 @@ struct ble_hs_conn {
     void *bhc_cb_arg;
 };
 
-void ble_hs_conn_lock(void);
-void ble_hs_conn_unlock(void);
-int ble_hs_conn_locked_by_cur_task(void);
 int ble_hs_conn_can_alloc(void);
 struct ble_hs_conn *ble_hs_conn_alloc(void);
 void ble_hs_conn_free(struct ble_hs_conn *conn);
@@ -72,8 +70,6 @@ struct ble_l2cap_chan *ble_hs_conn_chan_find(struct ble_hs_conn *conn,
                                              uint16_t cid);
 int ble_hs_conn_chan_insert(struct ble_hs_conn *conn,
                             struct ble_l2cap_chan *chan);
-void ble_hs_conn_rx_num_completed_pkts(uint16_t handle, uint16_t num_pkts);
-int ble_hs_conn_can_tx(struct ble_hs_conn *conn);
 int ble_hs_conn_init(void);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_misc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_misc.c b/net/nimble/host/src/ble_hs_misc.c
index 8335196..ab130bb 100644
--- a/net/nimble/host/src/ble_hs_misc.c
+++ b/net/nimble/host/src/ble_hs_misc.c
@@ -68,15 +68,9 @@ ble_hs_misc_log_flat_buf(void *data, int len)
 }
 
 void
-ble_hs_misc_assert_no_locks(void)
+ble_hs_misc_assert_not_locked(void)
 {
-    if (os_started()) {
-        assert(!ble_hs_conn_locked_by_cur_task()    &&
-               !ble_gattc_locked_by_cur_task()      &&
-               !ble_gap_locked_by_cur_task()        &&
-               !ble_hci_sched_locked_by_cur_task()  &&
-               !ble_l2cap_sm_locked_by_cur_task());
-    }
+    assert(!ble_hs_locked());
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 c9a5f86..09e9ef4 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -24,10 +24,8 @@
 #include <inttypes.h>
 #include "ble_att_cmd.h"
 #include "ble_att_priv.h"
-#include "ble_fsm_priv.h"
 #include "ble_gap_priv.h"
 #include "ble_gatt_priv.h"
-#include "ble_hci_sched.h"
 #include "ble_hs_adv_priv.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_endian.h"
@@ -35,6 +33,7 @@
 #include "ble_l2cap_priv.h"
 #include "ble_l2cap_sig.h"
 #include "ble_l2cap_sm.h"
+#include "ble_hci_util.h"
 #include "host/ble_hs.h"
 #include "log/log.h"
 #include "nimble/nimble_opt.h"
@@ -45,10 +44,6 @@ struct os_mbuf;
 struct os_mempool;
 
 #define BLE_HOST_HCI_EVENT_CTLR_EVENT   (OS_EVENT_T_PERUSER + 0)
-#define BLE_HS_KICK_HCI_EVENT           (OS_EVENT_T_PERUSER + 1)
-#define BLE_HS_KICK_GATT_EVENT          (OS_EVENT_T_PERUSER + 2)
-#define BLE_HS_KICK_L2CAP_SIG_EVENT     (OS_EVENT_T_PERUSER + 3)
-#define BLE_HS_KICK_L2CAP_SM_EVENT      (OS_EVENT_T_PERUSER + 4)
 
 STATS_SECT_START(ble_hs_stats)
     STATS_SECT_ENTRY(conn_create)
@@ -67,23 +62,24 @@ struct ble_hs_dev {
     unsigned has_random_addr:1;
 };
 
-extern struct os_task ble_hs_task;
+struct ble_hci_ack {
+    int bha_status;         /* A BLE_HS_E<...> error; NOT a naked HCI code. */
+    uint8_t *bha_params;
+    int bha_params_len;
+    uint16_t bha_opcode;
+    uint8_t bha_hci_handle;
+};
 
 extern struct ble_hs_dev ble_hs_our_dev;
 extern struct ble_hs_cfg ble_hs_cfg;
 
 extern struct os_mbuf_pool ble_hs_mbuf_pool;
-extern struct os_eventq ble_hs_evq;
 
 extern struct log ble_hs_log;
 
 void ble_hs_process_tx_data_queue(void);
 int ble_hs_rx_data(struct os_mbuf *om);
 int ble_hs_tx_data(struct os_mbuf *om);
-void ble_hs_kick_hci(void);
-void ble_hs_kick_gatt(void);
-void ble_hs_kick_l2cap_sig(void);
-void ble_hs_kick_l2cap_sm(void);
 
 int ble_hs_misc_malloc_mempool(void **mem, struct os_mempool *pool,
                                int num_entries, int entry_size, char *name);
@@ -96,30 +92,30 @@ int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid,
                                     struct ble_hs_conn **out_conn,
                                     struct ble_l2cap_chan **out_chan);
 
+int ble_hs_atomic_conn_delete(uint16_t conn_handle);
+void ble_hs_atomic_conn_insert(struct ble_hs_conn *conn);
+
 void ble_hs_cfg_init(struct ble_hs_cfg *cfg);
 
-void ble_hs_misc_assert_no_locks(void);
+void ble_hs_lock(void);
+void ble_hs_unlock(void);
+int ble_hs_locked(void);
+void ble_hs_misc_assert_not_locked(void);
 
 struct os_mbuf *ble_hs_misc_pkthdr(void);
 
 int ble_hs_misc_pullup_base(struct os_mbuf **om, int base_len);
 
-struct ble_hci_block_result {
-    uint8_t evt_buf_len;
-    uint8_t evt_total_len;
-};
+int ble_hci_tx_cmd(void *cmd, void *evt_buf, uint8_t evt_buf_len,
+                   uint8_t *out_evt_buf_len);
+int ble_hci_tx_cmd_empty_ack(void *cmd);
 
 #if PHONY_HCI_ACKS
-typedef int ble_hci_block_phony_ack_fn(void *cmd, uint8_t *ack,
-                                       int ack_buf_len);
+typedef int ble_hci_phony_ack_fn(uint8_t *ack, int ack_buf_len);
 
-void ble_hci_block_set_phony_ack_cb(ble_hci_block_phony_ack_fn *cb);
+void ble_hci_set_phony_ack_cb(ble_hci_phony_ack_fn *cb);
 #endif
 
-int ble_hci_block_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len,
-                     struct ble_hci_block_result *result);
-void ble_hci_block_init(void);
-
 #define BLE_HS_LOG(lvl, ...) \
     LOG_ ## lvl(&ble_hs_log, LOG_MODULE_NIMBLE_HOST, __VA_ARGS__)
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 b7cefb6..98be26c 100644
--- a/net/nimble/host/src/ble_hs_startup.c
+++ b/net/nimble/host/src/ble_hs_startup.c
@@ -23,159 +23,69 @@
 #include "host/ble_hs.h"
 #include "ble_hs_priv.h"
 
-#define BLE_HS_STARTUP_STATE_IDLE                       0
-#define BLE_HS_STARTUP_STATE_RESET                      1
-/* XXX: Read local supported commands. */
-/* XXX: Read local supported features. */
-#define BLE_HS_STARTUP_STATE_SET_EVMASK                 2
-#define BLE_HS_STARTUP_STATE_LE_SET_EVMASK              3
-#define BLE_HS_STARTUP_STATE_LE_READ_BUF_SZ             4
-/* XXX: Read buffer size. */
-#define BLE_HS_STARTUP_STATE_LE_READ_SUP_F              5
-/* XXX: Read BD_ADDR. */
-#define BLE_HS_STARTUP_STATE_MAX                        6
-
-static uint8_t ble_hs_startup_state;
-
-static int ble_hs_startup_reset_tx(void *arg);
-static int ble_hs_startup_set_evmask_tx(void *arg);
-static int ble_hs_startup_le_set_evmask_tx(void *arg);
-static int ble_hs_startup_le_read_buf_sz_tx(void *arg);
-static int ble_hs_startup_le_read_sup_f_tx(void *arg);
-
-static ble_hci_sched_tx_fn * const
-    ble_hs_startup_dispatch[BLE_HS_STARTUP_STATE_MAX] = {
-
-    [BLE_HS_STARTUP_STATE_IDLE]             = NULL,
-    [BLE_HS_STARTUP_STATE_RESET]            = ble_hs_startup_reset_tx,
-    [BLE_HS_STARTUP_STATE_SET_EVMASK]       = ble_hs_startup_set_evmask_tx,
-    [BLE_HS_STARTUP_STATE_LE_SET_EVMASK]    = ble_hs_startup_le_set_evmask_tx,
-    [BLE_HS_STARTUP_STATE_LE_READ_BUF_SZ]   = ble_hs_startup_le_read_buf_sz_tx,
-    [BLE_HS_STARTUP_STATE_LE_READ_SUP_F]    = ble_hs_startup_le_read_sup_f_tx,
-};
-
-static void
-ble_hs_startup_failure(int status)
-{
-    ble_hs_startup_state = BLE_HS_STARTUP_STATE_IDLE;
-    /* XXX: Signal failure. */
-}
-
 static int
-ble_hs_startup_enqueue_tx(void)
+ble_hs_startup_le_read_sup_f_tx(void)
 {
-    ble_hci_sched_tx_fn *tx_fn;
+    uint8_t ack_params[BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN];
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t ack_params_len;
     int rc;
 
-    if (ble_hs_startup_state == BLE_HS_STARTUP_STATE_MAX) {
-        return 0;
-    }
-
-    tx_fn = ble_hs_startup_dispatch[ble_hs_startup_state];
-    BLE_HS_DBG_ASSERT(tx_fn != NULL);
-
-    rc = ble_hci_sched_enqueue(tx_fn, NULL, NULL);
+    host_hci_cmd_build_le_read_loc_supp_feat(buf, sizeof buf);
+    rc = ble_hci_tx_cmd(buf, ack_params, sizeof ack_params, &ack_params_len);
     if (rc != 0) {
-        ble_hs_startup_failure(rc);
         return rc;
     }
 
-    return 0;
-}
-
-static void
-ble_hs_startup_gen_ack(struct ble_hci_ack *ack, void *arg)
-{
-    BLE_HS_DBG_ASSERT(ble_hs_startup_state < BLE_HS_STARTUP_STATE_MAX);
-
-    if (ack->bha_status != 0) {
-        ble_hs_startup_failure(ack->bha_status);
-        return;
-    }
-
-    ble_hs_startup_state++;
-    ble_hs_startup_enqueue_tx();
-}
-
-static void
-ble_hs_startup_le_read_sup_f_ack(struct ble_hci_ack *ack, void *arg)
-{
-    BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
-                      BLE_HS_STARTUP_STATE_LE_READ_SUP_F);
-
-    if (ack->bha_status != 0) {
-        ble_hs_startup_failure(ack->bha_status);
-        return;
-    }
-
-    if (ack->bha_params_len != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) {
-        ble_hs_startup_failure(BLE_HS_ECONTROLLER);
-        return;
+    if (ack_params_len != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) {
+        return BLE_HS_ECONTROLLER;
     }
 
     /* XXX: Do something with the supported features bit map. */
-}
-
-static int
-ble_hs_startup_le_read_sup_f_tx(void *arg)
-{
-    int rc;
-
-    BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
-                      BLE_HS_STARTUP_STATE_LE_READ_SUP_F);
-
-    ble_hci_sched_set_ack_cb(ble_hs_startup_le_read_sup_f_ack, NULL);
-    rc = host_hci_cmd_le_read_loc_supp_feat();
-    if (rc != 0) {
-        return rc;
-    }
 
     return 0;
 }
 
-static void
-ble_hs_startup_le_read_buf_size_ack(struct ble_hci_ack *ack, void *arg)
+static int
+ble_hs_startup_le_read_buf_sz_tx(void)
 {
     uint16_t pktlen;
+    uint8_t ack_params[BLE_HCI_RD_BUF_SIZE_RSPLEN];
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+    uint8_t ack_params_len;
     uint8_t max_pkts;
     int rc;
 
-    BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
-                      BLE_HS_STARTUP_STATE_LE_READ_BUF_SZ);
-
-    if (ack->bha_status != 0) {
-        ble_hs_startup_failure(ack->bha_status);
-        return;
+    host_hci_cmd_build_le_read_buffer_size(buf, sizeof buf);
+    rc = ble_hci_tx_cmd(buf, ack_params, sizeof ack_params, &ack_params_len);
+    if (rc != 0) {
+        return rc;
     }
 
-    if (ack->bha_params_len != BLE_HCI_RD_BUF_SIZE_RSPLEN + 1) {
-        ble_hs_startup_failure(BLE_HS_ECONTROLLER);
-        return;
+    if (ack_params_len != BLE_HCI_RD_BUF_SIZE_RSPLEN) {
+        return BLE_HS_ECONTROLLER;
     }
 
-    pktlen = le16toh(ack->bha_params + 1);
-    max_pkts = ack->bha_params[3];
+    pktlen = le16toh(ack_params + 0);
+    max_pkts = ack_params[2];
 
     rc = host_hci_set_buf_size(pktlen, max_pkts);
     if (rc != 0) {
-        ble_hs_startup_failure(rc);
-        return;
+        return rc;
     }
 
-    ble_hs_startup_state++;
-    ble_hs_startup_enqueue_tx();
+    return 0;
 }
 
 static int
-ble_hs_startup_le_read_buf_sz_tx(void *arg)
+ble_hs_startup_le_set_evmask_tx(void)
 {
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_LE_EVENT_MASK_LEN];
     int rc;
 
-    BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
-                      BLE_HS_STARTUP_STATE_LE_READ_BUF_SZ);
-
-    ble_hci_sched_set_ack_cb(ble_hs_startup_le_read_buf_size_ack, NULL);
-    rc = host_hci_cmd_le_read_buffer_size();
+    /* [ Default event set ]. */
+    host_hci_cmd_build_le_set_event_mask(0x000000000000001f, buf, sizeof buf);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -184,15 +94,14 @@ ble_hs_startup_le_read_buf_sz_tx(void *arg)
 }
 
 static int
-ble_hs_startup_le_set_evmask_tx(void *arg)
+ble_hs_startup_set_evmask_tx(void)
 {
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_EVENT_MASK_LEN];
     int rc;
 
-    BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
-                      BLE_HS_STARTUP_STATE_LE_SET_EVMASK);
-
-    ble_hci_sched_set_ack_cb(ble_hs_startup_gen_ack, NULL);
-    rc = host_hci_cmd_le_set_event_mask(0x000000000000001f);
+    /* [ Default event set | LE-meta event ]. */
+    host_hci_cmd_build_set_event_mask(0x20001fffffffffff, buf, sizeof buf);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -201,17 +110,13 @@ ble_hs_startup_le_set_evmask_tx(void *arg)
 }
 
 static int
-ble_hs_startup_set_evmask_tx(void *arg)
+ble_hs_startup_reset_tx(void)
 {
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
     int rc;
 
-    BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
-                      BLE_HS_STARTUP_STATE_SET_EVMASK);
-
-    ble_hci_sched_set_ack_cb(ble_hs_startup_gen_ack, NULL);
-
-    /* Default set + LE-meta event. */
-    rc = host_hci_cmd_set_event_mask(0x20001fffffffffff);
+    host_hci_cmd_build_reset(buf, sizeof buf);
+    rc = ble_hci_tx_cmd_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -219,33 +124,47 @@ ble_hs_startup_set_evmask_tx(void *arg)
     return 0;
 }
 
-static int
-ble_hs_startup_reset_tx(void *arg)
+int
+ble_hs_startup_go(void)
 {
     int rc;
 
-    BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
-                      BLE_HS_STARTUP_STATE_RESET);
+    rc = ble_hs_startup_reset_tx();
+    if (rc != 0) {
+        return rc;
+    }
+
+    /* XXX: Read local supported commands. */
+    /* XXX: Read local supported features. */
 
-    ble_hci_sched_set_ack_cb(ble_hs_startup_gen_ack, NULL);
-    rc = host_hci_cmd_reset();
+    rc = ble_hs_startup_set_evmask_tx();
     if (rc != 0) {
+        assert(0);
         return rc;
     }
 
-    return 0;
-}
+    rc = ble_hs_startup_le_set_evmask_tx();
+    if (rc != 0) {
+        assert(0);
+        return rc;
+    }
 
-int
-ble_hs_startup_go(void)
-{
-    int rc;
+    rc = ble_hs_startup_le_read_buf_sz_tx();
+    if (rc != 0) {
+        assert(0);
+        return rc;
+    }
+
+    /* XXX: Read buffer size. */
 
-    ble_hs_startup_state = BLE_HS_STARTUP_STATE_RESET;
+    rc = ble_hs_startup_le_read_sup_f_tx();
+    if (rc != 0) {
+        assert(0);
+        return rc;
+    }
 
-    /* XXX: Until we support reading the address from the controller. */
+    /* XXX: Read BD_ADDR. */
     memcpy(ble_hs_our_dev.public_addr, g_dev_addr, sizeof g_dev_addr);
 
-    rc = ble_hs_startup_enqueue_tx();
     return rc;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_ibeacon.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_ibeacon.c b/net/nimble/host/src/ble_ibeacon.c
index 9f610d2..896dc10 100644
--- a/net/nimble/host/src/ble_ibeacon.c
+++ b/net/nimble/host/src/ble_ibeacon.c
@@ -25,10 +25,9 @@
 int
 ble_ibeacon_set_adv_data(void *uuid128, uint16_t major, uint16_t minor)
 {
-    struct ble_hci_block_result result;
     struct ble_hs_adv_fields fields;
     uint8_t buf[BLE_IBEACON_MFG_DATA_SIZE];
-    uint8_t hci_cmd[BLE_HCI_CMD_HDR_LEN];
+    int8_t tx_pwr;
     int rc;
 
     /** Company identifier (Apple). */
@@ -48,13 +47,11 @@ ble_ibeacon_set_adv_data(void *uuid128, uint16_t major, uint16_t minor)
 
     /** Last byte (tx power level) filled in after HCI exchange. */
 
-    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR, 0,
-                       hci_cmd);
-
-    rc = ble_hci_block_tx(hci_cmd, buf + 24, 1, &result);
+    rc = ble_hci_util_read_adv_tx_pwr(&tx_pwr);
     if (rc != 0) {
         return rc;
     }
+    buf[24] = tx_pwr;
 
     memset(&fields, 0, sizeof fields);
     fields.mfg_data = buf;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_l2cap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_priv.h b/net/nimble/host/src/ble_l2cap_priv.h
index 9db54ea..2a728fc 100644
--- a/net/nimble/host/src/ble_l2cap_priv.h
+++ b/net/nimble/host/src/ble_l2cap_priv.h
@@ -111,7 +111,6 @@ struct ble_l2cap_chan
 
 SLIST_HEAD(ble_l2cap_chan_list, ble_l2cap_chan);
 
-int ble_l2cap_sig_locked_by_cur_task(void);
 int ble_l2cap_parse_hdr(struct os_mbuf *om, int off,
                         struct ble_l2cap_hdr *l2cap_hdr);
 struct os_mbuf *ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid,
@@ -151,7 +150,7 @@ int ble_l2cap_rx(struct ble_hs_conn *conn,
 int ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                  struct os_mbuf *om);
 
-void ble_l2cap_sig_wakeup(void);
+void ble_l2cap_sig_heartbeat(void);
 int ble_l2cap_sig_init(void);
 int ble_l2cap_init(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_l2cap_sig.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig.c b/net/nimble/host/src/ble_l2cap_sig.c
index e4a20b5..2f6b692 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -27,48 +27,38 @@
  * $definitions / declarations                                               *
  *****************************************************************************/
 
-#define BLE_L2CAP_SIG_HEARTBEAT_PERIOD          1000    /* Milliseconds. */
 #define BLE_L2CAP_SIG_UNRESPONSIVE_TIMEOUT      30000   /* Milliseconds. */
 
 #define BLE_L2CAP_SIG_PROC_OP_UPDATE            0
 #define BLE_L2CAP_SIG_PROC_OP_MAX               1
 
 struct ble_l2cap_sig_proc {
-    struct ble_fsm_proc fsm_proc;
+    STAILQ_ENTRY(ble_l2cap_sig_proc) next;
+
+    uint32_t exp_os_ticks;
+    uint16_t conn_handle;
+    uint8_t op;
     uint8_t id;
 
     union {
         struct {
-            struct ble_l2cap_sig_update_params params;
             ble_l2cap_sig_update_fn *cb;
             void *cb_arg;
         } update;
     };
 };
 
-/**
- * Handles unresponsive timeouts and periodic retries in case of resource
- * shortage.
- */
-static struct os_callout_func ble_l2cap_sig_heartbeat_timer;
+STAILQ_HEAD(ble_l2cap_sig_proc_list, ble_l2cap_sig_proc);
 
-typedef int ble_l2cap_sig_kick_fn(struct ble_l2cap_sig_proc *proc);
+static struct ble_l2cap_sig_proc_list ble_l2cap_sig_procs;
 
 typedef int ble_l2cap_sig_rx_fn(uint16_t conn_handle,
                                 struct ble_l2cap_sig_hdr *hdr,
                                 struct os_mbuf **om);
 
-static int ble_l2cap_sig_rx_noop(uint16_t conn_handle,
-                                 struct ble_l2cap_sig_hdr *hdr,
-                                 struct os_mbuf **om);
-static int ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
-                                       struct ble_l2cap_sig_hdr *hdr,
-                                       struct os_mbuf **om);
-static int ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle,
-                                       struct ble_l2cap_sig_hdr *hdr,
-                                       struct os_mbuf **om);
-
-static int ble_l2cap_sig_update_kick(struct ble_l2cap_sig_proc *proc);
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_rx_noop;
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_update_req_rx;
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_update_rsp_rx;
 
 static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = {
     [BLE_L2CAP_SIG_OP_REJECT]               = ble_l2cap_sig_rx_noop,
@@ -85,72 +75,15 @@ static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = {
     [BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP]   = ble_l2cap_sig_rx_noop,
 };
 
-static ble_l2cap_sig_kick_fn * const ble_l2cap_sig_kick[] = {
-    [BLE_L2CAP_SIG_PROC_OP_UPDATE]          = ble_l2cap_sig_update_kick,
-};
-
 static uint8_t ble_l2cap_sig_cur_id;
 
 static void *ble_l2cap_sig_proc_mem;
 static struct os_mempool ble_l2cap_sig_proc_pool;
 
-static struct ble_fsm ble_l2cap_sig_fsm;
-
-/*****************************************************************************
- * $mutex                                                                    *
- *****************************************************************************/
-
-void
-ble_l2cap_sig_lock(void)
-{
-    ble_fsm_lock(&ble_l2cap_sig_fsm);
-}
-
-void
-ble_l2cap_sig_unlock(void)
-{
-    ble_fsm_unlock(&ble_l2cap_sig_fsm);
-}
-
-int
-ble_l2cap_sig_locked_by_cur_task(void)
-{
-    return ble_fsm_locked_by_cur_task(&ble_l2cap_sig_fsm);
-}
-
 /*****************************************************************************
  * $misc                                                                     *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
-static ble_l2cap_sig_kick_fn *
-ble_l2cap_sig_kick_get(uint8_t op)
-{
-    if (op > BLE_L2CAP_SIG_PROC_OP_MAX) {
-        return NULL;
-    }
-
-    return ble_l2cap_sig_kick[op];
-}
-
-static int
-ble_l2cap_sig_proc_kick(struct ble_fsm_proc *proc)
-{
-    ble_l2cap_sig_kick_fn *kick_cb;
-    int rc;
-
-    kick_cb = ble_l2cap_sig_kick_get(proc->op);
-    rc = kick_cb((struct ble_l2cap_sig_proc *)proc);
-
-    return rc;
-}
-
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 static int
 ble_l2cap_sig_conn_chan_find(uint16_t conn_handle,
                              struct ble_hs_conn **out_conn,
@@ -163,9 +96,6 @@ ble_l2cap_sig_conn_chan_find(uint16_t conn_handle,
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint8_t
 ble_l2cap_sig_next_id(void)
 {
@@ -178,9 +108,6 @@ ble_l2cap_sig_next_id(void)
     return ble_l2cap_sig_cur_id;
 }
 
-/**
- * Lock restrictions: None.
- */
 static ble_l2cap_sig_rx_fn *
 ble_l2cap_sig_dispatch_get(uint8_t op)
 {
@@ -194,8 +121,6 @@ ble_l2cap_sig_dispatch_get(uint8_t op)
 /**
  * Allocates a proc entry.
  *
- * Lock restrictions: None.
- *
  * @return                      An entry on success; null on failure.
  */
 static struct ble_l2cap_sig_proc *
@@ -213,11 +138,9 @@ ble_l2cap_sig_proc_alloc(void)
 
 /**
  * Frees the specified proc entry.  No-op if passed a null pointer.
- *
- * Lock restrictions: None.
  */
 static void
-ble_l2cap_sig_proc_free(struct ble_fsm_proc *proc)
+ble_l2cap_sig_proc_free(struct ble_l2cap_sig_proc *proc)
 {
     int rc;
 
@@ -227,52 +150,34 @@ ble_l2cap_sig_proc_free(struct ble_fsm_proc *proc)
     }
 }
 
-/**
- * Lock restrictions: None.
- */
-static int
-ble_l2cap_sig_new_proc(uint16_t conn_handle, uint8_t op,
-                       struct ble_l2cap_sig_proc **out_proc)
+static void
+ble_l2cap_sig_proc_insert(struct ble_l2cap_sig_proc *proc)
 {
-    *out_proc = ble_l2cap_sig_proc_alloc();
-    if (*out_proc == NULL) {
-        return BLE_HS_ENOMEM;
-    }
-
-    memset(*out_proc, 0, sizeof **out_proc);
-    (*out_proc)->fsm_proc.op = op;
-    (*out_proc)->fsm_proc.conn_handle = conn_handle;
-    (*out_proc)->fsm_proc.tx_time = os_time_get();
-
-    STAILQ_INSERT_TAIL(&ble_l2cap_sig_fsm.procs, &(*out_proc)->fsm_proc, next);
-
-    return 0;
+    ble_hs_lock();
+    STAILQ_INSERT_HEAD(&ble_l2cap_sig_procs, proc, next);
+    ble_hs_unlock();
 }
 
 /**
  * Tests if a proc entry fits the specified criteria.
  *
- * Lock restrictions: None.
- *
  * @param proc                  The procedure to test.
  * @param conn_handle           The connection handle to match against.
  * @param op                    The op code to match against/
  * @param id                    The identifier to match against.
- * @param expecting_only        1=Only match entries expecting a response;
  *                                  0=Ignore this criterion.
  *
  * @return                      1 if the proc matches; 0 otherwise.
  */
 static int
 ble_l2cap_sig_proc_matches(struct ble_l2cap_sig_proc *proc,
-                           uint16_t conn_handle, uint8_t op, uint8_t id,
-                           int expecting_only)
+                           uint16_t conn_handle, uint8_t op, uint8_t id)
 {
-    if (conn_handle != proc->fsm_proc.conn_handle) {
+    if (conn_handle != proc->conn_handle) {
         return 0;
     }
 
-    if (op != proc->fsm_proc.op) {
+    if (op != proc->op) {
         return 0;
     }
 
@@ -280,43 +185,14 @@ ble_l2cap_sig_proc_matches(struct ble_l2cap_sig_proc *proc,
         return 0;
     }
 
-    if (expecting_only && !(proc->fsm_proc.flags & BLE_FSM_PROC_F_EXPECTING)) {
-        return 0;
-    }
-
     return 1;
 }
 
-struct ble_l2cap_sig_proc_extract_arg {
-    uint16_t conn_handle;
-    uint8_t op;
-    uint8_t id;
-};
-
-static int
-ble_l2cap_sig_proc_extract_cb(struct ble_fsm_proc *proc, void *arg)
-{
-    struct ble_l2cap_sig_proc_extract_arg *extract_arg;
-
-    extract_arg = arg;
-
-    if (ble_l2cap_sig_proc_matches((struct ble_l2cap_sig_proc *)proc,
-                                   extract_arg->conn_handle, extract_arg->op,
-                                   extract_arg->id, 1)) {
-        return BLE_FSM_EXTRACT_EMOVE_STOP;
-    } else {
-        return BLE_FSM_EXTRACT_EKEEP_CONTINUE;
-    }
-}
-
 /**
  * Searches the main proc list for an "expecting" entry whose connection handle
  * and op code match those specified.  If a matching entry is found, it is
  * removed from the list and returned.
  *
- * Lock restrictions:
- *     o Caller unlocks l2cap_sig.
- *
  * @param conn_handle           The connection handle to match against.
  * @param op                    The op code to match against.
  * @param identifier            The identifier to match against.
@@ -328,61 +204,44 @@ static struct ble_l2cap_sig_proc *
 ble_l2cap_sig_proc_extract(uint16_t conn_handle, uint8_t op,
                            uint8_t identifier)
 {
-    struct ble_l2cap_sig_proc_extract_arg extract_arg;
     struct ble_l2cap_sig_proc *proc;
-    int rc;
-
-    extract_arg.conn_handle = conn_handle;
-    extract_arg.op = op;
-    extract_arg.id = identifier;
-
-    rc = ble_fsm_proc_extract(&ble_l2cap_sig_fsm,
-                              (struct ble_fsm_proc **)&proc,
-                              ble_l2cap_sig_proc_extract_cb, &extract_arg);
-
-    if (rc != 0) {
-        proc = NULL;
+    struct ble_l2cap_sig_proc *prev;
+
+    ble_hs_lock();
+
+    prev = NULL;
+    STAILQ_FOREACH(proc, &ble_l2cap_sig_procs, next) {
+        if (ble_l2cap_sig_proc_matches(proc, conn_handle, op, identifier)) {
+            if (prev == NULL) {
+                STAILQ_REMOVE_HEAD(&ble_l2cap_sig_procs, next);
+            } else {
+                STAILQ_REMOVE_AFTER(&ble_l2cap_sig_procs, prev, next);
+            }
+            break;
+        }
     }
 
-    return proc;
-}
+    ble_hs_unlock();
 
-/**
- * Sets the specified proc entry's "pending" flag (i.e., indicates that the
- * L2CAP sig procedure is stalled until it transmits its next request).
- *
- * Lock restrictions: None.
- */
-static void
-ble_l2cap_sig_proc_set_pending(struct ble_l2cap_sig_proc *proc)
-{
-    ble_fsm_proc_set_pending(&proc->fsm_proc);
-    ble_hs_kick_l2cap_sig();
+    return proc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_l2cap_sig_rx_noop(uint16_t conn_handle,
                       struct ble_l2cap_sig_hdr *hdr,
                       struct os_mbuf **om)
 {
-    return 0;
+    return BLE_HS_ENOTSUP;
 }
 
 /*****************************************************************************
  * $update                                                                   *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static void
 ble_l2cap_sig_update_call_cb(struct ble_l2cap_sig_proc *proc, int status)
 {
-    BLE_HS_DBG_ASSERT(!ble_hs_conn_locked_by_cur_task());
+    ble_hs_misc_assert_not_locked();
 
     if (status != 0) {
         STATS_INC(ble_l2cap_stats, update_fail);
@@ -393,10 +252,6 @@ ble_l2cap_sig_update_call_cb(struct ble_l2cap_sig_proc *proc, int status)
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
                             struct ble_l2cap_sig_hdr *hdr,
@@ -415,12 +270,12 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
         return rc;
     }
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
     rc = ble_l2cap_sig_conn_chan_find(conn_handle, &conn, &chan);
     if (rc == 0) {
         is_master = conn->bhc_flags & BLE_HS_CONN_F_MASTER;
     }
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     if (rc != 0) {
         return rc;
@@ -458,13 +313,13 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
     /* Send L2CAP response. */
     rc = ble_l2cap_sig_update_rsp_tx(conn_handle, hdr->identifier,
                                      l2cap_result);
-    return rc;
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle,
                             struct ble_l2cap_sig_hdr *hdr,
@@ -475,12 +330,10 @@ ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle,
     int cb_status;
     int rc;
 
-    ble_hs_misc_assert_no_locks();
-
     proc = ble_l2cap_sig_proc_extract(conn_handle,
                                       BLE_L2CAP_SIG_PROC_OP_UPDATE,
                                       hdr->identifier);
-    if (proc ==  NULL) {
+    if (proc == NULL) {
         return BLE_HS_ENOENT;
     }
 
@@ -511,82 +364,69 @@ ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle,
 
 done:
     ble_l2cap_sig_update_call_cb(proc, cb_status);
-    ble_l2cap_sig_proc_free(&proc->fsm_proc);
-    return rc;
-}
-
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
-static int
-ble_l2cap_sig_update_kick(struct ble_l2cap_sig_proc *proc)
-{
-    struct ble_l2cap_sig_update_req req;
-    ble_hs_conn_flags_t flags;
-    int rc;
-
-    rc = ble_hs_conn_flags(proc->fsm_proc.conn_handle, &flags);
-    if (rc == 0) {
-        if (flags & BLE_HS_CONN_F_MASTER) {
-            /* Only the slave can initiate the L2CAP connection update
-             * procedure.
-             */
-            rc = BLE_HS_EINVAL;
-        }
-    }
-
-    if (rc == 0) {
-        proc->id = ble_l2cap_sig_next_id();
-        req.itvl_min = proc->update.params.itvl_min;
-        req.itvl_max = proc->update.params.itvl_max;
-        req.slave_latency = proc->update.params.slave_latency;
-        req.timeout_multiplier = proc->update.params.timeout_multiplier;
-
-        rc = ble_l2cap_sig_update_req_tx(proc->fsm_proc.conn_handle,
-                                         proc->id, &req);
-    }
-
-    if (rc != 0) {
-        ble_l2cap_sig_update_call_cb(proc, rc);
-        rc = BLE_HS_EDONE;
-    }
-
+    ble_l2cap_sig_proc_free(proc);
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_l2cap_sig_update(uint16_t conn_handle,
                      struct ble_l2cap_sig_update_params *params,
                      ble_l2cap_sig_update_fn *cb, void *cb_arg)
 {
+    struct ble_l2cap_sig_update_req req;
     struct ble_l2cap_sig_proc *proc;
+    ble_hs_conn_flags_t conn_flags;
     int rc;
 
+    proc = NULL;
+
     STATS_INC(ble_l2cap_stats, update_init);
 
-    rc = ble_l2cap_sig_new_proc(conn_handle, BLE_L2CAP_SIG_PROC_OP_UPDATE,
-                                &proc);
-    if (rc == 0) {
-        proc->update.params = *params;
-        proc->update.cb = cb;
-        proc->update.cb_arg = cb_arg;
+    rc = ble_hs_conn_flags(conn_handle, &conn_flags);
+    if (rc != 0) {
+        return rc;
+    }
+    if (conn_flags & BLE_HS_CONN_F_MASTER) {
+        /* Only the slave can initiate the L2CAP connection update
+         * procedure.
+         */
+        rc = BLE_HS_EINVAL;
+        goto err;
+    }
 
-        ble_l2cap_sig_proc_set_pending(proc);
-    } else {
+    proc = ble_l2cap_sig_proc_alloc();
+    if (proc == NULL) {
         STATS_INC(ble_l2cap_stats, update_fail);
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    proc->op = BLE_L2CAP_SIG_PROC_OP_UPDATE;
+    proc->id = ble_l2cap_sig_next_id();
+    proc->conn_handle = conn_handle;
+    proc->exp_os_ticks = os_time_get() + BLE_L2CAP_SIG_UNRESPONSIVE_TIMEOUT;
+    proc->update.cb = cb;
+    proc->update.cb_arg = cb_arg;
+
+    req.itvl_min = params->itvl_min;
+    req.itvl_max = params->itvl_max;
+    req.slave_latency = params->slave_latency;
+    req.timeout_multiplier = params->timeout_multiplier;
+
+    rc = ble_l2cap_sig_update_req_tx(conn_handle, proc->id, &req);
+    if (rc != 0) {
+        goto err;
     }
 
+    ble_l2cap_sig_proc_insert(proc);
+
     return 0;
+
+err:
+    ble_l2cap_sig_proc_free(proc);
+    return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -625,9 +465,6 @@ ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 struct ble_l2cap_chan *
 ble_l2cap_sig_create_chan(void)
 {
@@ -646,30 +483,39 @@ ble_l2cap_sig_create_chan(void)
     return chan;
 }
 
-static int
-ble_l2cap_sig_heartbeat_extract_cb(struct ble_fsm_proc *proc, void *arg)
+static void
+ble_l2cap_sig_extract_expired(struct ble_l2cap_sig_proc_list *dst_list)
 {
-    uint32_t *now;
-
-    now = arg;
+    struct ble_l2cap_sig_proc *proc;
+    struct ble_l2cap_sig_proc *prev;
+    struct ble_l2cap_sig_proc *next;
+    uint32_t now;
+    int32_t time_diff;
 
-    if (proc->flags & BLE_FSM_PROC_F_EXPECTING) {
-        if (*now - proc->tx_time >= BLE_L2CAP_SIG_UNRESPONSIVE_TIMEOUT) {
-            return BLE_FSM_EXTRACT_EMOVE_CONTINUE;
+    now = os_time_get();
+    STAILQ_INIT(dst_list);
+
+    ble_hs_lock();
+
+    prev = NULL;
+    proc = STAILQ_FIRST(&ble_l2cap_sig_procs);
+    while (proc != NULL) {
+        next = STAILQ_NEXT(proc, next);
+    
+        time_diff = now - proc->exp_os_ticks;
+        if (time_diff >= 0) {
+            if (prev == NULL) {
+                STAILQ_REMOVE_HEAD(&ble_l2cap_sig_procs, next);
+            } else {
+                STAILQ_REMOVE_AFTER(&ble_l2cap_sig_procs, prev, next);
+            }
+            STAILQ_INSERT_TAIL(dst_list, proc, next);
         }
-    }
 
-    /* If a proc failed due to low memory, don't extract it, but set its 
-     * pending bit.
-     */
-    if (proc->flags & BLE_FSM_PROC_F_NO_MEM) {
-        proc->flags &= ~BLE_FSM_PROC_F_NO_MEM;
-        if (ble_fsm_proc_can_pend(proc)) {
-            ble_fsm_proc_set_pending(proc);
-        }
+        proc = next;
     }
 
-    return BLE_FSM_EXTRACT_EKEEP_CONTINUE;
+    ble_hs_unlock();
 }
 
 /**
@@ -682,59 +528,25 @@ ble_l2cap_sig_heartbeat_extract_cb(struct ble_fsm_proc *proc, void *arg)
  * seconds are aborted, and their corresponding connection is terminated.
  *
  * Called by the heartbeat timer; executed every second.
- *
- * Lock restrictions: None.
  */
-static void
-ble_l2cap_sig_heartbeat(void *unused)
+void
+ble_l2cap_sig_heartbeat(void)
 {
-    struct ble_fsm_proc_list temp_list;
-    struct ble_fsm_proc *proc;
-    uint32_t ticks;
-    uint32_t now;
-    int rc;
-
-    ble_hs_misc_assert_no_locks();
-
-    now = os_time_get();
+    struct ble_l2cap_sig_proc_list temp_list;
+    struct ble_l2cap_sig_proc *proc;
 
     /* Remove timed-out procedures from the main list and insert them into a
-     * temporary list.  For any stalled procedures, set their pending bit so
-     * they can be retried.
+     * temporary list.
      */
-    ble_fsm_proc_extract_list(&ble_l2cap_sig_fsm, &temp_list,
-                              ble_l2cap_sig_heartbeat_extract_cb, &now);
+    ble_l2cap_sig_extract_expired(&temp_list);
 
     /* Terminate the connection associated with each timed-out procedure. */
     STAILQ_FOREACH(proc, &temp_list, next) {
         STATS_INC(ble_l2cap_stats, proc_timeout);
         ble_gap_terminate(proc->conn_handle);
     }
-
-    /* Concatenate the list of timed out procedures back onto the end of the
-     * main list.
-     */
-    ble_fsm_proc_concat(&ble_l2cap_sig_fsm, &temp_list);
-
-    ticks = BLE_L2CAP_SIG_HEARTBEAT_PERIOD * OS_TICKS_PER_SEC / 1000;
-    rc = os_callout_reset(&ble_l2cap_sig_heartbeat_timer.cf_c, ticks);
-        
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
-void
-ble_l2cap_sig_wakeup(void)
-{
-    ble_fsm_wakeup(&ble_l2cap_sig_fsm);
-}
-
-/**
- * Lock restrictions: None.
- */
 int
 ble_l2cap_sig_init(void)
 {
@@ -742,11 +554,7 @@ ble_l2cap_sig_init(void)
 
     free(ble_l2cap_sig_proc_mem);
 
-    rc = ble_fsm_new(&ble_l2cap_sig_fsm, ble_l2cap_sig_proc_kick,
-                     ble_l2cap_sig_proc_free);
-    if (rc != 0) {
-        goto err;
-    }
+    STAILQ_INIT(&ble_l2cap_sig_procs);
 
     if (ble_hs_cfg.max_l2cap_sig_procs > 0) {
         ble_l2cap_sig_proc_mem = malloc(
@@ -767,9 +575,6 @@ ble_l2cap_sig_init(void)
         }
     }
 
-    os_callout_func_init(&ble_l2cap_sig_heartbeat_timer, &ble_hs_evq,
-                         ble_l2cap_sig_heartbeat, NULL);
-
     return 0;
 
 err:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_l2cap_sig_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_cmd.c b/net/nimble/host/src/ble_l2cap_sig_cmd.c
index f5f6fa1..290dc43 100644
--- a/net/nimble/host/src/ble_l2cap_sig_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sig_cmd.c
@@ -65,7 +65,7 @@ ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom)
 
     STATS_INC(ble_l2cap_stats, sig_tx);
 
-    ble_hs_conn_lock();
+    ble_hs_lock();
 
     rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG,
                                          &conn, &chan);
@@ -73,7 +73,7 @@ ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom)
         rc = ble_l2cap_tx(conn, chan, txom);
     }
 
-    ble_hs_conn_unlock();
+    ble_hs_unlock();
 
     return rc;
 }


[15/50] [abbrv] incubator-mynewt-core git commit: Don't do anything in signal handlers when process is blocked in 'sigsuspend()'.

Posted by ma...@apache.org.
Don't do anything in signal handlers when process is blocked in 'sigsuspend()'.

When the OS is idling it may disable the periodic timer and enter the tickless
mode. The OS exits the tickless mode on arrival of an interrupt/signal (note
that OS time is incorrect when this happens). Thus it is important to call
'timer_handler()' to correct the OS time before executing anything else.


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

Branch: refs/heads/master
Commit: dd96f36edae81577343aeb3d439429e9d6eb710b
Parents: 27605cb
Author: Neel Natu <ne...@nahannisys.com>
Authored: Tue Apr 19 18:23:11 2016 -0700
Committer: Neel Natu <ne...@nahannisys.com>
Committed: Tue Apr 19 18:23:11 2016 -0700

----------------------------------------------------------------------
 libs/os/src/arch/sim/os_arch_sim.c | 101 +++++++++++++++++++++++---------
 1 file changed, 74 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/dd96f36e/libs/os/src/arch/sim/os_arch_sim.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/sim/os_arch_sim.c b/libs/os/src/arch/sim/os_arch_sim.c
index 7a3b27d..7bcca4d 100644
--- a/libs/os/src/arch/sim/os_arch_sim.c
+++ b/libs/os/src/arch/sim/os_arch_sim.c
@@ -57,6 +57,9 @@ static pid_t mypid;
 static sigset_t allsigs, nosigs;
 static void timer_handler(int sig);
 
+static bool suspended;      /* process is blocked in sigsuspend() */
+static sigset_t suspsigs;   /* signals delivered in sigsuspend() */
+
 /*
  * Called from 'os_arch_frame_init()' when setjmp returns indirectly via
  * longjmp. The return value of setjmp is passed to this function as 'rc'.
@@ -114,6 +117,17 @@ ctxsw_handler(int sig)
     int rc;
 
     OS_ASSERT_CRITICAL();
+
+    /*
+     * Just record that this handler was called when the process was blocked.
+     * The handler will be called after sigsuspend() returns in the correct
+     * order.
+     */
+    if (suspended) {
+        sigaddset(&suspsigs, sig);
+        return;
+    }
+
     t = os_sched_get_current_task();
     next_t = os_sched_next_task();
     if (t == next_t) {
@@ -195,11 +209,22 @@ os_arch_in_critical(void)
     return (sigismember(&omask, SIGALRM));
 }
 
+static struct {
+    int num;
+    void (*handler)(int sig);
+} signals[] = {
+    { SIGALRM, timer_handler },
+    { SIGURG, ctxsw_handler },
+};
+
+#define NUMSIGS     (sizeof(signals)/sizeof(signals[0]))
+
 void
 os_tick_idle(os_time_t ticks)
 {
-    int rc;
+    int i, rc, sig;
     struct itimerval it;
+    void (*handler)(int sig);
 
     OS_ASSERT_CRITICAL();
 
@@ -216,15 +241,28 @@ os_tick_idle(os_time_t ticks)
         assert(rc == 0);
     }
 
+    suspended = true;
+    sigemptyset(&suspsigs);
     sigsuspend(&nosigs);        /* Wait for a signal to wake us up */
+    suspended = false;
 
-    if (ticks > 0) {
-        /*
-         * Update OS time before anything else when coming out of
-         * the tickless regime.
-         */
+    /*
+     * Call handlers for signals delivered to the process during sigsuspend().
+     * The SIGALRM handler is called before any other handlers to ensure that
+     * OS time is always correct.
+     */
+    if (sigismember(&suspsigs, SIGALRM)) {
         timer_handler(SIGALRM);
+    }
+    for (i = 0; i < NUMSIGS; i++) {
+        sig = signals[i].num;
+        handler = signals[i].handler;
+        if (sig != SIGALRM && sigismember(&suspsigs, sig)) {
+            handler(sig);
+        }
+    }
 
+    if (ticks > 0) {
         /*
          * Enable the periodic timer interrupt.
          */
@@ -237,16 +275,6 @@ os_tick_idle(os_time_t ticks)
     }
 }
 
-static struct {
-    int num;
-    void (*handler)(int sig);
-} signals[] = {
-    { SIGALRM, timer_handler },
-    { SIGURG, ctxsw_handler },
-};
-
-#define NUMSIGS     (sizeof(signals)/sizeof(signals[0]))
-
 static void
 signals_init(void)
 {
@@ -299,24 +327,43 @@ timer_handler(int sig)
     static struct timeval time_last;
     static int time_inited; 
 
+    OS_ASSERT_CRITICAL();
+
+    /*
+     * Just record that this handler was called when the process was blocked.
+     * The handler will be called after sigsuspend() returns in the proper
+     * order.
+     */
+    if (suspended) {
+        sigaddset(&suspsigs, sig);
+        return;
+    }
+
     if (!time_inited) {
         gettimeofday(&time_last, NULL);
         time_inited = 1;
     }
 
     gettimeofday(&time_now, NULL);
-    timersub(&time_now, &time_last, &time_diff);
-
-    ticks = time_diff.tv_sec * OS_TICKS_PER_SEC;
-    ticks += time_diff.tv_usec / OS_USEC_PER_TICK;
 
-    /*
-     * Update 'time_last' but account for the remainder usecs that did not
-     * contribute towards whole 'ticks'.
-     */
-    time_diff.tv_sec = 0;
-    time_diff.tv_usec %= OS_USEC_PER_TICK;
-    timersub(&time_now, &time_diff, &time_last);
+    if (timercmp(&time_now, &time_last, >)) {
+        timersub(&time_now, &time_last, &time_diff);
+        ticks = time_diff.tv_sec * OS_TICKS_PER_SEC;
+        ticks += time_diff.tv_usec / OS_USEC_PER_TICK;
+        /*
+         * Update 'time_last' but account for the remainder usecs that did not
+         * contribute towards whole 'ticks'.
+         */
+        time_diff.tv_sec = 0;
+        time_diff.tv_usec %= OS_USEC_PER_TICK;
+        timersub(&time_now, &time_diff, &time_last);
+    } else {
+        /*
+         * XXX time went backwards so just start afresh.
+         */
+        time_last = time_now;
+        ticks = 0;
+    }
 
     os_time_advance(ticks);
 }


[30/50] [abbrv] incubator-mynewt-core git commit: nffs - Add 1000-append unit test.

Posted by ma...@apache.org.
nffs - Add 1000-append unit test.


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

Branch: refs/heads/master
Commit: 4d0a38707bdeeb2061b3089d627fc2cee13f1f6c
Parents: ff20497
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 20 17:59:15 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 20 17:59:15 2016 -0700

----------------------------------------------------------------------
 fs/nffs/src/test/arch/sim/nffs_test.c | 83 +++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4d0a3870/fs/nffs/src/test/arch/sim/nffs_test.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/test/arch/sim/nffs_test.c b/fs/nffs/src/test/arch/sim/nffs_test.c
index 8b3b03a..8078ea0 100644
--- a/fs/nffs/src/test/arch/sim/nffs_test.c
+++ b/fs/nffs/src/test/arch/sim/nffs_test.c
@@ -536,6 +536,7 @@ nffs_test_assert_system_once(const struct nffs_test_file_desc *root_dir)
 {
     struct nffs_inode_entry *inode_entry;
     struct nffs_hash_entry *entry;
+    struct nffs_hash_entry *next;
     int i;
 
     nffs_test_num_touched_entries = 0;
@@ -543,7 +544,7 @@ nffs_test_assert_system_once(const struct nffs_test_file_desc *root_dir)
     nffs_test_assert_branch_touched(nffs_root_dir);
 
     /* Ensure no orphaned inodes or blocks. */
-    NFFS_HASH_FOREACH(entry, i) {
+    NFFS_HASH_FOREACH(entry, i, next) {
         TEST_ASSERT(entry->nhe_flash_loc != NFFS_FLASH_LOC_NONE);
         if (nffs_hash_id_is_inode(entry->nhe_id)) {
             inode_entry = (void *)entry;
@@ -931,8 +932,10 @@ TEST_CASE(nffs_test_truncate)
 TEST_CASE(nffs_test_append)
 {
     struct fs_file *file;
+    uint32_t len;
+    char c;
     int rc;
-
+    int i;
 
     rc = nffs_format(nffs_area_descs);
     TEST_ASSERT(rc == 0);
@@ -978,6 +981,48 @@ TEST_CASE(nffs_test_append)
     nffs_test_util_assert_contents("/myfile.txt",
                                   "abcdefghijklmnopqrstuvwx", 24);
 
+    rc = fs_mkdir("/mydir");
+    TEST_ASSERT_FATAL(rc == 0);
+    rc = fs_open("/mydir/gaga.txt", FS_ACCESS_WRITE | FS_ACCESS_APPEND, &file);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    /*** Repeated appends to a large file. */
+    for (i = 0; i < 1000; i++) {
+        rc = fs_filelen(file, &len);
+        TEST_ASSERT_FATAL(rc == 0);
+        TEST_ASSERT(len == i);
+
+        c = '0' + i % 10;
+        rc = fs_write(file, &c, 1);
+        TEST_ASSERT_FATAL(rc == 0);
+    }
+
+    rc = fs_close(file);
+    TEST_ASSERT(rc == 0);
+
+    nffs_test_util_assert_contents("/mydir/gaga.txt",
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789"
+        "01234567890123456789012345678901234567890123456789",
+        1000);
+
     struct nffs_test_file_desc *expected_system =
         (struct nffs_test_file_desc[]) { {
             .filename = "",
@@ -987,6 +1032,37 @@ TEST_CASE(nffs_test_append)
                 .contents = "abcdefghijklmnopqrstuvwx",
                 .contents_len = 24,
             }, {
+                .filename = "mydir",
+                .is_dir = 1,
+                .children = (struct nffs_test_file_desc[]) { {
+                    .filename = "gaga.txt",
+                    .contents =
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    "01234567890123456789012345678901234567890123456789"
+    ,
+                    .contents_len = 1000,
+                }, {
+                    .filename = NULL,
+                } },
+            }, {
                 .filename = NULL,
             } },
     } };
@@ -2491,6 +2567,9 @@ TEST_SUITE(gen_32_1024)
 int
 nffs_test_all(void)
 {
+    nffs_config.nc_num_inodes = 1024 * 8;
+    nffs_config.nc_num_blocks = 1024 * 20;
+
     gen_1_1();
     gen_4_32();
     gen_32_1024();


[50/50] [abbrv] incubator-mynewt-core git commit: MYNEWT-85: Fix BLE timing for start of connection events. MYNEWT-283: Slave anchor point now set correctly on CRC error.

Posted by ma...@apache.org.
MYNEWT-85: Fix BLE timing for start of connection events.
MYNEWT-283: Slave anchor point now set correctly on CRC error.

Please read the respective tickets for a discussion of
the changes.


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

Branch: refs/heads/master
Commit: 8ddc20eed045e5d9d0abe6b0bd5d6af83f872dcf
Parents: f04731b
Author: William San Filippo <wi...@runtime.io>
Authored: Wed Apr 27 16:45:17 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Wed Apr 27 16:46:54 2016 -0700

----------------------------------------------------------------------
 apps/bletest/src/main.c                         |  39 +-
 hw/mcu/nordic/nrf51xxx/src/hal_cputime.c        | 225 +++++-----
 hw/mcu/nordic/nrf52xxx/src/hal_cputime.c        | 224 +++++-----
 .../controller/include/controller/ble_ll.h      |   5 +
 .../controller/include/controller/ble_phy.h     |  21 +-
 net/nimble/controller/pkg.yml                   |   1 +
 net/nimble/controller/src/ble_ll.c              |   2 +-
 net/nimble/controller/src/ble_ll_adv.c          |  34 +-
 net/nimble/controller/src/ble_ll_conn.c         |  86 ++--
 net/nimble/controller/src/ble_ll_scan.c         |   3 +-
 net/nimble/controller/src/ble_ll_sched.c        |   1 +
 net/nimble/drivers/native/src/ble_phy.c         |   2 +-
 net/nimble/drivers/nrf51/include/ble/xcvr.h     |  32 ++
 net/nimble/drivers/nrf51/src/ble_phy.c          | 419 ++++++++++--------
 net/nimble/drivers/nrf52/include/ble/xcvr.h     |  32 ++
 net/nimble/drivers/nrf52/src/ble_phy.c          | 423 +++++++++++--------
 net/nimble/include/nimble/ble.h                 |   2 +-
 17 files changed, 882 insertions(+), 669 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/apps/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c
index 9510641..7218fd1 100755
--- a/apps/bletest/src/main.c
+++ b/apps/bletest/src/main.c
@@ -356,27 +356,30 @@ bletest_init_scanner(void)
 {
     int rc;
     uint8_t dev_addr[BLE_DEV_ADDR_LEN];
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_PARAM_LEN];
     uint8_t filter_policy;
 
-    /* Set scanning parameters */
-    rc = bletest_hci_le_set_scan_params(BLETEST_CFG_SCAN_TYPE,
-                                        BLETEST_CFG_SCAN_ITVL,
-                                        BLETEST_CFG_SCAN_WINDOW,
-                                        BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-                                        BLETEST_CFG_SCAN_FILT_POLICY);
+    rc = host_hci_cmd_build_le_set_scan_params(BLETEST_CFG_SCAN_TYPE,
+                                               BLETEST_CFG_SCAN_ITVL,
+                                               BLETEST_CFG_SCAN_WINDOW,
+                                               BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+                                               BLETEST_CFG_SCAN_FILT_POLICY,
+                                               buf, sizeof buf);
     assert(rc == 0);
-
-    filter_policy = BLETEST_CFG_SCAN_FILT_POLICY;
-    if (filter_policy & 1) {
-        /* Add some whitelist addresses */
-        dev_addr[0] = 0x00;
-        dev_addr[1] = 0x00;
-        dev_addr[2] = 0x00;
-        dev_addr[3] = 0x88;
-        dev_addr[4] = 0x88;
-        dev_addr[5] = 0x08;
-        rc = bletest_hci_le_add_to_whitelist(dev_addr, BLE_ADDR_TYPE_PUBLIC);
-        assert(rc == 0);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
+    if (rc == 0) {
+        filter_policy = BLETEST_CFG_SCAN_FILT_POLICY;
+        if (filter_policy & 1) {
+            /* Add some whitelist addresses */
+            dev_addr[0] = 0x00;
+            dev_addr[1] = 0x00;
+            dev_addr[2] = 0x00;
+            dev_addr[3] = 0x88;
+            dev_addr[4] = 0x88;
+            dev_addr[5] = 0x08;
+            rc = bletest_hci_le_add_to_whitelist(dev_addr, BLE_ADDR_TYPE_PUBLIC);
+            assert(rc == 0);
+        }
     }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c b/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c
index 2f1c4fa..eb12237 100644
--- a/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c
+++ b/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c
@@ -6,7 +6,7 @@
  * 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,
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 #include <string.h>
 #include <stdint.h>
 #include <assert.h>
@@ -28,18 +29,15 @@
 /* Maximum timer frequency */
 #define NRF51_MAX_TIMER_FREQ    (16000000)
 
-/* 
- * Use these defines to select a timer and the compare channels. The reason
- * channel 2 is left open for TIMER0 is that there are pre-programmed PPI
- * channels that use timer 0 channel 2 for certain events. For example, the
- * radio has RADIO->EVENTS_END tied to capture channel 2. This can be
- * used to capture rx/tx end times.
- */
+#undef HAL_CPUTIME_USE_OVERFLOW
 
+/* The RF peripheral uses CC registers 0 and 1 for RF events. */
 #define CPUTIMER                NRF_TIMER0
 #define CPUTIMER_IRQ            (TIMER0_IRQn)
-#define CPUTIMER_CC_CNTR        (0)
-#define CPUTIMER_CC_OVERFLOW    (1)
+#define CPUTIMER_CC_CNTR        (2)
+#ifdef HAL_CPUTIME_USE_OVERFLOW
+#define CPUTIMER_CC_OVERFLOW    (2)
+#endif
 #define CPUTIMER_CC_INT         (3)
 
 /* Interrupt mask for interrupt enable/clear */
@@ -73,12 +71,12 @@ cputime_disable_ocmp(void)
 }
 
 /**
- * cputime set ocmp 
- *  
- * Set the OCMP used by the cputime module to the desired cputime. 
- *  
- * NOTE: Must be called with interrupts disabled. 
- * 
+ * cputime set ocmp
+ *
+ * Set the OCMP used by the cputime module to the desired cputime.
+ *
+ * NOTE: Must be called with interrupts disabled.
+ *
  * @param timer Pointer to timer.
  */
 static void
@@ -103,12 +101,12 @@ cputime_set_ocmp(struct cpu_timer *timer)
 }
 
 /**
- * cputime chk expiration 
- *  
- * Iterates through the cputimer queue to determine if any timers have expired. 
- * If the timer has expired the timer is removed from the queue and the timer 
- * callback function is executed. 
- * 
+ * cputime chk expiration
+ *
+ * Iterates through the cputimer queue to determine if any timers have expired.
+ * If the timer has expired the timer is removed from the queue and the timer
+ * callback function is executed.
+ *
  */
 static void
 cputime_chk_expiration(void)
@@ -138,37 +136,38 @@ cputime_chk_expiration(void)
 }
 
 /**
- * cputime isr 
- *  
- * This is the global timer interrupt routine. 
- * 
+ * cputime isr
+ *
+ * This is the global timer interrupt routine.
+ *
  */
 static void
 cputime_isr(void)
 {
     uint32_t compare;
+#ifdef HAL_CPUTIME_USE_OVERFLOW
     uint32_t overflow;
+#endif
 
     /* Check interrupt source. If set, clear them */
     compare = CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_INT];
     if (compare) {
         CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_INT] = 0;
     }
+
+#ifdef HAL_CPUTIME_USE_OVERFLOW
     overflow = CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW];
     if (overflow) {
         CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW] = 0;
+        ++g_cputime.uif_ints;
+        ++g_cputime.cputime_high;
     }
+#endif
 
     /* Count # of interrupts */
     ++g_cputime.timer_isrs;
 
-    /* If overflow, increment high word of cpu time */
-    if (overflow) {
-        ++g_cputime.uif_ints;
-        ++g_cputime.cputime_high;
-    }
-
-    /* 
+    /*
      * NOTE: we dont check the 'compare' variable here due to how the timer
      * is implemented on this chip. There is no way to force an output
      * compare, so if we are late setting the output compare (i.e. the timer
@@ -187,14 +186,14 @@ cputime_isr(void)
 }
 
 /**
- * cputime init 
- *  
- * Initialize the cputime module. This must be called after os_init is called 
- * and before any other timer API are used. This should be called only once 
- * and should be called before the hardware timer is used. 
- * 
+ * cputime init
+ *
+ * Initialize the cputime module. This must be called after os_init is called
+ * and before any other timer API are used. This should be called only once
+ * and should be called before the hardware timer is used.
+ *
  * @param clock_freq The desired cputime frequency, in hertz (Hz).
- * 
+ *
  * @return int 0 on success; -1 on error.
  */
 int
@@ -221,7 +220,7 @@ cputime_init(uint32_t clock_freq)
         return -1;
     }
 
-    /* 
+    /*
      * Pre-scaler is 4 bits and is a 2^n, so the only possible values that
      * work are 1, 2, 4, 8 and 16, which gives a valid pre-scaler of 0, 1, 2,
      * 3 or 4.
@@ -276,9 +275,11 @@ cputime_init(uint32_t clock_freq)
     CPUTIMER->TASKS_START = 1;
 
     /*  Use an output compare to generate an overflow */
+#ifdef HAL_CPUTIME_USE_OVERFLOW
     CPUTIMER->CC[CPUTIMER_CC_OVERFLOW] = 0;
     CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW] = 0;
     CPUTIMER->INTENSET = CPUTIMER_INT_MASK(CPUTIMER_CC_OVERFLOW);
+#endif
 
     /* Set isr in vector table and enable interrupt */
     NVIC_SetVector(CPUTIMER_IRQ, (uint32_t)cputime_isr);
@@ -291,12 +292,13 @@ cputime_init(uint32_t clock_freq)
 
 /**
  * cputime get64
- *  
- * Returns cputime as a 64-bit number. 
- * 
+ *
+ * Returns cputime as a 64-bit number.
+ *
  * @return uint64_t The 64-bit representation of cputime.
  */
-uint64_t 
+#ifdef HAL_CPUTIME_USE_OVERFLOW
+uint64_t
 cputime_get64(void)
 {
     uint32_t ctx;
@@ -317,12 +319,13 @@ cputime_get64(void)
 
     return cpu_time;
 }
+#endif
 
 /**
- * cputime get32 
- *  
- * Returns the low 32 bits of cputime. 
- * 
+ * cputime get32
+ *
+ * Returns the low 32 bits of cputime.
+ *
  * @return uint32_t The lower 32 bits of cputime
  */
 uint32_t
@@ -338,15 +341,15 @@ cputime_get32(void)
 }
 
 /**
- * cputime nsecs to ticks 
- *  
- * Converts the given number of nanoseconds into cputime ticks. 
- * 
+ * cputime nsecs to ticks
+ *
+ * Converts the given number of nanoseconds into cputime ticks.
+ *
  * @param usecs The number of nanoseconds to convert to ticks
- * 
+ *
  * @return uint32_t The number of ticks corresponding to 'nsecs'
  */
-uint32_t 
+uint32_t
 cputime_nsecs_to_ticks(uint32_t nsecs)
 {
     uint32_t ticks;
@@ -357,34 +360,34 @@ cputime_nsecs_to_ticks(uint32_t nsecs)
 
 /**
  * cputime ticks to nsecs
- *  
- * Convert the given number of ticks into nanoseconds. 
- * 
+ *
+ * Convert the given number of ticks into nanoseconds.
+ *
  * @param ticks The number of ticks to convert to nanoseconds.
- * 
+ *
  * @return uint32_t The number of nanoseconds corresponding to 'ticks'
  */
-uint32_t 
+uint32_t
 cputime_ticks_to_nsecs(uint32_t ticks)
 {
     uint32_t nsecs;
 
-    nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) / 
+    nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) /
             g_cputime.ticks_per_usec;
 
     return nsecs;
 }
 
 /**
- * cputime usecs to ticks 
- *  
- * Converts the given number of microseconds into cputime ticks. 
- * 
+ * cputime usecs to ticks
+ *
+ * Converts the given number of microseconds into cputime ticks.
+ *
  * @param usecs The number of microseconds to convert to ticks
- * 
+ *
  * @return uint32_t The number of ticks corresponding to 'usecs'
  */
-uint32_t 
+uint32_t
 cputime_usecs_to_ticks(uint32_t usecs)
 {
     uint32_t ticks;
@@ -395,14 +398,14 @@ cputime_usecs_to_ticks(uint32_t usecs)
 
 /**
  * cputime ticks to usecs
- *  
- * Convert the given number of ticks into microseconds. 
- * 
+ *
+ * Convert the given number of ticks into microseconds.
+ *
  * @param ticks The number of ticks to convert to microseconds.
- * 
+ *
  * @return uint32_t The number of microseconds corresponding to 'ticks'
  */
-uint32_t 
+uint32_t
 cputime_ticks_to_usecs(uint32_t ticks)
 {
     uint32_t us;
@@ -413,12 +416,12 @@ cputime_ticks_to_usecs(uint32_t ticks)
 
 /**
  * cputime delay ticks
- *  
- * Wait until the number of ticks has elapsed. This is a blocking delay. 
- * 
+ *
+ * Wait until the number of ticks has elapsed. This is a blocking delay.
+ *
  * @param ticks The number of ticks to wait.
  */
-void 
+void
 cputime_delay_ticks(uint32_t ticks)
 {
     uint32_t until;
@@ -430,13 +433,13 @@ cputime_delay_ticks(uint32_t ticks)
 }
 
 /**
- * cputime delay nsecs 
- *  
- * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay. 
- *  
+ * cputime delay nsecs
+ *
+ * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay.
+ *
  * @param nsecs The number of nanoseconds to wait.
  */
-void 
+void
 cputime_delay_nsecs(uint32_t nsecs)
 {
     uint32_t ticks;
@@ -446,13 +449,13 @@ cputime_delay_nsecs(uint32_t nsecs)
 }
 
 /**
- * cputime delay usecs 
- *  
- * Wait until 'usecs' microseconds has elapsed. This is a blocking delay. 
- *  
+ * cputime delay usecs
+ *
+ * Wait until 'usecs' microseconds has elapsed. This is a blocking delay.
+ *
  * @param usecs The number of usecs to wait.
  */
-void 
+void
 cputime_delay_usecs(uint32_t usecs)
 {
     uint32_t ticks;
@@ -463,13 +466,13 @@ cputime_delay_usecs(uint32_t usecs)
 
 /**
  * cputime timer init
- * 
- * 
+ *
+ *
  * @param timer The timer to initialize. Cannot be NULL.
  * @param fp    The timer callback function. Cannot be NULL.
- * @param arg   Pointer to data object to pass to timer. 
+ * @param arg   Pointer to data object to pass to timer.
  */
-void 
+void
 cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg)
 {
     assert(timer != NULL);
@@ -481,16 +484,16 @@ cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg)
 }
 
 /**
- * cputime timer start 
- *  
- * Start a cputimer that will expire at 'cputime'. If cputime has already 
- * passed, the timer callback will still be called (at interrupt context). 
- * Cannot be called when the timer has already started. 
- * 
+ * cputime timer start
+ *
+ * Start a cputimer that will expire at 'cputime'. If cputime has already
+ * passed, the timer callback will still be called (at interrupt context).
+ * Cannot be called when the timer has already started.
+ *
  * @param timer     Pointer to timer to start. Cannot be NULL.
  * @param cputime   The cputime at which the timer should expire.
  */
-void 
+void
 cputime_timer_start(struct cpu_timer *timer, uint32_t cputime)
 {
     struct cpu_timer *entry;
@@ -508,7 +511,7 @@ cputime_timer_start(struct cpu_timer *timer, uint32_t cputime)
     } else {
         TAILQ_FOREACH(entry, &g_cputimer_q, link) {
             if ((int32_t)(timer->cputime - entry->cputime) < 0) {
-                TAILQ_INSERT_BEFORE(entry, timer, link);   
+                TAILQ_INSERT_BEFORE(entry, timer, link);
                 break;
             }
         }
@@ -526,15 +529,15 @@ cputime_timer_start(struct cpu_timer *timer, uint32_t cputime)
 }
 
 /**
- * cputimer timer relative 
- *  
- * Sets a cpu timer that will expire 'usecs' microseconds from the current 
- * cputime. 
- * 
+ * cputimer timer relative
+ *
+ * Sets a cpu timer that will expire 'usecs' microseconds from the current
+ * cputime.
+ *
  * @param timer Pointer to timer. Cannot be NULL.
  * @param usecs The number of usecs from now at which the timer will expire.
  */
-void 
+void
 cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs)
 {
     uint32_t cputime;
@@ -546,15 +549,15 @@ cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs)
 }
 
 /**
- * cputime timer stop 
- *  
- * Stops a cputimer from running. The timer is removed from the timer queue 
- * and interrupts are disabled if no timers are left on the queue. Can be 
- * called even if timer is not running. 
- * 
+ * cputime timer stop
+ *
+ * Stops a cputimer from running. The timer is removed from the timer queue
+ * and interrupts are disabled if no timers are left on the queue. Can be
+ * called even if timer is not running.
+ *
  * @param timer Pointer to cputimer to stop. Cannot be NULL.
  */
-void 
+void
 cputime_timer_stop(struct cpu_timer *timer)
 {
     int reset_ocmp;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c b/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c
index 134a601..fbcc96d 100644
--- a/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_cputime.c
@@ -6,7 +6,7 @@
  * 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,
@@ -29,18 +29,15 @@
 /* Maximum timer frequency */
 #define NRF52_MAX_TIMER_FREQ    (16000000)
 
-/* 
- * Use these defines to select a timer and the compare channels. The reason
- * channel 2 is left open for TIMER0 is that there are pre-programmed PPI
- * channels that use timer 0 channel 2 for certain events. For example, the
- * radio has RADIO->EVENTS_END tied to capture channel 2. This can be
- * used to capture rx/tx end times.
- */
+#undef HAL_CPUTIME_USE_OVERFLOW
 
+/* The RF peripheral uses CC registers 0 and 1 for RF events. */
 #define CPUTIMER                NRF_TIMER0
 #define CPUTIMER_IRQ            (TIMER0_IRQn)
-#define CPUTIMER_CC_CNTR        (0)
-#define CPUTIMER_CC_OVERFLOW    (1)
+#define CPUTIMER_CC_CNTR        (2)
+#ifdef HAL_CPUTIME_USE_OVERFLOW
+#define CPUTIMER_CC_OVERFLOW    (2)
+#endif
 #define CPUTIMER_CC_INT         (3)
 
 /* Interrupt mask for interrupt enable/clear */
@@ -74,12 +71,12 @@ cputime_disable_ocmp(void)
 }
 
 /**
- * cputime set ocmp 
- *  
- * Set the OCMP used by the cputime module to the desired cputime. 
- *  
- * NOTE: Must be called with interrupts disabled. 
- * 
+ * cputime set ocmp
+ *
+ * Set the OCMP used by the cputime module to the desired cputime.
+ *
+ * NOTE: Must be called with interrupts disabled.
+ *
  * @param timer Pointer to timer.
  */
 static void
@@ -104,12 +101,12 @@ cputime_set_ocmp(struct cpu_timer *timer)
 }
 
 /**
- * cputime chk expiration 
- *  
- * Iterates through the cputimer queue to determine if any timers have expired. 
- * If the timer has expired the timer is removed from the queue and the timer 
- * callback function is executed. 
- * 
+ * cputime chk expiration
+ *
+ * Iterates through the cputimer queue to determine if any timers have expired.
+ * If the timer has expired the timer is removed from the queue and the timer
+ * callback function is executed.
+ *
  */
 static void
 cputime_chk_expiration(void)
@@ -139,37 +136,38 @@ cputime_chk_expiration(void)
 }
 
 /**
- * cputime isr 
- *  
- * This is the global timer interrupt routine. 
- * 
+ * cputime isr
+ *
+ * This is the global timer interrupt routine.
+ *
  */
 static void
 cputime_isr(void)
 {
     uint32_t compare;
+#ifdef HAL_CPUTIME_USE_OVERFLOW
     uint32_t overflow;
+#endif
 
     /* Check interrupt source. If set, clear them */
     compare = CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_INT];
     if (compare) {
         CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_INT] = 0;
     }
+
+#ifdef HAL_CPUTIME_USE_OVERFLOW
     overflow = CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW];
     if (overflow) {
         CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW] = 0;
+        ++g_cputime.uif_ints;
+        ++g_cputime.cputime_high;
     }
+#endif
 
     /* Count # of interrupts */
     ++g_cputime.timer_isrs;
 
-    /* If overflow, increment high word of cpu time */
-    if (overflow) {
-        ++g_cputime.uif_ints;
-        ++g_cputime.cputime_high;
-    }
-
-    /* 
+    /*
      * NOTE: we dont check the 'compare' variable here due to how the timer
      * is implemented on this chip. There is no way to force an output
      * compare, so if we are late setting the output compare (i.e. the timer
@@ -188,14 +186,14 @@ cputime_isr(void)
 }
 
 /**
- * cputime init 
- *  
- * Initialize the cputime module. This must be called after os_init is called 
- * and before any other timer API are used. This should be called only once 
- * and should be called before the hardware timer is used. 
- * 
+ * cputime init
+ *
+ * Initialize the cputime module. This must be called after os_init is called
+ * and before any other timer API are used. This should be called only once
+ * and should be called before the hardware timer is used.
+ *
  * @param clock_freq The desired cputime frequency, in hertz (Hz).
- * 
+ *
  * @return int 0 on success; -1 on error.
  */
 int
@@ -222,7 +220,7 @@ cputime_init(uint32_t clock_freq)
         return -1;
     }
 
-    /* 
+    /*
      * Pre-scaler is 4 bits and is a 2^n, so the only possible values that
      * work are 1, 2, 4, 8 and 16, which gives a valid pre-scaler of 0, 1, 2,
      * 3 or 4.
@@ -277,9 +275,11 @@ cputime_init(uint32_t clock_freq)
     CPUTIMER->TASKS_START = 1;
 
     /*  Use an output compare to generate an overflow */
+#ifdef HAL_CPUTIME_USE_OVERFLOW
     CPUTIMER->CC[CPUTIMER_CC_OVERFLOW] = 0;
     CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW] = 0;
     CPUTIMER->INTENSET = CPUTIMER_INT_MASK(CPUTIMER_CC_OVERFLOW);
+#endif
 
     /* Set isr in vector table and enable interrupt */
     NVIC_SetVector(CPUTIMER_IRQ, (uint32_t)cputime_isr);
@@ -292,12 +292,13 @@ cputime_init(uint32_t clock_freq)
 
 /**
  * cputime get64
- *  
- * Returns cputime as a 64-bit number. 
- * 
+ *
+ * Returns cputime as a 64-bit number.
+ *
  * @return uint64_t The 64-bit representation of cputime.
  */
-uint64_t 
+#ifdef HAL_CPUTIME_USE_OVERFLOW
+uint64_t
 cputime_get64(void)
 {
     uint32_t ctx;
@@ -318,12 +319,13 @@ cputime_get64(void)
 
     return cpu_time;
 }
+#endif
 
 /**
- * cputime get32 
- *  
- * Returns the low 32 bits of cputime. 
- * 
+ * cputime get32
+ *
+ * Returns the low 32 bits of cputime.
+ *
  * @return uint32_t The lower 32 bits of cputime
  */
 uint32_t
@@ -339,15 +341,15 @@ cputime_get32(void)
 }
 
 /**
- * cputime nsecs to ticks 
- *  
- * Converts the given number of nanoseconds into cputime ticks. 
- * 
+ * cputime nsecs to ticks
+ *
+ * Converts the given number of nanoseconds into cputime ticks.
+ *
  * @param usecs The number of nanoseconds to convert to ticks
- * 
+ *
  * @return uint32_t The number of ticks corresponding to 'nsecs'
  */
-uint32_t 
+uint32_t
 cputime_nsecs_to_ticks(uint32_t nsecs)
 {
     uint32_t ticks;
@@ -358,34 +360,34 @@ cputime_nsecs_to_ticks(uint32_t nsecs)
 
 /**
  * cputime ticks to nsecs
- *  
- * Convert the given number of ticks into nanoseconds. 
- * 
+ *
+ * Convert the given number of ticks into nanoseconds.
+ *
  * @param ticks The number of ticks to convert to nanoseconds.
- * 
+ *
  * @return uint32_t The number of nanoseconds corresponding to 'ticks'
  */
-uint32_t 
+uint32_t
 cputime_ticks_to_nsecs(uint32_t ticks)
 {
     uint32_t nsecs;
 
-    nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) / 
+    nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) /
             g_cputime.ticks_per_usec;
 
     return nsecs;
 }
 
 /**
- * cputime usecs to ticks 
- *  
- * Converts the given number of microseconds into cputime ticks. 
- * 
+ * cputime usecs to ticks
+ *
+ * Converts the given number of microseconds into cputime ticks.
+ *
  * @param usecs The number of microseconds to convert to ticks
- * 
+ *
  * @return uint32_t The number of ticks corresponding to 'usecs'
  */
-uint32_t 
+uint32_t
 cputime_usecs_to_ticks(uint32_t usecs)
 {
     uint32_t ticks;
@@ -396,14 +398,14 @@ cputime_usecs_to_ticks(uint32_t usecs)
 
 /**
  * cputime ticks to usecs
- *  
- * Convert the given number of ticks into microseconds. 
- * 
+ *
+ * Convert the given number of ticks into microseconds.
+ *
  * @param ticks The number of ticks to convert to microseconds.
- * 
+ *
  * @return uint32_t The number of microseconds corresponding to 'ticks'
  */
-uint32_t 
+uint32_t
 cputime_ticks_to_usecs(uint32_t ticks)
 {
     uint32_t us;
@@ -414,12 +416,12 @@ cputime_ticks_to_usecs(uint32_t ticks)
 
 /**
  * cputime delay ticks
- *  
- * Wait until the number of ticks has elapsed. This is a blocking delay. 
- * 
+ *
+ * Wait until the number of ticks has elapsed. This is a blocking delay.
+ *
  * @param ticks The number of ticks to wait.
  */
-void 
+void
 cputime_delay_ticks(uint32_t ticks)
 {
     uint32_t until;
@@ -431,13 +433,13 @@ cputime_delay_ticks(uint32_t ticks)
 }
 
 /**
- * cputime delay nsecs 
- *  
- * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay. 
- *  
+ * cputime delay nsecs
+ *
+ * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay.
+ *
  * @param nsecs The number of nanoseconds to wait.
  */
-void 
+void
 cputime_delay_nsecs(uint32_t nsecs)
 {
     uint32_t ticks;
@@ -447,13 +449,13 @@ cputime_delay_nsecs(uint32_t nsecs)
 }
 
 /**
- * cputime delay usecs 
- *  
- * Wait until 'usecs' microseconds has elapsed. This is a blocking delay. 
- *  
+ * cputime delay usecs
+ *
+ * Wait until 'usecs' microseconds has elapsed. This is a blocking delay.
+ *
  * @param usecs The number of usecs to wait.
  */
-void 
+void
 cputime_delay_usecs(uint32_t usecs)
 {
     uint32_t ticks;
@@ -464,13 +466,13 @@ cputime_delay_usecs(uint32_t usecs)
 
 /**
  * cputime timer init
- * 
- * 
+ *
+ *
  * @param timer The timer to initialize. Cannot be NULL.
  * @param fp    The timer callback function. Cannot be NULL.
- * @param arg   Pointer to data object to pass to timer. 
+ * @param arg   Pointer to data object to pass to timer.
  */
-void 
+void
 cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg)
 {
     assert(timer != NULL);
@@ -482,16 +484,16 @@ cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg)
 }
 
 /**
- * cputime timer start 
- *  
- * Start a cputimer that will expire at 'cputime'. If cputime has already 
- * passed, the timer callback will still be called (at interrupt context). 
- * Cannot be called when the timer has already started. 
- * 
+ * cputime timer start
+ *
+ * Start a cputimer that will expire at 'cputime'. If cputime has already
+ * passed, the timer callback will still be called (at interrupt context).
+ * Cannot be called when the timer has already started.
+ *
  * @param timer     Pointer to timer to start. Cannot be NULL.
  * @param cputime   The cputime at which the timer should expire.
  */
-void 
+void
 cputime_timer_start(struct cpu_timer *timer, uint32_t cputime)
 {
     struct cpu_timer *entry;
@@ -509,7 +511,7 @@ cputime_timer_start(struct cpu_timer *timer, uint32_t cputime)
     } else {
         TAILQ_FOREACH(entry, &g_cputimer_q, link) {
             if ((int32_t)(timer->cputime - entry->cputime) < 0) {
-                TAILQ_INSERT_BEFORE(entry, timer, link);   
+                TAILQ_INSERT_BEFORE(entry, timer, link);
                 break;
             }
         }
@@ -527,15 +529,15 @@ cputime_timer_start(struct cpu_timer *timer, uint32_t cputime)
 }
 
 /**
- * cputimer timer relative 
- *  
- * Sets a cpu timer that will expire 'usecs' microseconds from the current 
- * cputime. 
- * 
+ * cputimer timer relative
+ *
+ * Sets a cpu timer that will expire 'usecs' microseconds from the current
+ * cputime.
+ *
  * @param timer Pointer to timer. Cannot be NULL.
  * @param usecs The number of usecs from now at which the timer will expire.
  */
-void 
+void
 cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs)
 {
     uint32_t cputime;
@@ -547,15 +549,15 @@ cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs)
 }
 
 /**
- * cputime timer stop 
- *  
- * Stops a cputimer from running. The timer is removed from the timer queue 
- * and interrupts are disabled if no timers are left on the queue. Can be 
- * called even if timer is not running. 
- * 
+ * cputime timer stop
+ *
+ * Stops a cputimer from running. The timer is removed from the timer queue
+ * and interrupts are disabled if no timers are left on the queue. Can be
+ * called even if timer is not running.
+ *
  * @param timer Pointer to cputimer to stop. Cannot be NULL.
  */
-void 
+void
 cputime_timer_stop(struct cpu_timer *timer)
 {
     int reset_ocmp;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/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 60a8408..e579a26 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -201,6 +201,9 @@ struct ble_dev_addr
  */
 #define BLE_TX_DUR_USECS_M(len)     (((len) + BLE_LL_PDU_OVERHEAD) << 3)
 
+/* Calculates the time it takes to transmit 'len' bytes */
+#define BLE_TX_LEN_USECS_M(len)     ((len) << 3)
+
 /* Access address for advertising channels */
 #define BLE_ACCESS_ADDR_ADV             (0x8E89BED6)
 
@@ -373,6 +376,8 @@ int ble_ll_rand_start(void);
 #define BLE_LL_LOG_ID_RX_END            (3)
 #define BLE_LL_LOG_ID_WFR_EXP           (4)
 #define BLE_LL_LOG_ID_PHY_TXEND         (5)
+#define BLE_LL_LOG_ID_PHY_TX            (6)
+#define BLE_LL_LOG_ID_PHY_RX            (7)
 #define BLE_LL_LOG_ID_PHY_DISABLE       (9)
 #define BLE_LL_LOG_ID_CONN_EV_START     (10)
 #define BLE_LL_LOG_ID_CONN_TX           (15)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/net/nimble/controller/include/controller/ble_phy.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_phy.h b/net/nimble/controller/include/controller/ble_phy.h
index 88373c2..af31dbd 100644
--- a/net/nimble/controller/include/controller/ble_phy.h
+++ b/net/nimble/controller/include/controller/ble_phy.h
@@ -23,18 +23,6 @@
 /* Forward declarations */
 struct os_mbuf;
 
-/*
- * XXX: Transceiver definitions. These dont belong here and will be moved
- * once we finalize transceiver specific support.
- */
-#define XCVR_RX_START_DELAY_USECS     (140)
-#define XCVR_TX_START_DELAY_USECS     (140)
-#define XCVR_PROC_DELAY_USECS         (50)
-#define XCVR_TX_SCHED_DELAY_USECS     \
-    (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
-#define XCVR_RX_SCHED_DELAY_USECS     \
-    (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
-
 /* Channel/Frequency defintions */
 #define BLE_PHY_NUM_CHANS           (40)
 #define BLE_PHY_NUM_DATA_CHANS      (37)
@@ -77,6 +65,7 @@ struct os_mbuf;
 #define BLE_PHY_ERR_INIT            (2)
 #define BLE_PHY_ERR_INV_PARAM       (3)
 #define BLE_PHY_ERR_NO_BUFS         (4)
+#define BLE_PHY_ERR_TX_LATE         (5)
 
 /* Maximun PDU length. Includes LL header of 2 bytes and 255 bytes payload. */
 #define BLE_PHY_MAX_PDU_LEN         (257)
@@ -93,11 +82,17 @@ int ble_phy_reset(void);
 /* Set the PHY channel */
 int ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit);
 
+/* Set transmit start time */
+int ble_phy_tx_set_start_time(uint32_t cputime);
+
+/* Set receive start time */
+int ble_phy_rx_set_start_time(uint32_t cputime);
+
 /* Set the transmit end callback and argument */
 void ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg);
 
 /* Place the PHY into transmit mode */
-int ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans);
+int ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans);
 
 /* Place the PHY into receive mode */
 int ble_phy_rx(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/net/nimble/controller/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/controller/pkg.yml b/net/nimble/controller/pkg.yml
index f9c3eae..07a9d56 100644
--- a/net/nimble/controller/pkg.yml
+++ b/net/nimble/controller/pkg.yml
@@ -25,6 +25,7 @@ pkg.keywords:
     - ble
     - bluetooth
 
+pkg.req_apis: ble_driver
 pkg.deps:
     - libs/os
     - sys/stats

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/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 003d594..a5ba967 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -737,7 +737,7 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *ble_hdr)
 
     ble_ll_log(BLE_LL_LOG_ID_RX_END, rxbuf[0],
                ((uint16_t)ble_hdr->rxinfo.flags << 8) | rxbuf[1],
-               (BLE_MBUF_HDR_PTR(rxpdu))->end_cputime);
+               (BLE_MBUF_HDR_PTR(rxpdu))->beg_cputime);
 
     /* Check channel type */
     if (chan < BLE_PHY_NUM_DATA_CHANS) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/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 d6a208a..4d45f16 100644
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -21,6 +21,7 @@
 #include <assert.h>
 #include "os/os.h"
 #include "bsp/bsp.h"
+#include "ble/xcvr.h"
 #include "nimble/ble.h"
 #include "nimble/nimble_opt.h"
 #include "nimble/hci_common.h"
@@ -343,7 +344,7 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
 {
     int rc;
     uint8_t end_trans;
-    uint32_t start_time;
+    uint32_t txstart;
     struct ble_ll_adv_sm *advsm;
 
     /* Get the state machine for the event */
@@ -353,6 +354,15 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
     rc = ble_phy_setchan(advsm->adv_chan, 0, 0);
     assert(rc == 0);
 
+    /* Set transmit start time. */
+    txstart = sch->start_time + XCVR_PROC_DELAY_USECS;
+    rc = ble_phy_tx_set_start_time(txstart);
+    if (rc) {
+        STATS_INC(ble_ll_stats, adv_late_starts);
+        ble_ll_adv_tx_done(advsm);
+        return BLE_LL_SCHED_STATE_DONE;
+    }
+
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
     ble_phy_encrypt_disable();
 #endif
@@ -366,23 +376,12 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
         ble_phy_set_txend_cb(NULL, NULL);
     }
 
-    /* This is for debug */
-    start_time = cputime_get32();
-
-    /* XXX: transmit using an output compare */
     /* Transmit advertisement */
-    rc = ble_phy_tx(advsm->adv_pdu, BLE_PHY_TRANSITION_NONE, end_trans);
+    rc = ble_phy_tx(advsm->adv_pdu, end_trans);
     if (rc) {
-        /* Transmit failed. */
         ble_ll_adv_tx_done(advsm);
         rc =  BLE_LL_SCHED_STATE_DONE;
     } else {
-        /* Check if we were late getting here */
-        if ((int32_t)(start_time - (advsm->adv_pdu_start_time -
-               cputime_usecs_to_ticks(XCVR_TX_START_DELAY_USECS))) > 0) {
-            STATS_INC(ble_ll_stats, adv_late_starts);
-        }
-
         /* Enable/disable whitelisting based on filter policy */
         if (advsm->adv_filter_policy != BLE_HCI_ADV_FILT_NONE) {
             ble_ll_whitelist_enable();
@@ -878,8 +877,7 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu)
     rc = -1;
     if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
         ble_phy_set_txend_cb(ble_ll_adv_tx_done, &g_ble_ll_adv_sm);
-        rc = ble_phy_tx(advsm->scan_rsp_pdu, BLE_PHY_TRANSITION_RX_TX,
-                        BLE_PHY_TRANSITION_NONE);
+        rc = ble_phy_tx(advsm->scan_rsp_pdu, BLE_PHY_TRANSITION_NONE);
         if (!rc) {
             ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_SCAN_RSP_TXD;
             STATS_INC(ble_ll_stats, scan_rsp_txg);
@@ -903,7 +901,9 @@ int
 ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr)
 {
     int valid;
+    uint8_t pyld_len;
     uint8_t *inita;
+    uint32_t endtime;
     struct ble_ll_adv_sm *advsm;
 
     /* Check filter policy. */
@@ -937,7 +937,9 @@ ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr)
 
     if (valid) {
         /* Try to start slave connection. If successful, stop advertising */
-        valid = ble_ll_conn_slave_start(rxbuf, hdr->end_cputime);
+        pyld_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
+        endtime = hdr->beg_cputime + BLE_TX_DUR_USECS_M(pyld_len);
+        valid = ble_ll_conn_slave_start(rxbuf, endtime);
         if (valid) {
             ble_ll_adv_sm_stop(advsm);
         }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/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 05b2c6c..07e7fad 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 "ble/xcvr.h"
 #include "controller/ble_ll.h"
 #include "controller/ble_ll_hci.h"
 #include "controller/ble_ll_scan.h"
@@ -740,7 +741,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm)
  * @return int 0: success; otherwise failure to transmit
  */
 static int
-ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, int beg_transition)
+ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm)
 {
     int rc;
     uint8_t md;
@@ -1049,7 +1050,7 @@ conn_tx_pdu:
 
     /* Set transmit end callback */
     ble_phy_set_txend_cb(txend_func, connsm);
-    rc = ble_phy_tx(m, beg_transition, end_transition);
+    rc = ble_phy_tx(m, end_transition);
     if (!rc) {
         /* Log transmit on connection state */
         cur_txlen = ble_hdr->txinfo.pyld_len;
@@ -1115,21 +1116,28 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
                     connsm->crcinit);
 
     if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
+        /* Set start time of transmission */
+        rc = ble_phy_tx_set_start_time(sch->start_time + XCVR_PROC_DELAY_USECS);
+        if (!rc) {
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-        if (CONN_F_ENCRYPTED(connsm)) {
-            ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr,
-                                   connsm->enc_data.iv,
-                                   connsm->enc_data.enc_block.cipher_text,
-                                   1);
-        } else {
-            ble_phy_encrypt_disable();
-        }
+            if (CONN_F_ENCRYPTED(connsm)) {
+                ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr,
+                                       connsm->enc_data.iv,
+                                       connsm->enc_data.enc_block.cipher_text,
+                                       1);
+            } else {
+                ble_phy_encrypt_disable();
+            }
 #endif
-        rc = ble_ll_conn_tx_data_pdu(connsm, BLE_PHY_TRANSITION_NONE);
-        if (!rc) {
-            rc = BLE_LL_SCHED_STATE_RUNNING;
+            rc = ble_ll_conn_tx_data_pdu(connsm);
+            if (!rc) {
+                rc = BLE_LL_SCHED_STATE_RUNNING;
+            } else {
+                /* Inform LL task of connection event end */
+                rc = BLE_LL_SCHED_STATE_DONE;
+            }
         } else {
-            /* Inform LL task of connection event end */
+            STATS_INC(ble_ll_conn_stats, conn_ev_late);
             rc = BLE_LL_SCHED_STATE_DONE;
         }
     } else {
@@ -1143,6 +1151,10 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
                 ble_phy_encrypt_disable();
             }
 #endif
+        /*
+         * XXX: make sure I dont care that I get here early to start receiving.
+         * I could use events compare and all that shit to start rx.
+         */
         rc = ble_phy_rx();
         if (rc) {
             /* End the connection event as we have no more buffers */
@@ -1938,7 +1950,7 @@ ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva, uint16_t txoffset)
     m = ble_ll_scan_get_pdu();
     ble_ll_conn_req_pdu_update(m, adva, addr_type, txoffset);
     ble_phy_set_txend_cb(ble_ll_conn_req_txend, NULL);
-    rc = ble_phy_tx(m, BLE_PHY_TRANSITION_RX_TX, BLE_PHY_TRANSITION_NONE);
+    rc = ble_phy_tx(m, BLE_PHY_TRANSITION_NONE);
     return rc;
 }
 
@@ -1973,6 +1985,8 @@ void
 ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr)
 {
     uint8_t addr_type;
+    uint8_t payload_len;
+    uint32_t endtime;
     struct ble_ll_conn_sm *connsm;
 
     /* Get the connection state machine we are trying to create */
@@ -2002,7 +2016,9 @@ ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr)
         /* Connection has been created. Stop scanning */
         g_ble_ll_conn_create_sm = NULL;
         ble_ll_scan_sm_stop(0);
-        ble_ll_conn_created(connsm, ble_hdr->end_cputime);
+        payload_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;;
+        endtime = ble_hdr->beg_cputime + BLE_TX_DUR_USECS_M(payload_len);
+        ble_ll_conn_created(connsm, endtime);
     } else {
         ble_ll_scan_chk_resume();
     }
@@ -2030,6 +2046,8 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
     uint8_t *adv_addr;
     uint8_t *init_addr;
     uint8_t *rxbuf;
+    uint8_t pyld_len;
+    uint32_t endtime;
     struct ble_mbuf_hdr *ble_hdr;
 
     /*
@@ -2049,6 +2067,7 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
     /* Only interested in ADV IND or ADV DIRECT IND */
     rxbuf = rxpdu->om_data;
     pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
+    pyld_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
 
     switch (pdu_type) {
     case BLE_ADV_PDU_TYPE_ADV_IND:
@@ -2098,8 +2117,8 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
         }
 
         /* Attempt to schedule new connection. Possible that this might fail */
-        if (!ble_ll_sched_master_new(g_ble_ll_conn_create_sm,
-                                     ble_hdr->end_cputime,
+        endtime = ble_hdr->beg_cputime + BLE_TX_DUR_USECS_M(pyld_len);
+        if (!ble_ll_sched_master_new(g_ble_ll_conn_create_sm, endtime,
                                      NIMBLE_OPT_LL_CONN_INIT_SLOTS)) {
             /* Setup to transmit the connect request */
             rc = ble_ll_conn_request_send(addr_type, adv_addr,
@@ -2339,7 +2358,8 @@ ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu, uint32_t aa)
     uint8_t reply;
     uint8_t rem_bytes;
     uint8_t opcode;
-    uint32_t ticks;
+    uint8_t pyld_len;
+    uint32_t endtime;
     struct os_mbuf *txpdu;
     struct ble_ll_conn_sm *connsm;
     struct ble_mbuf_hdr *rxhdr;
@@ -2365,6 +2385,8 @@ ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu, uint32_t aa)
     /* Set the handle in the ble mbuf header */
     rxhdr = BLE_MBUF_HDR_PTR(rxpdu);
     rxhdr->rxinfo.handle = connsm->conn_handle;
+    hdr_byte = rxpdu->om_data[0];
+    pyld_len = rxpdu->om_data[1];
 
     /*
      * Check the packet CRC. A connection event can continue even if the
@@ -2391,9 +2413,6 @@ ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu, uint32_t aa)
         /* Reset consecutively received bad crcs (since this one was good!) */
         connsm->cons_rxd_bad_crc = 0;
 
-        /* Store received header byte in state machine  */
-        hdr_byte = rxpdu->om_data[0];
-
         /* Check for valid LLID before proceeding. */
         if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == 0) {
             /*
@@ -2534,7 +2553,8 @@ chk_rx_terminate_ind:
 
     /* If reply flag set, send data pdu and continue connection event */
     rc = -1;
-    if (reply && ble_ll_conn_can_send_next_pdu(connsm, rxhdr->end_cputime)) {
+    endtime = rxhdr->beg_cputime + BLE_TX_DUR_USECS_M(pyld_len);
+    if (reply && ble_ll_conn_can_send_next_pdu(connsm, endtime)) {
         /*
          * While this is not perfect, we will just check to see if the
          * terminate timer will expire within two packet times. If it will,
@@ -2544,28 +2564,22 @@ chk_rx_terminate_ind:
          *  XXX: should we just skip this check?
          */
         if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_TERMINATE)) {
-            ticks = BLE_TX_DUR_USECS_M(0) +
-                BLE_TX_DUR_USECS_M(BLE_LL_CTRL_TERMINATE_IND_LEN + 1) +
-                BLE_LL_IFS;
-            ticks = cputime_usecs_to_ticks(ticks) + cputime_get32();
-            if ((int32_t)(connsm->terminate_timeout - ticks) < 0) {
+            endtime = BLE_TX_DUR_USECS_M(BLE_LL_CTRL_TERMINATE_IND_LEN + 1) +
+                      BLE_TX_DUR_USECS_M(0) + BLE_LL_IFS;
+            endtime = cputime_usecs_to_ticks(endtime) + cputime_get32();
+            if ((int32_t)(connsm->terminate_timeout - endtime) < 0) {
                 goto conn_rx_pdu_end;
             }
         }
-        rc = ble_ll_conn_tx_data_pdu(connsm, BLE_PHY_TRANSITION_RX_TX);
+        rc = ble_ll_conn_tx_data_pdu(connsm);
     }
 
 conn_rx_pdu_end:
     /* Set anchor point (and last) if 1st received frame in connection event */
     if (connsm->csmflags.cfbit.slave_set_last_anchor) {
         connsm->csmflags.cfbit.slave_set_last_anchor = 0;
-        /* XXX: For now, we just wont adjust the anchor point on crc error
-           until I fix this issue */
-        if (BLE_MBUF_HDR_CRC_OK(rxhdr)) {
-            connsm->last_anchor_point = rxhdr->end_cputime -
-                cputime_usecs_to_ticks(BLE_TX_DUR_USECS_M(rxpdu->om_data[1]));
-            connsm->anchor_point = connsm->last_anchor_point;
-        }
+        connsm->last_anchor_point = rxhdr->beg_cputime;
+        connsm->anchor_point = connsm->last_anchor_point;
     }
 
     /* Send link layer a connection end event if over */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/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 dbcc63a..94a33e3 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -915,8 +915,7 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
         if (scansm->backoff_count == 0) {
             /* Setup to transmit the scan request */
             ble_ll_scan_req_pdu_make(scansm, adv_addr, addr_type);
-            rc = ble_phy_tx(scansm->scan_req_pdu, BLE_PHY_TRANSITION_RX_TX,
-                            BLE_PHY_TRANSITION_TX_RX);
+            rc = ble_phy_tx(scansm->scan_req_pdu, BLE_PHY_TRANSITION_TX_RX);
 
             /* Set "waiting for scan response" flag */
             scansm->scan_rsp_pending = 1;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/net/nimble/controller/src/ble_ll_sched.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_sched.c b/net/nimble/controller/src/ble_ll_sched.c
index 9b0ccea..82f4189 100644
--- a/net/nimble/controller/src/ble_ll_sched.c
+++ b/net/nimble/controller/src/ble_ll_sched.c
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <string.h>
 #include "os/os.h"
+#include "ble/xcvr.h"
 #include "controller/ble_phy.h"
 #include "controller/ble_ll.h"
 #include "controller/ble_ll_sched.h"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/net/nimble/drivers/native/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/native/src/ble_phy.c b/net/nimble/drivers/native/src/ble_phy.c
index 3cdca69..4b132ca 100644
--- a/net/nimble/drivers/native/src/ble_phy.c
+++ b/net/nimble/drivers/native/src/ble_phy.c
@@ -257,7 +257,7 @@ ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg)
 }
 
 int
-ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
+ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
 {
     int rc;
     uint32_t state;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/net/nimble/drivers/nrf51/include/ble/xcvr.h
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf51/include/ble/xcvr.h b/net/nimble/drivers/nrf51/include/ble/xcvr.h
new file mode 100644
index 0000000..34abd7a
--- /dev/null
+++ b/net/nimble/drivers/nrf51/include/ble/xcvr.h
@@ -0,0 +1,32 @@
+/**
+ * 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_BLE_XCVR_
+#define H_BLE_XCVR_
+
+/* Transceiver specific defintions */
+#define XCVR_RX_START_DELAY_USECS     (140)
+#define XCVR_TX_START_DELAY_USECS     (140)
+#define XCVR_PROC_DELAY_USECS         (100)
+#define XCVR_TX_SCHED_DELAY_USECS     \
+    (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
+#define XCVR_RX_SCHED_DELAY_USECS     \
+    (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
+
+#endif /* H_BLE_XCVR_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/net/nimble/drivers/nrf51/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf51/src/ble_phy.c b/net/nimble/drivers/nrf51/src/ble_phy.c
index d95329a..70a7500 100644
--- a/net/nimble/drivers/nrf51/src/ble_phy.c
+++ b/net/nimble/drivers/nrf51/src/ble_phy.c
@@ -61,6 +61,7 @@
 /* Maximum length of frames */
 #define NRF_MAXLEN              (255)
 #define NRF_BALEN               (3)     /* For base address of 3 bytes */
+#define NRF_RX_START_OFFSET     (5)
 
 /* Maximum tx power */
 #define NRF_TX_PWR_MAX_DBM      (4)
@@ -76,6 +77,7 @@ struct ble_phy_obj
     uint8_t phy_transition;
     uint8_t phy_rx_started;
     uint8_t phy_encrypted;
+    uint8_t phy_tx_pyld_len;
     uint32_t phy_access_address;
     struct os_mbuf *rxpdu;
     void *txend_arg;
@@ -102,6 +104,7 @@ STATS_SECT_START(ble_phy_stats)
     STATS_SECT_ENTRY(rx_aborts)
     STATS_SECT_ENTRY(rx_valid)
     STATS_SECT_ENTRY(rx_crc_err)
+    STATS_SECT_ENTRY(rx_late)
     STATS_SECT_ENTRY(no_bufs)
     STATS_SECT_ENTRY(radio_state_errs)
     STATS_SECT_ENTRY(rx_hw_err)
@@ -119,6 +122,7 @@ STATS_NAME_START(ble_phy_stats)
     STATS_NAME(ble_phy_stats, rx_aborts)
     STATS_NAME(ble_phy_stats, rx_valid)
     STATS_NAME(ble_phy_stats, rx_crc_err)
+    STATS_NAME(ble_phy_stats, rx_late)
     STATS_NAME(ble_phy_stats, no_bufs)
     STATS_NAME(ble_phy_stats, radio_state_errs)
     STATS_NAME(ble_phy_stats, rx_hw_err)
@@ -250,6 +254,9 @@ ble_phy_rx_xcvr_setup(void)
     NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
 #endif
 
+    /* We dont want to trigger TXEN on output compare match */
+    NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
+
     /* Reset the rx started flag. Used for the wait for response */
     g_ble_phy_data.phy_rx_started = 0;
     g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
@@ -285,7 +292,7 @@ ble_phy_tx_end_isr(void)
 
     /* Log the event */
     ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
-               g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[2]);
+               g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[1]);
 
     /* Clear events and clear interrupt on disabled event */
     NRF_RADIO->EVENTS_DISABLED = 0;
@@ -318,14 +325,16 @@ ble_phy_tx_end_isr(void)
         }
 
         /*
-         * Enable the wait for response timer. Note that cc #2 on
-         * timer 0 contains the transmit end time
+         * Enable the wait for response timer. Note that cc #1 on
+         * timer 0 contains the transmit start time
          */
-        wfr_time = NRF_TIMER0->CC[2];
+        wfr_time = NRF_TIMER0->CC[1] - BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
+        wfr_time += BLE_TX_DUR_USECS_M(g_ble_phy_data.phy_tx_pyld_len);
         wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
         ble_ll_wfr_enable(wfr_time);
     } else {
-        /* Better not be going from rx to tx! */
+        /* Disable automatic TXEN */
+        NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
         assert(transition == BLE_PHY_TRANSITION_NONE);
     }
 
@@ -336,152 +345,170 @@ ble_phy_tx_end_isr(void)
 }
 
 static void
-ble_phy_isr(void)
+ble_phy_rx_end_isr(void)
 {
     int rc;
-    uint8_t crcok;
-    uint32_t irq_en;
-    uint32_t state;
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
     uint8_t *dptr;
 #endif
+    uint8_t crcok;
     struct os_mbuf *rxpdu;
     struct ble_mbuf_hdr *ble_hdr;
 
-    /* Read irq register to determine which interrupts are enabled */
-    irq_en = NRF_RADIO->INTENCLR;
-
-    /* Check for disabled event. This only happens for transmits now */
-    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
-        ble_phy_tx_end_isr();
-    }
-
-    /* We get this if we have started to receive a frame */
-    if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) {
-        /* Clear events and clear interrupt */
-        NRF_RADIO->EVENTS_ADDRESS = 0;
-        NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk;
+    /* Clear events and clear interrupt */
+    NRF_RADIO->EVENTS_END = 0;
+    NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk;
 
-        assert(g_ble_phy_data.rxpdu != NULL);
+    /* Disable automatic RXEN */
+    NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
 
-        /* Wait to get 1st byte of frame */
-        while (1) {
-            state = NRF_RADIO->STATE;
-            if (NRF_RADIO->EVENTS_BCMATCH != 0) {
-                break;
+    /* Set RSSI and CRC status flag in header */
+    ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+    assert(NRF_RADIO->EVENTS_RSSIEND != 0);
+    ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+    dptr = g_ble_phy_data.rxpdu->om_data;
+#endif
+    /* Count PHY crc errors and valid packets */
+    crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
+    if (!crcok) {
+        STATS_INC(ble_phy_stats, rx_crc_err);
+    } else {
+        STATS_INC(ble_phy_stats, rx_valid);
+        ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
+#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+        if (g_ble_phy_data.phy_encrypted) {
+            /* Only set MIC failure flag if frame is not zero length */
+            if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
+                ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE;
             }
 
             /*
-             * If state is disabled, we should have the BCMATCH. If not,
-             * something is wrong!
+             * XXX: not sure how to deal with this. This should not
+             * be a MIC failure but we should not hand it up. I guess
+             * this is just some form of rx error and that is how we
+             * handle it? For now, just set CRC error flags
              */
-            if (state == RADIO_STATE_STATE_Disabled) {
-                NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
-                NRF_RADIO->SHORTS = 0;
-                goto phy_isr_exit;
+            if (NRF_CCM->EVENTS_ERROR) {
+                STATS_INC(ble_phy_stats, rx_hw_err);
+                ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
             }
-        }
 
-        /* Initialize flags, channel and state in ble header at rx start */
-        ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
-        ble_hdr->rxinfo.flags = ble_ll_state_get();
-        ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
-        ble_hdr->rxinfo.handle = 0;
-
-        /* Call Link Layer receive start function */
-        rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
-        if (rc >= 0) {
-            /* Set rx started flag and enable rx end ISR */
-            g_ble_phy_data.phy_rx_started = 1;
-            NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
-        } else {
-            /* Disable PHY */
-            ble_phy_disable();
-            irq_en = 0;
-            STATS_INC(ble_phy_stats, rx_aborts);
+            /*
+             * XXX: This is a total hack work-around for now but I dont
+             * know what else to do. If ENDCRYPT is not set and we are
+             * encrypted we need to not trust this frame and drop it.
+             */
+            if (NRF_CCM->EVENTS_ENDCRYPT == 0) {
+                STATS_INC(ble_phy_stats, rx_hw_err);
+                ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
+            }
         }
-
-        /* Count rx starts */
-        STATS_INC(ble_phy_stats, rx_starts);
+#endif
     }
 
-    /* Receive packet end (we dont enable this for transmit) */
-    if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) {
-        /* Clear events and clear interrupt */
-        NRF_RADIO->EVENTS_END = 0;
-        NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk;
-
-        /* Set RSSI and CRC status flag in header */
-        ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
-        assert(NRF_RADIO->EVENTS_RSSIEND != 0);
-        ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
-        ble_hdr->end_cputime = NRF_TIMER0->CC[2];
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-        dptr = g_ble_phy_data.rxpdu->om_data;
-#endif
-        /* Count PHY crc errors and valid packets */
-        crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
-        if (!crcok) {
-            STATS_INC(ble_phy_stats, rx_crc_err);
-        } else {
-            STATS_INC(ble_phy_stats, rx_valid);
-            ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
+    /* Call Link Layer receive payload function */
+    rxpdu = g_ble_phy_data.rxpdu;
+    g_ble_phy_data.rxpdu = NULL;
+
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-            if (g_ble_phy_data.phy_encrypted) {
-                /* Only set MIC failure flag if frame is not zero length */
-                if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
-                    ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE;
-                }
-
-                /*
-                 * XXX: not sure how to deal with this. This should not
-                 * be a MIC failure but we should not hand it up. I guess
-                 * this is just some form of rx error and that is how we
-                 * handle it? For now, just set CRC error flags
-                 */
-                if (NRF_CCM->EVENTS_ERROR) {
-                    STATS_INC(ble_phy_stats, rx_hw_err);
-                    ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
-                }
-
-                /*
-                 * XXX: This is a total hack work-around for now but I dont
-                 * know what else to do. If ENDCRYPT is not set and we are
-                 * encrypted we need to not trust this frame and drop it.
-                 */
-                if (NRF_CCM->EVENTS_ENDCRYPT == 0) {
-                    STATS_INC(ble_phy_stats, rx_hw_err);
-                    ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK;
-                }
-            }
+    if (g_ble_phy_data.phy_encrypted) {
+        /*
+         * XXX: This is a horrible ugly hack to deal with the RAM S1 byte.
+         * This should get fixed as we should not be handing up the header
+         * and length as part of the pdu.
+         */
+        dptr[2] = dptr[1];
+        dptr[1] = dptr[0];
+        rxpdu->om_data += 1;
+    }
 #endif
-        }
+    rc = ble_ll_rx_end(rxpdu, ble_hdr);
+    if (rc < 0) {
+        ble_phy_disable();
+    }
+}
 
-        /* Call Link Layer receive payload function */
-        rxpdu = g_ble_phy_data.rxpdu;
-        g_ble_phy_data.rxpdu = NULL;
+static void
+ble_phy_rx_start_isr(void)
+{
+    int rc;
+    uint32_t state;
+    struct ble_mbuf_hdr *ble_hdr;
 
-#ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
-        if (g_ble_phy_data.phy_encrypted) {
-            /*
-             * XXX: This is a horrible ugly hack to deal with the RAM S1 byte.
-             * This should get fixed as we should not be handing up the header
-             * and length as part of the pdu.
-             */
-            dptr[2] = dptr[1];
-            dptr[1] = dptr[0];
-            rxpdu->om_data += 1;
+    /* Clear events and clear interrupt */
+    NRF_RADIO->EVENTS_ADDRESS = 0;
+    NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk;
+
+    assert(g_ble_phy_data.rxpdu != NULL);
+
+    /* Wait to get 1st byte of frame */
+    while (1) {
+        state = NRF_RADIO->STATE;
+        if (NRF_RADIO->EVENTS_BCMATCH != 0) {
+            break;
         }
-#endif
-        rc = ble_ll_rx_end(rxpdu, ble_hdr);
-        if (rc < 0) {
-            ble_phy_disable();
+
+        /*
+         * If state is disabled, we should have the BCMATCH. If not,
+         * something is wrong!
+         */
+        if (state == RADIO_STATE_STATE_Disabled) {
+            NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
+            NRF_RADIO->SHORTS = 0;
+            return;
         }
     }
 
-phy_isr_exit:
+    /* Initialize flags, channel and state in ble header at rx start */
+    ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+    ble_hdr->rxinfo.flags = ble_ll_state_get();
+    ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
+    ble_hdr->rxinfo.handle = 0;
+    ble_hdr->beg_cputime = NRF_TIMER0->CC[1] -
+        BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
+
+    /* Call Link Layer receive start function */
+    rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
+    if (rc >= 0) {
+        /* Set rx started flag and enable rx end ISR */
+        g_ble_phy_data.phy_rx_started = 1;
+        NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
+    } else {
+        /* Disable PHY */
+        ble_phy_disable();
+        STATS_INC(ble_phy_stats, rx_aborts);
+    }
+
+    /* Count rx starts */
+    STATS_INC(ble_phy_stats, rx_starts);
+}
+
+static void
+ble_phy_isr(void)
+{
+    uint32_t irq_en;
+
+    /* Read irq register to determine which interrupts are enabled */
+    irq_en = NRF_RADIO->INTENCLR;
+
+    /* Check for disabled event. This only happens for transmits now */
+    if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) {
+        ble_phy_tx_end_isr();
+    }
+
+    /* We get this if we have started to receive a frame */
+    if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) {
+        ble_phy_rx_start_isr();
+    }
+
+    /* Receive packet end (we dont enable this for transmit) */
+    if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) {
+        ble_phy_rx_end_isr();
+    }
+
     /* Ensures IRQ is cleared */
-    state = NRF_RADIO->SHORTS;
+    irq_en = NRF_RADIO->SHORTS;
 
     /* Count # of interrupts */
     STATS_INC(ble_phy_stats, phy_isrs);
@@ -546,11 +573,8 @@ ble_phy_init(void)
     /* Configure IFS */
     NRF_RADIO->TIFS = BLE_LL_IFS;
 
-    /*
-     * Enable the pre-programmed PPI to capture the time when a receive
-     * or transmit ends
-     */
-    NRF_PPI->CHENSET = PPI_CHEN_CH27_Msk;
+    /* Captures tx/rx start in timer0 capture 1 */
+    NRF_PPI->CHENSET = PPI_CHEN_CH26_Msk;
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
     NRF_CCM->INTENCLR = 0xffffffff;
@@ -611,8 +635,12 @@ ble_phy_rx(void)
     /* Setup for rx */
     ble_phy_rx_xcvr_setup();
 
-    /* Start the receive task in the radio */
-    NRF_RADIO->TASKS_RXEN = 1;
+    /* Start the receive task in the radio if not automatically going to rx */
+    if ((NRF_PPI->CHEN & PPI_CHEN_CH21_Msk) == 0) {
+        NRF_RADIO->TASKS_RXEN = 1;
+    }
+
+    ble_ll_log(BLE_LL_LOG_ID_PHY_RX, g_ble_phy_data.phy_encrypted, 0, 0);
 
     return 0;
 }
@@ -674,11 +702,76 @@ ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg)
     g_ble_phy_data.txend_arg = arg;
 }
 
+/**
+ * Called to set the start time of a transmission.
+ *
+ * This function is called to set the start time when we are not going from
+ * rx to tx automatically.
+ *
+ * NOTE: care must be taken when calling this function. The channel should
+ * already be set.
+ *
+ * @param cputime
+ *
+ * @return int
+ */
+int
+ble_phy_tx_set_start_time(uint32_t cputime)
+{
+    int rc;
+
+    NRF_TIMER0->CC[0] = cputime;
+    NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk;
+    NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
+    if ((int32_t)(cputime_get32() - cputime) >= 0) {
+        STATS_INC(ble_phy_stats, tx_late);
+        ble_phy_disable();
+        rc =  BLE_PHY_ERR_TX_LATE;
+    } else {
+        rc = 0;
+    }
+    return rc;
+}
+
+/**
+ * Called to set the start time of a reception
+ *
+ * This function acts a bit differently than transmit. If we are late getting
+ * here we will still attempt to receive.
+ *
+ * NOTE: care must be taken when calling this function. The channel should
+ * already be set.
+ *
+ * @param cputime
+ *
+ * @return int
+ */
 int
-ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
+ble_phy_rx_set_start_time(uint32_t cputime)
+{
+    int rc;
+
+    NRF_TIMER0->CC[0] = cputime;
+    NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
+    NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk;
+    if ((int32_t)(cputime_get32() - cputime) >= 0) {
+        STATS_INC(ble_phy_stats, rx_late);
+        NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
+        NRF_RADIO->TASKS_RXEN = 1;
+        rc =  BLE_PHY_ERR_TX_LATE;
+    } else {
+        rc = 0;
+    }
+    return rc;
+}
+
+
+int
+ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
 {
     int rc;
     uint8_t *dptr;
+    uint8_t payload_len;
     uint32_t state;
     uint32_t shortcuts;
     struct ble_mbuf_hdr *ble_hdr;
@@ -686,37 +779,24 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
     /* Better have a pdu! */
     assert(txpdu != NULL);
 
-    /* If radio is not disabled, */
+    /*
+     * This check is to make sure that the radio is not in a state where
+     * it is moving to disabled state. If so, let it get there.
+     */
     nrf_wait_disabled();
 
-    if (beg_trans == BLE_PHY_TRANSITION_RX_TX) {
-        if ((NRF_RADIO->SHORTS & RADIO_SHORTS_DISABLED_TXEN_Msk) == 0) {
-            assert(0);
-        }
-        /* Radio better be in TXRU state or we are in bad shape */
-        state = RADIO_STATE_STATE_TxRu;
-    } else {
-        /* Radio should be in disabled state */
-        state = RADIO_STATE_STATE_Disabled;
-    }
-
-    if (NRF_RADIO->STATE != state) {
-        ble_phy_disable();
-        STATS_INC(ble_phy_stats, radio_state_errs);
-        return BLE_PHY_ERR_RADIO_STATE;
-    }
+    ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
+    payload_len = ble_hdr->txinfo.pyld_len;
 
 #ifdef BLE_LL_CFG_FEAT_LE_ENCRYPTION
     if (g_ble_phy_data.phy_encrypted) {
         /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
-        ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
         dptr = (uint8_t *)&g_ble_phy_enc_buf[0];
         dptr[0] = ble_hdr->txinfo.hdr_byte;
-        dptr[1] = ble_hdr->txinfo.pyld_len;
+        dptr[1] = payload_len;
         dptr[2] = 0;
         dptr += 3;
 
-        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
         NRF_CCM->SHORTS = 1;
         NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
         NRF_CCM->OUTPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
@@ -728,24 +808,19 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
         NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk;
     } else {
         /* RAM representation has S0 and LENGTH fields (2 bytes) */
-        ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
         dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
         dptr[0] = ble_hdr->txinfo.hdr_byte;
-        dptr[1] = ble_hdr->txinfo.pyld_len;
+        dptr[1] = payload_len;
         dptr += 2;
-
-        NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
     }
 #else
     /* RAM representation has S0 and LENGTH fields (2 bytes) */
-    ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
     dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
     dptr[0] = ble_hdr->txinfo.hdr_byte;
-    dptr[1] = ble_hdr->txinfo.pyld_len;
+    dptr[1] = payload_len;
     dptr += 2;
-
-    NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
 #endif
+    NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
 
     /* Clear the ready, end and disabled events */
     NRF_RADIO->EVENTS_READY = 0;
@@ -763,36 +838,26 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
     NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
     NRF_RADIO->SHORTS = shortcuts;
 
-    /* Trigger transmit if our state was disabled */
-    if (state == RADIO_STATE_STATE_Disabled) {
-        NRF_RADIO->TASKS_TXEN = 1;
-    }
+    /* Set transmitted payload length */
+    g_ble_phy_data.phy_tx_pyld_len = payload_len;
 
     /* Set the PHY transition */
     g_ble_phy_data.phy_transition = end_trans;
 
-    /* Read back radio state. If in TXRU, we are fine */
+    /* If we already started transmitting, abort it! */
     state = NRF_RADIO->STATE;
-    if (state == RADIO_STATE_STATE_TxRu) {
+    if (state != RADIO_STATE_STATE_Tx) {
         /* Copy data from mbuf into transmit buffer */
-        os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset,
-                         ble_hdr->txinfo.pyld_len, dptr);
+        os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset, payload_len, dptr);
 
         /* Set phy state to transmitting and count packet statistics */
         g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
         STATS_INC(ble_phy_stats, tx_good);
-        STATS_INCN(ble_phy_stats, tx_bytes,
-                   ble_hdr->txinfo.pyld_len + BLE_LL_PDU_HDR_LEN);
+        STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN);
         rc = BLE_ERR_SUCCESS;
     } else {
-        if (state == RADIO_STATE_STATE_Tx) {
-            STATS_INC(ble_phy_stats, tx_late);
-        } else {
-            STATS_INC(ble_phy_stats, tx_fail);
-        }
-
-        /* Frame failed to transmit */
         ble_phy_disable();
+        STATS_INC(ble_phy_stats, tx_late);
         rc = BLE_PHY_ERR_RADIO_STATE;
     }
 
@@ -932,6 +997,7 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit)
  *  -> Turn off all phy interrupts.
  *  -> Disable internal shortcuts.
  *  -> Disable the radio.
+ *  -> Make sure we wont automatically go to rx/tx on output compare
  *  -> Sets phy state to idle.
  *  -> Clears any pending irqs in the NVIC. Might not be necessary but we do
  *  it as a precaution.
@@ -944,6 +1010,7 @@ ble_phy_disable(void)
     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
     NRF_RADIO->SHORTS = 0;
     NRF_RADIO->TASKS_DISABLE = 1;
+    NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk | PPI_CHEN_CH20_Msk;
     NVIC_ClearPendingIRQ(RADIO_IRQn);
     g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8ddc20ee/net/nimble/drivers/nrf52/include/ble/xcvr.h
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf52/include/ble/xcvr.h b/net/nimble/drivers/nrf52/include/ble/xcvr.h
new file mode 100644
index 0000000..f3e60fa
--- /dev/null
+++ b/net/nimble/drivers/nrf52/include/ble/xcvr.h
@@ -0,0 +1,32 @@
+/**
+ * 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_BLE_XCVR_
+#define H_BLE_XCVR_
+
+/* Transceiver specific defintions */
+#define XCVR_RX_START_DELAY_USECS     (140)
+#define XCVR_TX_START_DELAY_USECS     (140)
+#define XCVR_PROC_DELAY_USECS         (50)
+#define XCVR_TX_SCHED_DELAY_USECS     \
+    (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
+#define XCVR_RX_SCHED_DELAY_USECS     \
+    (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
+
+#endif /* H_BLE_XCVR_ */


[19/50] [abbrv] incubator-mynewt-core git commit: I2C interface supporting blocking read and write

Posted by ma...@apache.org.
I2C interface supporting blocking read and write

changes to support start and stop conditions


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

Branch: refs/heads/master
Commit: 598b91010431f175394c03f34b7cd2429b66248e
Parents: 9131d1e
Author: Paul Dietrich <pa...@yahoo.com>
Authored: Thu Apr 14 16:55:12 2016 -0700
Committer: Paul Dietrich <pa...@yahoo.com>
Committed: Tue Apr 19 20:48:12 2016 -0700

----------------------------------------------------------------------
 hw/hal/include/hal/hal_i2c.h     | 89 +++++++++++++++++++++++++++++++++++
 hw/hal/include/hal/hal_i2c_int.h | 54 +++++++++++++++++++++
 hw/hal/src/hal_i2c.c             | 78 ++++++++++++++++++++++++++++++
 3 files changed, 221 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/598b9101/hw/hal/include/hal/hal_i2c.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_i2c.h b/hw/hal/include/hal/hal_i2c.h
new file mode 100644
index 0000000..82546d4
--- /dev/null
+++ b/hw/hal/include/hal/hal_i2c.h
@@ -0,0 +1,89 @@
+/**
+ * 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 HAL_I2C_H
+#define HAL_I2C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <bsp/bsp_sysid.h>
+
+/* This is the API for an i2c bus.  I tried to make this a simple API */
+
+struct hal_i2c;
+
+/* when sending a packet, use this structure to pass the arguments */
+struct hal_i2c_master_data {
+    uint8_t  address;   /* destination address */
+            /* NOTE: Write addresses are even and read addresses are odd
+             * but in this API, you must enter a single address that is the
+             * write address divide by 2.  For example, for address 
+             * 80, you would enter a 40 */
+    uint8_t *buffer;    /* buffer space to hold the transmit or receive */
+    uint16_t len;       /* length of buffer to transmit or receive */
+};
+
+/* Initialize a new i2c device with the given system id.
+ * Returns negative on error, 0 on success. */
+struct hal_i2c*
+hal_i2c_init(enum system_device_id sysid);
+
+/* Sends <len> bytes of data on the i2c.  This API assumes that you 
+ * issued a successful start condition.  It will fail if you
+ * have not. This API does NOT issue a stop condition.  You must stop the 
+ * bus after successful or unsuccessful write attempts.  Returns 0 on 
+ * success, negative on failure */
+int
+hal_i2c_master_write(struct hal_i2c*, struct hal_i2c_master_data *pdata);
+
+/* Reads <len> bytes of data on the i2c.  This API assumes that you 
+ * issued a successful start condition.  It will fail if you
+ * have not. This API does NOT issue a stop condition.  You must stop the 
+ * bus after successful or unsuccessful write attempts.  Returns 0 on 
+ * success, negative on failure */
+int
+hal_i2c_master_read(struct hal_i2c*, struct hal_i2c_master_data *pdata);
+
+/* issues a start condition and address on the SPI bus. Returns 0 
+ * on success, negative on error.
+ */
+int 
+hal_i2c_master_start(struct hal_i2c*);
+
+/* issues a stop condition on the bus.  You must issue a stop condition for
+ * every successful start condition on the bus */
+int 
+hal_i2c_master_stop(struct hal_i2c*);
+
+
+/* Probes the i2c bus for a device with this address.  THIS API 
+ * issues a start condition, probes the address and issues a stop
+ * condition.  
+ */
+int 
+hal_i2c_master_probe(struct hal_i2c*, uint8_t address);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_I2C_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/598b9101/hw/hal/include/hal/hal_i2c_int.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_i2c_int.h b/hw/hal/include/hal/hal_i2c_int.h
new file mode 100644
index 0000000..59593e0
--- /dev/null
+++ b/hw/hal/include/hal/hal_i2c_int.h
@@ -0,0 +1,54 @@
+/**
+ * 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 HAL_I2C_INT_H
+#define HAL_I2C_INT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <hal/hal_i2c.h>
+#include <inttypes.h>
+
+struct hal_i2c;
+
+struct hal_i2c_funcs {
+    int (*hi2cm_write_data) (struct hal_i2c *pi2c, struct hal_i2c_master_data *ppkt);
+    int (*hi2cm_read_data)  (struct hal_i2c *pi2c, struct hal_i2c_master_data *ppkt);
+    int (*hi2cm_probe)      (struct hal_i2c *pi2c, uint8_t address);
+    int (*hi2cm_start)      (struct hal_i2c *pi2c);
+    int (*hi2cm_stop)       (struct hal_i2c *pi2c);
+};
+
+struct hal_i2c
+{
+    const struct hal_i2c_funcs *driver_api;
+};
+
+struct hal_i2c *
+bsp_get_hal_i2c_driver(enum system_device_id sysid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_I2C_INT_H */
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/598b9101/hw/hal/src/hal_i2c.c
----------------------------------------------------------------------
diff --git a/hw/hal/src/hal_i2c.c b/hw/hal/src/hal_i2c.c
new file mode 100644
index 0000000..bd20620
--- /dev/null
+++ b/hw/hal/src/hal_i2c.c
@@ -0,0 +1,78 @@
+/**
+ * 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.
+ */
+#include <bsp/bsp_sysid.h>
+#include <hal/hal_i2c.h>
+#include <hal/hal_i2c_int.h>
+
+struct hal_i2c *
+hal_i2c_init(enum system_device_id sysid)
+{
+    return bsp_get_hal_i2c_driver(sysid);
+}
+
+int
+hal_i2c_master_write(struct hal_i2c *pi2c, struct hal_i2c_master_data *ppkt)
+{
+    if (pi2c && pi2c->driver_api && pi2c->driver_api->hi2cm_write_data )
+    {
+        return pi2c->driver_api->hi2cm_write_data(pi2c, ppkt);
+    }
+    return -1;
+}
+
+int
+hal_i2c_master_read(struct hal_i2c *pi2c, struct hal_i2c_master_data *ppkt)
+{
+    if (pi2c && pi2c->driver_api && pi2c->driver_api->hi2cm_read_data )
+    {
+        return pi2c->driver_api->hi2cm_read_data(pi2c, ppkt);
+    }
+    return -1;
+}
+
+int
+hal_i2c_master_probe(struct hal_i2c *pi2c, uint8_t address)
+{
+    if (pi2c && pi2c->driver_api && pi2c->driver_api->hi2cm_probe )
+    {
+        return pi2c->driver_api->hi2cm_probe(pi2c, address);
+    }
+    return -1;
+}
+
+int
+hal_i2c_master_start(struct hal_i2c *pi2c)
+{
+    if (pi2c && pi2c->driver_api && pi2c->driver_api->hi2cm_start )
+    {
+        return pi2c->driver_api->hi2cm_start(pi2c);
+    }
+    return -1;
+}
+
+
+int
+hal_i2c_master_stop(struct hal_i2c *pi2c)
+{
+    if (pi2c && pi2c->driver_api && pi2c->driver_api->hi2cm_stop )
+    {
+        return pi2c->driver_api->hi2cm_stop(pi2c);
+    }
+    return -1;
+}


[40/50] [abbrv] incubator-mynewt-core git commit: add coding standards

Posted by ma...@apache.org.
add coding standards


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

Branch: refs/heads/master
Commit: 3bdb0183caa84397af454b018fdabfe40cc99e79
Parents: 2b268fb
Author: Sterling Hughes <st...@apache.org>
Authored: Sun Apr 24 09:56:13 2016 -0700
Committer: Sterling Hughes <st...@apache.org>
Committed: Sun Apr 24 09:56:13 2016 -0700

----------------------------------------------------------------------
 CODING_STANDARDS.md | 240 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 240 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bdb0183/CODING_STANDARDS.md
----------------------------------------------------------------------
diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md
new file mode 100644
index 0000000..5d1e5f3
--- /dev/null
+++ b/CODING_STANDARDS.md
@@ -0,0 +1,240 @@
+# Coding Style for Apache Mynewt Core
+
+This document is meant to define the coding style for Apache Mynewt, and 
+all subprojects of Apache Mynewt.  This covers C and Assembly coding 
+conventions, *only*.  Other languages (such as Go), have their own 
+coding conventions.
+
+## Whitespace and Braces
+
+* Code must be indented to 4 spaces, tabs should not be used.
+
+* Do not add whitespace at the end of a line.
+
+* Put space after keywords (for, if, return, switch, while).
+
+* for, else, if, while statements must have braces around their 
+code blocks, i.e., do: 
+
+```
+    if (x) {
+        assert(0);
+    } else {
+        assert(0);
+    }
+```
+
+not: 
+
+```
+    if (x) 
+        assert(0);
+    else
+        assert(0);
+```
+
+* Braces for statements must be on the same line as the statement.  Good:
+
+```
+    for (i = 0; i < 10; i++) {
+        if (i == 5) {
+            break;
+        } else {
+            continue;
+        }
+    }
+```
+
+Bad:
+
+```
+    for (i = 0; i < 10; i++) 
+    { <-- brace must be on same line as for
+        if (i == 5) {
+            break;
+        } <-- no new line between else
+        else {
+            continue;
+        }
+    }
+```
+
+* After a function declaration, the braces should be on a newline, i.e. do:
+
+```
+    static void *
+    function(int var1, int var2)
+    {
+```
+
+not: 
+
+```
+    static void *
+    function(int var1, int var2) {
+```
+
+## Line Length and Wrap
+
+* Line length should never exceed 79 columns.
+
+* When you have to wrap a long statement, put the operator at the end of the 
+  line.  i.e.:
+
+    if (x &&
+        y == 10 &&
+        b)
+  Not:
+
+    if (x
+        && y == 10
+        && b)
+
+## Comments
+
+* No C++ style comments allowed.
+
+* When using a single line comment, put it above the line of code that you 
+intend to comment, i.e., do:
+
+    /* check variable */
+    if (a) {
+
+and not: 
+
+    if (a) { /* check variable */
+
+
+* All public APIs should be commented with Doxygen style comments describing 
+purpose, parameters and return values.  Private APIs need not be documented.
+
+
+## Header files
+
+* Header files must contain the following structure:
+    * Apache License
+    * ```#ifdef``` aliasing, to prevent multiple includes
+    * ```#include``` directives for other required header files
+    * ```#ifdef __cplusplus``` wrappers to maintain C++ friendly APIs
+    * Contents of the header file
+
+* The Apache License clause is as follows:
+
+```no-highlight
+/**
+ * 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.
+ */
+```
+
+* ```#ifdef``` aliasing, shall be in the following format, where
+the package name is "os" and the file name is "callout.h": 
+
+```no-highlight
+#ifndef _OS_CALLOUT_H
+#define _OS_CALLOUT_H
+```
+
+* ```#include``` directives must happen prior to the cplusplus 
+wrapper.
+
+* The cplusplus wrapper must have the following format, and precedes
+any contents of the header file:
+
+```no-highlight
+#ifdef __cplusplus
+#extern "C" {
+##endif
+```
+
+## Naming
+
+* Names of functions, structures and variables must be in all lowercase.  
+
+* Names should be as short as possible, but no shorter.  
+
+* Globally visible names must be prefixed with the name of the module, 
+followed by the '_' character, i.e.: 
+
+```
+    os_callout_init(&c)
+```
+
+not:
+
+```
+    callout_init(c)
+```
+
+## Functions
+
+* No spaces after function names when calling a function, i.e, do:
+
+```
+    rc = function(a)
+```
+
+not: 
+
+```
+    rc = function (a)
+```
+
+
+* Arguments to function calls should have spaces between the comma, i.e. do:
+
+```
+    rc = function(a, b)
+```
+
+not: 
+
+```
+    rc = function(a,b)
+```
+
+* The function type must be on a line by itself preceding the function, i.e. do: 
+
+```
+    static void *
+    function(int var1, int var2)
+    {
+```
+
+not: 
+
+```
+    static void *function(int var1, int var2)
+    {
+```
+
+* In general, for functions that return values that denote success or error, 0
+shall be success, and non-zero shall be the failure code.
+
+## Variables and Macros
+
+* Do not use typedefs for structures.  This makes it impossible for 
+applications to use pointers to those structures opaquely.  
+
+* typedef may be used for non-structure types, where it is beneficial to 
+hide or alias the underlying type used (e.g. ```os_time_t```.)   Indicate
+typedefs by applying the ```_t``` marker to them.
+
+## Compiler Directives
+
+* Code must compile cleanly with -Wall enabled.
+


[22/50] [abbrv] incubator-mynewt-core git commit: ble host - separate blocking HCI from rx

Posted by ma...@apache.org.
ble host - separate blocking HCI from rx


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

Branch: refs/heads/master
Commit: 151139ced61ffdeb339977844be5bb99ed0986f3
Parents: d200094
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 20 12:42:32 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 20 16:11:38 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/include/host/host_hci.h |   1 -
 net/nimble/host/src/ble_gap.c           |  32 +--
 net/nimble/host/src/ble_hci_cmd.c       | 293 +++++++++++++++++++++++++++
 net/nimble/host/src/ble_hci_util.c      |   6 +-
 net/nimble/host/src/ble_hs.c            |   2 +-
 net/nimble/host/src/ble_hs_priv.h       |  10 +-
 net/nimble/host/src/ble_hs_startup.c    |  10 +-
 net/nimble/host/src/ble_l2cap_sm.c      |   4 +-
 net/nimble/host/src/host_hci.c          | 235 +--------------------
 9 files changed, 327 insertions(+), 266 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/151139ce/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 1b8d61f..8011f79 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -129,6 +129,5 @@ int host_hci_data_rx(struct os_mbuf *om);
 int host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *om);
 
 void host_hci_timer_set(void);
-void host_hci_init(void);
 
 #endif /* H_HOST_HCI_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/151139ce/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 7e87661..5a556d1 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -1013,7 +1013,7 @@ ble_gap_wl_tx_add(struct ble_gap_white_entry *entry)
         return rc;
     }
 
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1032,7 +1032,7 @@ ble_gap_wl_tx_clear(void)
     int rc;
 
     host_hci_cmd_build_le_clear_whitelist(buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1114,7 +1114,7 @@ ble_gap_adv_disable_tx(void)
     int rc;
 
     host_hci_cmd_build_le_set_adv_enable(0, buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1204,7 +1204,7 @@ ble_gap_adv_enable_tx(void)
 
     host_hci_cmd_build_le_set_adv_enable(1, buf, sizeof buf);
 
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1229,7 +1229,7 @@ ble_gap_adv_rsp_data_tx(void)
         return rc;
     }
 
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1294,7 +1294,7 @@ ble_gap_adv_data_tx(void)
         return rc;
     }
 
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1335,7 +1335,7 @@ ble_gap_adv_params_tx(struct hci_adv_params *adv_params)
         return rc;
     }
 
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1582,7 +1582,7 @@ ble_gap_disc_tx_disable(void)
     int rc;
 
     host_hci_cmd_build_le_set_scan_enable(0, 0, buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1601,7 +1601,7 @@ ble_gap_disc_tx_enable(void)
     int rc;
 
     host_hci_cmd_build_le_set_scan_enable(1, 0, buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1628,7 +1628,7 @@ ble_gap_disc_tx_params(uint8_t scan_type, uint8_t filter_policy)
         buf, sizeof buf);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0);
 
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1770,7 +1770,7 @@ ble_gap_conn_create_tx(int addr_type, uint8_t *addr,
         return BLE_HS_EUNKNOWN;
     }
 
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1884,7 +1884,7 @@ ble_gap_terminate(uint16_t conn_handle)
 
     host_hci_cmd_build_disconnect(conn_handle, BLE_ERR_REM_USER_CONN_TERM,
                                   buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         goto done;
     }
@@ -1927,7 +1927,7 @@ ble_gap_cancel(void)
     BLE_HS_LOG(INFO, "GAP procedure initiated: cancel connection\n");
 
     host_hci_cmd_build_le_create_conn_cancel(buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         goto done;
     }
@@ -1965,7 +1965,7 @@ ble_gap_tx_param_pos_reply(uint16_t conn_handle,
     pos_reply.max_ce_len = params->max_ce_len;
 
     host_hci_cmd_build_le_conn_param_reply(&pos_reply, buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -1984,7 +1984,7 @@ ble_gap_tx_param_neg_reply(uint16_t conn_handle, uint8_t reject_reason)
     neg_reply.reason = reject_reason;
 
     host_hci_cmd_build_le_conn_param_neg_reply(&neg_reply, buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -2079,7 +2079,7 @@ ble_gap_update_tx(uint16_t conn_handle, struct ble_gap_upd_params *params)
         return rc;
     }
 
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/151139ce/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
new file mode 100644
index 0000000..76b7b0e
--- /dev/null
+++ b/net/nimble/host/src/ble_hci_cmd.c
@@ -0,0 +1,293 @@
+/**
+ * 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.
+ */
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include "os/os.h"
+#include "ble_hs_priv.h"
+#include "host_dbg.h"
+
+#define BLE_HCI_CMD_TIMEOUT     (OS_TICKS_PER_SEC)
+
+static struct os_mutex ble_hci_cmd_mutex;
+static struct os_sem ble_hci_cmd_sem;
+static uint8_t *ble_hci_cmd_ack_ev;
+
+#if PHONY_HCI_ACKS
+static ble_hci_cmd_phony_ack_fn *ble_hci_cmd_phony_ack_cb;
+#endif
+
+#if PHONY_HCI_ACKS
+void
+ble_hci_set_phony_ack_cb(ble_hci_cmd_phony_ack_fn *cb)
+{
+    ble_hci_cmd_phony_ack_cb = cb;
+}
+#endif
+
+static void
+ble_hci_cmd_lock(void)
+{
+    int rc;
+
+    rc = os_mutex_pend(&ble_hci_cmd_mutex, 0xffffffff);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
+}
+
+static void
+ble_hci_cmd_unlock(void)
+{
+    int rc;
+
+    rc = os_mutex_release(&ble_hci_cmd_mutex);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
+}
+
+static int
+ble_hci_cmd_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len,
+                         struct ble_hci_ack *out_ack)
+{
+    uint16_t opcode;
+    uint8_t *params;
+    uint8_t params_len;
+    uint8_t num_pkts;
+
+    if (len < BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN) {
+        /* XXX: Increment stat. */
+        return BLE_HS_EMSGSIZE;
+    }
+
+    num_pkts = data[2];
+    opcode = le16toh(data + 3);
+    params = data + 5;
+
+    /* XXX: Process num_pkts field. */
+    (void)num_pkts;
+
+    out_ack->bha_opcode = opcode;
+
+    params_len = len - BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
+    if (params_len > 0) {
+        out_ack->bha_status = BLE_HS_HCI_ERR(params[0]);
+    } else if (opcode == BLE_HCI_OPCODE_NOP) {
+        out_ack->bha_status = 0;
+    } else {
+        out_ack->bha_status = BLE_HS_ECONTROLLER;
+    }
+
+    /* Don't include the status byte in the parameters blob. */
+    if (params_len > 1) {
+        out_ack->bha_params = params + 1;
+        out_ack->bha_params_len = params_len - 1;
+    } else {
+        out_ack->bha_params = NULL;
+        out_ack->bha_params_len = 0;
+    }
+
+    return 0;
+}
+
+static int
+ble_hci_cmd_rx_cmd_status(uint8_t event_code, uint8_t *data, int len,
+                       struct ble_hci_ack *out_ack)
+{
+    uint16_t opcode;
+    uint8_t num_pkts;
+    uint8_t status;
+
+    if (len < BLE_HCI_EVENT_CMD_STATUS_LEN) {
+        /* XXX: Increment stat. */
+        return BLE_HS_EMSGSIZE;
+    }
+
+    status = data[2];
+    num_pkts = data[3];
+    opcode = le16toh(data + 4);
+
+    /* XXX: Process num_pkts field. */
+    (void)num_pkts;
+
+    out_ack->bha_opcode = opcode;
+    out_ack->bha_params = NULL;
+    out_ack->bha_params_len = 0;
+    out_ack->bha_status = BLE_HS_HCI_ERR(status);
+
+    return 0;
+}
+
+static int
+ble_hci_cmd_process_ack(uint8_t *params_buf, uint8_t params_buf_len,
+                        struct ble_hci_ack *out_ack)
+{
+    uint8_t event_code;
+    uint8_t param_len;
+    uint8_t event_len;
+    int rc;
+
+    BLE_HS_DBG_ASSERT(ble_hci_cmd_ack_ev != NULL);
+
+    /* Count events received */
+    STATS_INC(ble_hs_stats, hci_event);
+
+    /* Display to console */
+    host_hci_dbg_event_disp(ble_hci_cmd_ack_ev);
+
+    event_code = ble_hci_cmd_ack_ev[0];
+    param_len = ble_hci_cmd_ack_ev[1];
+    event_len = param_len + 2;
+
+    /* Clear ack fields up front to silence spurious gcc warnings. */
+    memset(out_ack, 0, sizeof *out_ack);
+
+    switch (event_code) {
+    case BLE_HCI_EVCODE_COMMAND_COMPLETE:
+        rc = ble_hci_cmd_rx_cmd_complete(event_code, ble_hci_cmd_ack_ev,
+                                         event_len, out_ack);
+        break;
+
+    case BLE_HCI_EVCODE_COMMAND_STATUS:
+        rc = ble_hci_cmd_rx_cmd_status(event_code, ble_hci_cmd_ack_ev,
+                                       event_len, out_ack);
+        break;
+
+    default:
+        BLE_HS_DBG_ASSERT(0);
+        rc = BLE_HS_EUNKNOWN;
+        break;
+    }
+
+    if (rc == 0) {
+        if (params_buf == NULL) {
+            out_ack->bha_params_len = 0;
+        } else {
+            if (out_ack->bha_params_len > params_buf_len) {
+                out_ack->bha_params_len = params_buf_len;
+                rc = BLE_HS_EMSGSIZE;
+            }
+            memcpy(params_buf, out_ack->bha_params, out_ack->bha_params_len);
+        }
+        out_ack->bha_params = params_buf;
+    }
+
+    os_memblock_put(&g_hci_cmd_pool, ble_hci_cmd_ack_ev);
+    ble_hci_cmd_ack_ev = NULL;
+
+    return rc;
+}
+
+static int
+ble_hci_cmd_wait_for_ack(void)
+{
+    int rc;
+
+#if PHONY_HCI_ACKS
+    if (ble_hci_cmd_phony_ack_cb == NULL) {
+        rc = BLE_HS_ETIMEOUT;
+    } else {
+        BLE_HS_DBG_ASSERT(ble_hci_cmd_ack_ev == NULL);
+        ble_hci_cmd_ack_ev = os_memblock_get(&g_hci_cmd_pool);
+        if (ble_hci_cmd_ack_ev == NULL) {
+            rc = BLE_HS_ENOMEM;
+        } else {
+            rc = ble_hci_cmd_phony_ack_cb(ble_hci_cmd_ack_ev, 260);
+        }
+    }
+#else
+    rc = os_sem_pend(&ble_hci_cmd_sem, BLE_HCI_CMD_TIMEOUT);
+#endif
+
+    return rc;
+}
+
+int
+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;
+    int rc;
+
+    ble_hci_cmd_lock();
+
+    rc = host_hci_cmd_send_buf(cmd);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_hci_cmd_wait_for_ack();
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_hci_cmd_process_ack(evt_buf, evt_buf_len, &ack);
+    if (rc != 0) {
+        goto done;
+    }
+
+    if (out_evt_buf_len != NULL) {
+        *out_evt_buf_len = ack.bha_params_len;
+    }
+
+    rc = ack.bha_status;
+
+done:
+    ble_hci_cmd_unlock();
+    return rc;
+}
+
+int
+ble_hci_cmd_tx_empty_ack(void *cmd)
+{
+    int rc;
+
+    rc = ble_hci_cmd_tx(cmd, NULL, 0, NULL);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+void
+ble_hci_cmd_rx_ack(uint8_t *ack_ev)
+{
+    int rc;
+
+    if (ble_hci_cmd_ack_ev != NULL) {
+        /* The controller sent two acks.  Free the first one. */
+        rc = os_memblock_put(&g_hci_cmd_pool, ble_hci_cmd_ack_ev);
+        BLE_HS_DBG_ASSERT_EVAL(rc == 0);
+    }
+
+    /* Hand up the acknowledgement and unblock the application. */
+    ble_hci_cmd_ack_ev = ack_ev;
+    os_sem_release(&ble_hci_cmd_sem);
+}
+
+void
+ble_hci_cmd_init(void)
+{
+    int rc;
+
+    rc = os_sem_init(&ble_hci_cmd_sem, 0);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
+
+    rc = os_mutex_init(&ble_hci_cmd_mutex);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/151139ce/net/nimble/host/src/ble_hci_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util.c b/net/nimble/host/src/ble_hci_util.c
index 9216377..2a661e9 100644
--- a/net/nimble/host/src/ble_hci_util.c
+++ b/net/nimble/host/src/ble_hci_util.c
@@ -30,7 +30,7 @@ ble_hci_util_read_adv_tx_pwr(int8_t *out_tx_pwr)
     int rc;
 
     host_hci_cmd_build_read_adv_pwr(buf, sizeof buf);
-    rc = ble_hci_tx_cmd(buf, out_tx_pwr, 1, &params_len);
+    rc = ble_hci_cmd_tx(buf, out_tx_pwr, 1, &params_len);
     if (rc != 0) {
         return rc;
     }
@@ -59,7 +59,7 @@ ble_hci_util_rand(void *dst, int len)
 
     u8ptr = dst;
     while (len > 0) {
-        rc = ble_hci_tx_cmd(req_buf, rsp_buf, sizeof rsp_buf, &params_len);
+        rc = ble_hci_cmd_tx(req_buf, rsp_buf, sizeof rsp_buf, &params_len);
         if (rc != 0) {
             return rc;
         }
@@ -87,7 +87,7 @@ ble_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi)
     int rc;
 
     host_hci_cmd_build_read_rssi(conn_handle, buf, sizeof buf);
-    rc = ble_hci_tx_cmd(buf, params, 1, &params_len);
+    rc = ble_hci_cmd_tx(buf, params, 1, &params_len);
     if (rc != 0) {
         return rc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/151139ce/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 8a65c00..e05a9e9 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -329,7 +329,7 @@ ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg)
         goto err;
     }
 
-    host_hci_init();
+    ble_hci_cmd_init();
 
     rc = ble_hs_conn_init();
     if (rc != 0) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/151139ce/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 09e9ef4..9bd3632 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -106,14 +106,16 @@ struct os_mbuf *ble_hs_misc_pkthdr(void);
 
 int ble_hs_misc_pullup_base(struct os_mbuf **om, int base_len);
 
-int ble_hci_tx_cmd(void *cmd, void *evt_buf, uint8_t evt_buf_len,
+int ble_hci_cmd_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len,
                    uint8_t *out_evt_buf_len);
-int ble_hci_tx_cmd_empty_ack(void *cmd);
+int ble_hci_cmd_tx_empty_ack(void *cmd);
+void ble_hci_cmd_rx_ack(uint8_t *ack_ev);
+void ble_hci_cmd_init(void);
 
 #if PHONY_HCI_ACKS
-typedef int ble_hci_phony_ack_fn(uint8_t *ack, int ack_buf_len);
+typedef int ble_hci_cmd_phony_ack_fn(uint8_t *ack, int ack_buf_len);
 
-void ble_hci_set_phony_ack_cb(ble_hci_phony_ack_fn *cb);
+void ble_hci_set_phony_ack_cb(ble_hci_cmd_phony_ack_fn *cb);
 #endif
 
 #define BLE_HS_LOG(lvl, ...) \

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/151139ce/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 98be26c..31af1ea 100644
--- a/net/nimble/host/src/ble_hs_startup.c
+++ b/net/nimble/host/src/ble_hs_startup.c
@@ -32,7 +32,7 @@ ble_hs_startup_le_read_sup_f_tx(void)
     int rc;
 
     host_hci_cmd_build_le_read_loc_supp_feat(buf, sizeof buf);
-    rc = ble_hci_tx_cmd(buf, ack_params, sizeof ack_params, &ack_params_len);
+    rc = ble_hci_cmd_tx(buf, ack_params, sizeof ack_params, &ack_params_len);
     if (rc != 0) {
         return rc;
     }
@@ -57,7 +57,7 @@ ble_hs_startup_le_read_buf_sz_tx(void)
     int rc;
 
     host_hci_cmd_build_le_read_buffer_size(buf, sizeof buf);
-    rc = ble_hci_tx_cmd(buf, ack_params, sizeof ack_params, &ack_params_len);
+    rc = ble_hci_cmd_tx(buf, ack_params, sizeof ack_params, &ack_params_len);
     if (rc != 0) {
         return rc;
     }
@@ -85,7 +85,7 @@ ble_hs_startup_le_set_evmask_tx(void)
 
     /* [ Default event set ]. */
     host_hci_cmd_build_le_set_event_mask(0x000000000000001f, buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -101,7 +101,7 @@ ble_hs_startup_set_evmask_tx(void)
 
     /* [ Default event set | LE-meta event ]. */
     host_hci_cmd_build_set_event_mask(0x20001fffffffffff, buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -116,7 +116,7 @@ ble_hs_startup_reset_tx(void)
     int rc;
 
     host_hci_cmd_build_reset(buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/151139ce/net/nimble/host/src/ble_l2cap_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.c b/net/nimble/host/src/ble_l2cap_sm.c
index e385ac6..e052f2e 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -468,7 +468,7 @@ ble_l2cap_sm_start_encrypt_tx(uint16_t conn_handle, uint8_t *ltk)
     memcpy(cmd.long_term_key, ltk, sizeof cmd.long_term_key);
 
     host_hci_cmd_build_le_start_encrypt(&cmd, buf, sizeof buf);
-    rc = ble_hci_tx_cmd_empty_ack(buf);
+    rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
     }
@@ -489,7 +489,7 @@ ble_l2cap_sm_lt_key_req_reply_tx(uint16_t conn_handle, uint8_t *ltk)
     memcpy(cmd.long_term_key, ltk, 16);
 
     host_hci_cmd_build_le_lt_key_req_reply(&cmd, buf, sizeof buf);
-    rc = ble_hci_tx_cmd(buf, &ack_conn_handle, sizeof ack_conn_handle,
+    rc = ble_hci_cmd_tx(buf, &ack_conn_handle, sizeof ack_conn_handle,
                         &ack_params_len);
     if (rc != 0) {
         return rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/151139ce/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 31eb108..4994cb6 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -31,8 +31,6 @@
 _Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ,
                "struct hci_data_hdr must be 4 bytes");
 
-#define BLE_HCI_TIMEOUT       (OS_TICKS_PER_SEC)
-
 typedef int host_hci_event_fn(uint8_t event_code, uint8_t *data, int len);
 static host_hci_event_fn host_hci_rx_disconn_complete;
 static host_hci_event_fn host_hci_rx_encrypt_change;
@@ -181,78 +179,6 @@ host_hci_rx_encrypt_change(uint8_t event_code, uint8_t *data, int len)
 }
 
 static int
-host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len,
-                         struct ble_hci_ack *out_ack)
-{
-    uint16_t opcode;
-    uint8_t *params;
-    uint8_t params_len;
-    uint8_t num_pkts;
-
-    if (len < BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN) {
-        /* XXX: Increment stat. */
-        return BLE_HS_EMSGSIZE;
-    }
-
-    num_pkts = data[2];
-    opcode = le16toh(data + 3);
-    params = data + 5;
-
-    /* XXX: Process num_pkts field. */
-    (void)num_pkts;
-
-    out_ack->bha_opcode = opcode;
-
-    params_len = len - BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
-    if (params_len > 0) {
-        out_ack->bha_status = BLE_HS_HCI_ERR(params[0]);
-    } else if (opcode == BLE_HCI_OPCODE_NOP) {
-        out_ack->bha_status = 0;
-    } else {
-        out_ack->bha_status = BLE_HS_ECONTROLLER;
-    }
-
-    /* Don't include the status byte in the parameters blob. */
-    if (params_len > 1) {
-        out_ack->bha_params = params + 1;
-        out_ack->bha_params_len = params_len - 1;
-    } else {
-        out_ack->bha_params = NULL;
-        out_ack->bha_params_len = 0;
-    }
-
-    return 0;
-}
-
-static int
-host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len,
-                       struct ble_hci_ack *out_ack)
-{
-    uint16_t opcode;
-    uint8_t num_pkts;
-    uint8_t status;
-
-    if (len < BLE_HCI_EVENT_CMD_STATUS_LEN) {
-        /* XXX: Increment stat. */
-        return BLE_HS_EMSGSIZE;
-    }
-
-    status = data[2];
-    num_pkts = data[3];
-    opcode = le16toh(data + 4);
-
-    /* XXX: Process num_pkts field. */
-    (void)num_pkts;
-
-    out_ack->bha_opcode = opcode;
-    out_ack->bha_params = NULL;
-    out_ack->bha_params_len = 0;
-    out_ack->bha_status = BLE_HS_HCI_ERR(status);
-
-    return 0;
-}
-
-static int
 host_hci_rx_num_completed_pkts(uint8_t event_code, uint8_t *data, int len)
 {
     uint16_t num_pkts;
@@ -598,21 +524,6 @@ host_hci_os_event_proc(struct os_event *ev)
     return rc;
 }
 
-static uint8_t *ble_hci_ack_ev;
-static struct os_sem ble_hci_sem;
-
-#if PHONY_HCI_ACKS
-static ble_hci_phony_ack_fn *ble_hci_phony_ack_cb;
-#endif
-
-#if PHONY_HCI_ACKS
-void
-ble_hci_set_phony_ack_cb(ble_hci_phony_ack_fn *cb)
-{
-    ble_hci_phony_ack_cb = cb;
-}
-#endif
-
 /* XXX: For now, put this here */
 int
 ble_hci_transport_ctlr_event_send(uint8_t *hci_ev)
@@ -629,16 +540,7 @@ ble_hci_transport_ctlr_event_send(uint8_t *hci_ev)
         if (hci_ev[3] == 0 && hci_ev[4] == 0) {
             enqueue = 1;
         } else {
-            if (ble_hci_ack_ev != NULL) {
-                /* The controller sent two acks.  Free the first one. */
-                BLE_HS_DBG_ASSERT(0);
-
-                err = os_memblock_put(&g_hci_cmd_pool, ble_hci_ack_ev);
-                BLE_HS_DBG_ASSERT_EVAL(err == OS_OK);
-            }
-
-            ble_hci_ack_ev = hci_ev;
-            os_sem_release(&ble_hci_sem);
+            ble_hci_cmd_rx_ack(hci_ev);
             enqueue = 0;
         }
         break;
@@ -668,132 +570,6 @@ ble_hci_transport_ctlr_event_send(uint8_t *hci_ev)
 }
 
 static int
-ble_hci_process_ack(uint8_t *params_buf, uint8_t params_buf_len,
-                    struct ble_hci_ack *out_ack)
-{
-    uint8_t event_code;
-    uint8_t param_len;
-    uint8_t event_len;
-    int rc;
-
-    BLE_HS_DBG_ASSERT(ble_hci_ack_ev != NULL);
-
-    /* Count events received */
-    STATS_INC(ble_hs_stats, hci_event);
-
-    /* Display to console */
-    host_hci_dbg_event_disp(ble_hci_ack_ev);
-
-    event_code = ble_hci_ack_ev[0];
-    param_len = ble_hci_ack_ev[1];
-    event_len = param_len + 2;
-
-    /* Clear ack fields up front to silence spurious gcc warnings. */
-    memset(out_ack, 0, sizeof *out_ack);
-
-    switch (event_code) {
-    case BLE_HCI_EVCODE_COMMAND_COMPLETE:
-        rc = host_hci_rx_cmd_complete(event_code, ble_hci_ack_ev, event_len,
-                                      out_ack);
-        break;
-
-    case BLE_HCI_EVCODE_COMMAND_STATUS:
-        rc = host_hci_rx_cmd_status(event_code, ble_hci_ack_ev, event_len,
-                                    out_ack);
-        break;
-
-    default:
-        BLE_HS_DBG_ASSERT(0);
-        rc = BLE_HS_EUNKNOWN;
-        break;
-    }
-
-    if (rc == 0) {
-        if (params_buf == NULL) {
-            out_ack->bha_params_len = 0;
-        } else {
-            if (out_ack->bha_params_len > params_buf_len) {
-                out_ack->bha_params_len = params_buf_len;
-                rc = BLE_HS_EMSGSIZE;
-            }
-            memcpy(params_buf, out_ack->bha_params, out_ack->bha_params_len);
-        }
-        out_ack->bha_params = params_buf;
-    }
-
-    os_memblock_put(&g_hci_cmd_pool, ble_hci_ack_ev);
-    ble_hci_ack_ev = NULL;
-
-    return rc;
-}
-
-static int
-ble_hci_wait_for_ack(void)
-{
-    int rc;
-
-#if PHONY_HCI_ACKS
-    if (ble_hci_phony_ack_cb == NULL) {
-        rc = BLE_HS_ETIMEOUT;
-    } else {
-        BLE_HS_DBG_ASSERT(ble_hci_ack_ev == NULL);
-        ble_hci_ack_ev = os_memblock_get(&g_hci_cmd_pool);
-        if (ble_hci_ack_ev == NULL) {
-            rc = BLE_HS_ENOMEM;
-        } else {
-            rc = ble_hci_phony_ack_cb(ble_hci_ack_ev, 260);
-        }
-    }
-#else
-    rc = os_sem_pend(&ble_hci_sem, BLE_HCI_TIMEOUT);
-#endif
-
-    return rc;
-}
-
-int
-ble_hci_tx_cmd(void *cmd, void *evt_buf, uint8_t evt_buf_len,
-               uint8_t *out_evt_buf_len)
-{
-    struct ble_hci_ack ack;
-    int rc;
-
-    rc = host_hci_cmd_send_buf(cmd);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = ble_hci_wait_for_ack();
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = ble_hci_process_ack(evt_buf, evt_buf_len, &ack);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (out_evt_buf_len != NULL) {
-        *out_evt_buf_len = ack.bha_params_len;
-    }
-
-    return ack.bha_status;
-}
-
-int
-ble_hci_tx_cmd_empty_ack(void *cmd)
-{
-    int rc;
-
-    rc = ble_hci_tx_cmd(cmd, NULL, 0, NULL);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-static int
 host_hci_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *hdr)
 {
     int rc;
@@ -928,12 +704,3 @@ host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *om)
 
     return 0;
 }
-
-void
-host_hci_init(void)
-{
-    int rc;
-
-    rc = os_sem_init(&ble_hci_sem, 0);
-    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-}


[36/50] [abbrv] incubator-mynewt-core git commit: cortex-m0; trap on divide-by-zero.

Posted by ma...@apache.org.
cortex-m0; trap on divide-by-zero.


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

Branch: refs/heads/master
Commit: c2959dc7c9eb869b4100650740e7095874dd4256
Parents: f0556b1
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Thu Apr 21 15:36:21 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Thu Apr 21 15:37:16 2016 -0700

----------------------------------------------------------------------
 libs/os/src/arch/cortex_m0/m0/HAL_CM0.s | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c2959dc7/libs/os/src/arch/cortex_m0/m0/HAL_CM0.s
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/cortex_m0/m0/HAL_CM0.s b/libs/os/src/arch/cortex_m0/m0/HAL_CM0.s
index 7cc7f1c..03d7957 100644
--- a/libs/os/src/arch/cortex_m0/m0/HAL_CM0.s
+++ b/libs/os/src/arch/cortex_m0/m0/HAL_CM0.s
@@ -200,6 +200,23 @@ SysTick_Handler:
         .fnend
         .size   SysTick_Handler, .-SysTick_Handler
 
+/* divide-by-zero */
+        .thumb_func
+	.type __aeabi_idiv0, %function
+	.global __aeabi_idiv0
+	.global __aeabi_ldiv0
+__aeabi_idiv0:
+__aeabi_ldiv0:
+        .fnstart
+        .cantunwind
+	push {r0,r1,r5}
+	ldr r0, =file_name
+	ldr r1, =__LINE__
+	ldr r5, =__assert_func
+	bx r5
+        .fnend
+        .size   __aeabi_idiv0, .-__aeabi_idiv0
+
 /*-------------------------- Defalt IRQ --------------------------------*/
         .thumb_func
         .type   os_default_irq_asm, %function
@@ -251,6 +268,9 @@ using_msp_as_sp:
         .section ".data"
         .global __aeabi_unwind_cpp_pr0
 __aeabi_unwind_cpp_pr0:
+	.section ".rodata"
+file_name:
+	.asciz __FILE__
         .end
 
 /*----------------------------------------------------------------------------


[25/50] [abbrv] incubator-mynewt-core git commit: ble host - fix SM bug; r1/r2 misordered on master.

Posted by ma...@apache.org.
ble host - fix SM bug; r1/r2 misordered on master.


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

Branch: refs/heads/master
Commit: 3befe370a84d50281001f695983f10f04774764e
Parents: 151139c
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 20 13:55:31 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 20 16:11:45 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_l2cap_sm.c | 36 +++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3befe370/net/nimble/host/src/ble_l2cap_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.c b/net/nimble/host/src/ble_l2cap_sm.c
index e052f2e..99f7d64 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -57,8 +57,8 @@ struct ble_l2cap_sm_proc {
     struct ble_l2cap_sm_pair_cmd pair_rsp;
     uint8_t tk[16];
     uint8_t confirm_their[16];
-    uint8_t rand_our[16];
-    uint8_t rand_their[16];
+    uint8_t randm[16];
+    uint8_t rands[16];
     uint8_t ltk[16];
 };
 
@@ -228,7 +228,7 @@ ble_l2cap_sm_gen_key(struct ble_l2cap_sm_proc *proc)
     uint8_t key[16];
     int rc;
 
-    rc = ble_l2cap_sm_alg_s1(proc->tk, proc->rand_our, proc->rand_their, key);
+    rc = ble_l2cap_sm_alg_s1(proc->tk, proc->rands, proc->randm, key);
     if (rc != 0) {
         return rc;
     }
@@ -528,13 +528,33 @@ ble_l2cap_sm_lt_key_req_handle(struct ble_l2cap_sm_proc *proc,
  * $random                                                                   *
  *****************************************************************************/
 
+static uint8_t *
+ble_l2cap_sm_our_pair_rand(struct ble_l2cap_sm_proc *proc)
+{
+    if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+        return proc->randm;
+    } else {
+        return proc->rands;
+    }
+}
+
+static uint8_t *
+ble_l2cap_sm_their_pair_rand(struct ble_l2cap_sm_proc *proc)
+{
+    if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+        return proc->rands;
+    } else {
+        return proc->randm;
+    }
+}
+
 static int
 ble_l2cap_sm_random_go(struct ble_l2cap_sm_proc *proc)
 {
     struct ble_l2cap_sm_pair_random cmd;
     int rc;
 
-    memcpy(cmd.value, proc->rand_our, 16);
+    memcpy(cmd.value, ble_l2cap_sm_our_pair_rand(proc), 16);
     rc = ble_l2cap_sm_pair_random_tx(proc->conn_handle, &cmd);
     if (rc != 0) {
         return rc;
@@ -582,7 +602,7 @@ ble_l2cap_sm_random_handle(struct ble_l2cap_sm_proc *proc,
         return rc;
     }
 
-    memcpy(proc->rand_their, cmd->value, 16);
+    memcpy(ble_l2cap_sm_their_pair_rand(proc), cmd->value, 16);
 
     /* Generate the key. */
     rc = ble_l2cap_sm_gen_key(proc);
@@ -677,8 +697,8 @@ ble_l2cap_sm_confirm_go(struct ble_l2cap_sm_proc *proc)
         return rc;
     }
 
-    rc = ble_l2cap_sm_alg_c1(k, proc->rand_our, preq, pres, iat, rat,
-                             ia, ra, cmd.value);
+    rc = ble_l2cap_sm_alg_c1(k, ble_l2cap_sm_our_pair_rand(proc), preq, pres,
+                             iat, rat, ia, ra, cmd.value);
     if (rc != 0) {
         return rc;
     }
@@ -764,7 +784,7 @@ ble_l2cap_sm_pair_go(struct ble_l2cap_sm_proc *proc)
         proc->pair_rsp = cmd;
     }
 
-    rc = ble_l2cap_sm_gen_pair_rand(proc->rand_our);
+    rc = ble_l2cap_sm_gen_pair_rand(ble_l2cap_sm_our_pair_rand(proc));
     if (rc != 0) {
         return rc;
     }


[23/50] [abbrv] incubator-mynewt-core git commit: ble host - clarify locking restrictions.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_l2cap_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.c b/net/nimble/host/src/ble_l2cap_sm.c
index 99f7d64..2460048 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -17,6 +17,31 @@
  * under the License.
  */
 
+/**
+ * L2CAP Security Manager (channel ID = 6).
+ *
+ * Design overview:
+ *
+ * L2CAP sm procedures are initiated by the application via function calls.
+ * Such functions return when either of the following happens:
+ *
+ * (1) The procedure completes (success or failure).
+ * (2) The procedure cannot proceed until a BLE peer responds.
+ *
+ * For (1), the result of the procedure if fully indicated by the function
+ * return code.
+ * For (2), the procedure result is indicated by an application-configured
+ * callback.  The callback is executed when the procedure completes.
+ *
+ * Notes on thread-safety:
+ * 1. The ble_hs mutex must never be locked when an application callback is
+ *    executed.  A callback is free to initiate additional host procedures.
+ * 2. The only resource protected by the mutex is the list of active procedures
+ *    (ble_l2cap_sm_procs).  Thread-safety is achieved by locking the mutex
+ *    during removal and insertion operations.  Procedure objects are only
+ *    modified while they are not in the list.
+ */
+
 #include <string.h>
 #include <errno.h>
 #include "console/console.h"
@@ -245,9 +270,6 @@ ble_l2cap_sm_proc_set_timer(struct ble_l2cap_sm_proc *proc)
     proc->exp_os_ticks = os_time_get() + BLE_L2CAP_SM_TIMEOUT_OS_TICKS;
 }
 
-/**
- * Lock restrictions: None.
- */
 static ble_l2cap_sm_rx_fn *
 ble_l2cap_sm_dispatch_get(uint8_t state)
 {
@@ -261,8 +283,6 @@ ble_l2cap_sm_dispatch_get(uint8_t state)
 /**
  * Allocates a proc entry.
  *
- * Lock restrictions: None.
- *
  * @return                      An entry on success; null on failure.
  */
 static struct ble_l2cap_sm_proc *
@@ -280,8 +300,6 @@ ble_l2cap_sm_proc_alloc(void)
 
 /**
  * Frees the specified proc entry.  No-state if passed a null pointer.
- *
- * Lock restrictions: None.
  */
 static void
 ble_l2cap_sm_proc_free(struct ble_l2cap_sm_proc *proc)
@@ -644,6 +662,8 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
 {
     struct ble_hs_conn *conn;
 
+    ble_hs_lock();
+
     conn = ble_hs_conn_find(proc->conn_handle);
     if (conn != NULL) {
         if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
@@ -661,6 +681,8 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
         }
     }
 
+    ble_hs_unlock();
+
     if (conn == NULL) {
         return BLE_HS_ENOTCONN;
     }
@@ -1047,10 +1069,6 @@ ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
     ble_l2cap_sm_proc_free(proc);
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_l2cap_sm_rx(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -1136,9 +1154,6 @@ ble_l2cap_sm_initiate(uint16_t conn_handle)
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 struct ble_l2cap_chan *
 ble_l2cap_sm_create_chan(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 e95e567..8e370fb 100644
--- a/net/nimble/host/src/test/ble_os_test.c
+++ b/net/nimble/host/src/test/ble_os_test.c
@@ -76,6 +76,24 @@ ble_os_test_misc_init(void)
 }
 
 static int
+ble_os_test_misc_conn_exists(uint16_t conn_handle)
+{
+    struct ble_hs_conn *conn;
+
+    ble_hs_lock();
+
+    if (conn_handle == BLE_HS_CONN_HANDLE_NONE) {
+        conn = ble_hs_conn_first();
+    } else {
+        conn = ble_hs_conn_find(conn_handle);
+    }
+
+    ble_hs_unlock();
+
+    return conn != NULL;
+}
+
+static int
 ble_gap_direct_connect_test_connect_cb(int event, int status,
                                        struct ble_gap_conn_ctxt *ctxt,
                                        void *arg)
@@ -110,13 +128,13 @@ ble_gap_direct_connect_test_task_handler(void *arg)
     /* Make sure there are no created connections and no connections in
      * progress.
      */
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
 
     /* Initiate a direct connection. */
     ble_hs_test_util_conn_initiate(0, addr, NULL,
                                    ble_gap_direct_connect_test_connect_cb,
                                    &cb_called, 0);
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(!cb_called);
 
     /* Receive an HCI connection-complete event. */
@@ -129,7 +147,7 @@ ble_gap_direct_connect_test_task_handler(void *arg)
     TEST_ASSERT(rc == 0);
 
     /* The connection should now be created. */
-    TEST_ASSERT(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT(ble_os_test_misc_conn_exists(2));
     TEST_ASSERT(cb_called);
 
     tu_restart();
@@ -180,7 +198,7 @@ ble_gap_gen_disc_test_task_handler(void *arg)
     /* Make sure there are no created connections and no connections in
      * progress.
      */
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(!ble_gap_master_in_progress());
 
     /* Initiate the general discovery procedure with a 200 ms timeout. */
@@ -190,18 +208,18 @@ ble_gap_gen_disc_test_task_handler(void *arg)
                                ble_gap_gen_disc_test_connect_cb,
                                &cb_called, 0, 0);
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(ble_gap_master_in_progress());
     TEST_ASSERT(!cb_called);
 
     /* Receive acks from the controller. */
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(ble_gap_master_in_progress());
     TEST_ASSERT(!cb_called);
 
     /* Wait 100 ms; verify scan still in progress. */
     os_time_delay(100 * OS_TICKS_PER_SEC / 1000);
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(ble_gap_master_in_progress());
     TEST_ASSERT(!cb_called);
 
@@ -211,7 +229,7 @@ ble_gap_gen_disc_test_task_handler(void *arg)
 
     /* Wait 250 more ms; verify scan completed. */
     os_time_delay(250 * OS_TICKS_PER_SEC / 1000);
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(cb_called);
 
@@ -272,7 +290,7 @@ ble_gap_terminate_test_task_handler(void *arg)
     /* Make sure there are no created connections and no connections in
      * progress.
      */
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(!ble_gap_master_in_progress());
 
     /* Create two direct connections. */
@@ -296,8 +314,8 @@ ble_gap_terminate_test_task_handler(void *arg)
     rc = ble_gap_rx_conn_complete(&conn_evt);
     TEST_ASSERT(rc == 0);
 
-    TEST_ASSERT_FATAL(ble_hs_conn_find(1) != NULL);
-    TEST_ASSERT_FATAL(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT_FATAL(ble_os_test_misc_conn_exists(1));
+    TEST_ASSERT_FATAL(ble_os_test_misc_conn_exists(2));
 
     /* Terminate the first one. */
     rc = ble_hs_test_util_conn_terminate(1, 0);
@@ -307,8 +325,8 @@ ble_gap_terminate_test_task_handler(void *arg)
     disconn_evt.reason = BLE_ERR_REM_USER_CONN_TERM;
     ble_gap_rx_disconn_complete(&disconn_evt);
     TEST_ASSERT(disconn_handle == 1);
-    TEST_ASSERT(ble_hs_conn_find(1) == NULL);
-    TEST_ASSERT(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT_FATAL(!ble_os_test_misc_conn_exists(1));
+    TEST_ASSERT_FATAL(ble_os_test_misc_conn_exists(2));
 
     /* Terminate the second one. */
     rc = ble_hs_test_util_conn_terminate(2, 0);
@@ -318,8 +336,8 @@ ble_gap_terminate_test_task_handler(void *arg)
     disconn_evt.reason = BLE_ERR_REM_USER_CONN_TERM;
     ble_gap_rx_disconn_complete(&disconn_evt);
     TEST_ASSERT(disconn_handle == 2);
-    TEST_ASSERT(ble_hs_conn_find(1) == NULL);
-    TEST_ASSERT(ble_hs_conn_find(2) == NULL);
+    TEST_ASSERT_FATAL(!ble_os_test_misc_conn_exists(1));
+    TEST_ASSERT_FATAL(!ble_os_test_misc_conn_exists(2));
 
     tu_restart();
 }


[47/50] [abbrv] incubator-mynewt-core git commit: MYNEWT-75 NFFS - Garbage collect on OOM.

Posted by ma...@apache.org.
MYNEWT-75 NFFS - Garbage collect on OOM.


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

Branch: refs/heads/master
Commit: 0970df86c887e2ad1d9cd3984ea9c2b3091d6fba
Parents: c12dbb9
Author: Christopher Collins <cc...@apache.org>
Authored: Fri Apr 22 21:12:19 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Apr 26 16:35:52 2016 -0700

----------------------------------------------------------------------
 fs/nffs/src/nffs_block.c              | 31 ++++++++++--
 fs/nffs/src/nffs_file.c               |  5 +-
 fs/nffs/src/nffs_inode.c              | 25 ++++++++++
 fs/nffs/src/nffs_misc.c               | 72 +++++++++++++++++++++++++++-
 fs/nffs/src/nffs_priv.h               |  3 ++
 fs/nffs/src/nffs_write.c              |  2 +-
 fs/nffs/src/test/arch/sim/nffs_test.c | 75 ++++++++++++++++++++++++++++--
 7 files changed, 202 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0970df86/fs/nffs/src/nffs_block.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_block.c b/fs/nffs/src/nffs_block.c
index 2186444..126a58c 100644
--- a/fs/nffs/src/nffs_block.c
+++ b/fs/nffs/src/nffs_block.c
@@ -39,10 +39,35 @@ nffs_block_entry_alloc(void)
 }
 
 void
-nffs_block_entry_free(struct nffs_hash_entry *entry)
+nffs_block_entry_free(struct nffs_hash_entry *block_entry)
 {
-    assert(nffs_hash_id_is_block(entry->nhe_id));
-    os_memblock_put(&nffs_block_entry_pool, entry);
+    assert(nffs_hash_id_is_block(block_entry->nhe_id));
+    os_memblock_put(&nffs_block_entry_pool, block_entry);
+}
+
+/**
+ * Allocates a block entry.  If allocation fails due to memory exhaustion,
+ * garbage collection is performed and the allocation is retried.  This
+ * process is repeated until allocation is successful or all areas have been
+ * garbage collected.
+ *
+ * @param out_block_entry           On success, the address of the allocated
+ *                                      block gets written here.
+ *
+ * @return                          0 on successful allocation;
+ *                                  FS_ENOMEM on memory exhaustion;
+ *                                  other nonzero on garbage collection error.
+ */
+int
+nffs_block_entry_reserve(struct nffs_hash_entry **out_block_entry)
+{
+    int rc;
+
+    do {
+        *out_block_entry = nffs_block_entry_alloc();
+    } while (nffs_misc_gc_if_oom(*out_block_entry, &rc));
+
+    return rc;
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0970df86/fs/nffs/src/nffs_file.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_file.c b/fs/nffs/src/nffs_file.c
index 40741df..6745df7 100644
--- a/fs/nffs/src/nffs_file.c
+++ b/fs/nffs/src/nffs_file.c
@@ -75,9 +75,8 @@ nffs_file_new(struct nffs_inode_entry *parent, const char *filename,
     uint8_t area_idx;
     int rc;
 
-    inode_entry = nffs_inode_entry_alloc();
-    if (inode_entry == NULL) {
-        rc = FS_ENOMEM;
+    rc = nffs_inode_entry_reserve(&inode_entry);
+    if (rc != 0) {
         goto err;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0970df86/fs/nffs/src/nffs_inode.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_inode.c b/fs/nffs/src/nffs_inode.c
index ffef547..5beb87d 100644
--- a/fs/nffs/src/nffs_inode.c
+++ b/fs/nffs/src/nffs_inode.c
@@ -59,6 +59,31 @@ nffs_inode_entry_free(struct nffs_inode_entry *inode_entry)
     }
 }
 
+/**
+ * Allocates a inode entry.  If allocation fails due to memory exhaustion,
+ * garbage collection is performed and the allocation is retried.  This
+ * process is repeated until allocation is successful or all areas have been
+ * garbage collected.
+ *
+ * @param out_inode_entry           On success, the address of the allocated
+ *                                      inode gets written here.
+ *
+ * @return                          0 on successful allocation;
+ *                                  FS_ENOMEM on memory exhaustion;
+ *                                  other nonzero on garbage collection error.
+ */
+int
+nffs_inode_entry_reserve(struct nffs_inode_entry **out_inode_entry)
+{
+    int rc;
+
+    do {
+        *out_inode_entry = nffs_inode_entry_alloc();
+    } while (nffs_misc_gc_if_oom(*out_inode_entry, &rc));
+
+    return rc;
+}
+
 uint32_t
 nffs_inode_disk_size(const struct nffs_inode *inode)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0970df86/fs/nffs/src/nffs_misc.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_misc.c b/fs/nffs/src/nffs_misc.c
index e3e1dc7..8dbff0a 100644
--- a/fs/nffs/src/nffs_misc.c
+++ b/fs/nffs/src/nffs_misc.c
@@ -6,7 +6,7 @@
  * 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,
@@ -90,6 +90,76 @@ nffs_misc_validate_scratch(void)
 }
 
 /**
+ * Performs a garbage cycle to free up memory, if necessary.  This function
+ * should be called repeatedly until either:
+ *   o The subsequent allocation is successful, or
+ *   o Garbage collection is not successfully performed (indicated by a return
+ *     code other than FS_EAGAIN).
+ *
+ * This function determines if garbage collection is necessary by inspecting
+ * the value of the supplied "resource" parameter.  If resource is null, that
+ * implies that allocation failed.
+ *
+ * This function will not initiate garbage collection if all areas have already
+ * been collected in an attempt to free memory for the allocation in question.
+ *
+ * @param resource              The result of the allocation attempt; null
+ *                                  implies that garbage collection is
+ *                                  necessary.
+ * @param out_rc                The status of this operation gets written here.
+ *                                   0: garbage collection was successful or
+ *                                       unnecessary.
+ *                                   FS_EFULL: Garbage collection was not
+ *                                       performed because all areas have
+ *                                       already been collected.
+ *                                   Other nonzero: garbage collection failed.
+ *
+ * @return                      FS_EAGAIN if garbage collection was
+ *                                  successfully performed and the allocation
+ *                                  should be retried;
+ *                              Other value if the allocation should not be
+ *                                  retried; the value of the out_rc parameter
+ *                                  indicates whether allocation was successful
+ *                                  or there was an error.
+ */
+int
+nffs_misc_gc_if_oom(void *resource, int *out_rc)
+{
+    /**
+     * Keeps track of the number of repeated garbage collection cycles.
+     * Necessary for ensuring GC stops after all areas have been collected.
+     */
+    static uint8_t total_gc_cycles;
+
+    if (resource != NULL) {
+        /* Allocation succeeded.  Reset cycle count in preparation for the next
+         * allocation failure.
+         */
+        total_gc_cycles = 0;
+        *out_rc = 0;
+        return 0;
+    }
+
+    /* If every area has already been garbage collected, there is nothing else
+     * that can be done ("- 1" to account for the scratch area).
+     */
+    if (total_gc_cycles >= nffs_num_areas - 1) {
+        *out_rc = FS_ENOMEM;
+        return 0;
+    }
+
+    /* Attempt a garbage collection on the next area. */
+    *out_rc = nffs_gc(NULL);
+    total_gc_cycles++;
+    if (*out_rc != 0) {
+        return 0;
+    }
+
+    /* Indicate that garbage collection was successfully performed. */
+    return 1;
+}
+
+/**
  * Reserves the specified number of bytes within the specified area.
  *
  * @param area_idx              The index of the area to reserve from.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0970df86/fs/nffs/src/nffs_priv.h
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_priv.h b/fs/nffs/src/nffs_priv.h
index 49b72ea..2168289 100644
--- a/fs/nffs/src/nffs_priv.h
+++ b/fs/nffs/src/nffs_priv.h
@@ -254,6 +254,7 @@ int nffs_area_find_corrupt_scratch(uint16_t *out_good_idx,
 /* @block */
 struct nffs_hash_entry *nffs_block_entry_alloc(void);
 void nffs_block_entry_free(struct nffs_hash_entry *entry);
+int nffs_block_entry_reserve(struct nffs_hash_entry **out_block_entry);
 int nffs_block_read_disk(uint8_t area_idx, uint32_t area_offset,
                          struct nffs_disk_block *out_disk_block);
 int nffs_block_write_disk(const struct nffs_disk_block *disk_block,
@@ -355,6 +356,7 @@ int nffs_hash_init(void);
 /* @inode */
 struct nffs_inode_entry *nffs_inode_entry_alloc(void);
 void nffs_inode_entry_free(struct nffs_inode_entry *inode_entry);
+int nffs_inode_entry_reserve(struct nffs_inode_entry **out_inode_entry);
 int nffs_inode_calc_data_length(struct nffs_inode_entry *inode_entry,
                                 uint32_t *out_len);
 int nffs_inode_data_len(struct nffs_inode_entry *inode_entry,
@@ -401,6 +403,7 @@ int nffs_inode_unlink_from_ram_corrupt_ok(struct nffs_inode *inode,
 int nffs_inode_unlink(struct nffs_inode *inode);
 
 /* @misc */
+int nffs_misc_gc_if_oom(void *resource, int *out_rc);
 int nffs_misc_reserve_space(uint16_t space,
                             uint8_t *out_area_idx, uint32_t *out_area_offset);
 int nffs_misc_set_num_areas(uint8_t num_areas);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0970df86/fs/nffs/src/nffs_write.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_write.c b/fs/nffs/src/nffs_write.c
index 8888016..95927cd 100644
--- a/fs/nffs/src/nffs_write.c
+++ b/fs/nffs/src/nffs_write.c
@@ -219,7 +219,7 @@ nffs_write_append(struct nffs_cache_inode *cache_inode, const void *data,
     uint8_t area_idx;
     int rc;
 
-    entry = nffs_block_entry_alloc();
+    rc = nffs_block_entry_reserve(&entry);
     if (entry == NULL) {
         return FS_ENOMEM;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0970df86/fs/nffs/src/test/arch/sim/nffs_test.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/test/arch/sim/nffs_test.c b/fs/nffs/src/test/arch/sim/nffs_test.c
index 8078ea0..bf97ef8 100644
--- a/fs/nffs/src/test/arch/sim/nffs_test.c
+++ b/fs/nffs/src/test/arch/sim/nffs_test.c
@@ -269,7 +269,7 @@ nffs_test_util_create_file_blocks(const char *filename,
 
 static void
 nffs_test_util_create_file(const char *filename, const char *contents,
-                          int contents_len)
+                           int contents_len)
 {
     struct nffs_test_block_desc block;
 
@@ -281,7 +281,7 @@ nffs_test_util_create_file(const char *filename, const char *contents,
 
 static void
 nffs_test_util_append_file(const char *filename, const char *contents,
-                          int contents_len)
+                           int contents_len)
 {
     struct fs_file *file;
     int rc;
@@ -298,7 +298,7 @@ nffs_test_util_append_file(const char *filename, const char *contents,
 
 static void
 nffs_test_copy_area(const struct nffs_area_desc *from,
-                   const struct nffs_area_desc *to)
+                    const struct nffs_area_desc *to)
 {
     void *buf;
     int rc;
@@ -2495,6 +2495,74 @@ TEST_CASE(nffs_test_split_file)
     nffs_test_assert_system(expected_system, area_descs_two);
 }
 
+TEST_CASE(nffs_test_gc_on_oom)
+{
+    int rc;
+
+    /*** Setup. */
+    /* Ensure all areas are the same size. */
+    static const struct nffs_area_desc area_descs_two[] = {
+            { 0x00000000, 16 * 1024 },
+            { 0x00004000, 16 * 1024 },
+            { 0x00008000, 16 * 1024 },
+            { 0, 0 },
+    };
+
+    rc = nffs_format(area_descs_two);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    /* Leak block entries until only four are left. */
+    /* XXX: This is ridiculous.  Need to fix nffs configuration so that the
+     * caller passes a config object rather than writing to a global variable.
+     */
+    while (nffs_block_entry_pool.mp_num_free != 4) {
+        nffs_block_entry_alloc();
+    }
+
+    /*** Write 4 data blocks. */
+    struct nffs_test_block_desc blocks[4] = { {
+        .data = "1",
+        .data_len = 1,
+    }, {
+        .data = "2",
+        .data_len = 1,
+    }, {
+        .data = "3",
+        .data_len = 1,
+    }, {
+        .data = "4",
+        .data_len = 1,
+    } };
+
+    nffs_test_util_create_file_blocks("/myfile.txt", blocks, 4);
+
+    TEST_ASSERT_FATAL(nffs_block_entry_pool.mp_num_free == 0);
+
+    /* Attempt another one-byte write.  This should trigger a garbage
+     * collection cycle, resulting in the four blocks being collated.  The
+     * fifth write consumes an additional block, resulting in 2 out of 4 blocks
+     * in use.
+     */
+    nffs_test_util_append_file("/myfile.txt", "5", 1);
+
+    TEST_ASSERT_FATAL(nffs_block_entry_pool.mp_num_free == 2);
+
+    struct nffs_test_file_desc *expected_system =
+        (struct nffs_test_file_desc[]) { {
+            .filename = "",
+            .is_dir = 1,
+            .children = (struct nffs_test_file_desc[]) { {
+                .filename = "myfile.txt",
+                .contents = "12345",
+                .contents_len = 5,
+            }, {
+                .filename = NULL,
+            } },
+    } };
+
+    nffs_test_assert_system(expected_system, area_descs_two);
+}
+
 TEST_SUITE(nffs_suite_cache)
 {
     int rc;
@@ -2541,6 +2609,7 @@ nffs_test_gen(void)
     nffs_test_lost_found();
     nffs_test_readdir();
     nffs_test_split_file();
+    nffs_test_gc_on_oom();
 }
 
 TEST_SUITE(gen_1_1)


[05/50] [abbrv] incubator-mynewt-core git commit: nffs - Only build logging code if LOG_LEVEL is low enough.

Posted by ma...@apache.org.
nffs - Only build logging code if LOG_LEVEL is low enough.


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

Branch: refs/heads/master
Commit: 1a6f234c6a3e99e4c84d6cb80b13e6bf9d3aff43
Parents: 2f430d3
Author: Christopher Collins <cc...@apache.org>
Authored: Tue Apr 19 14:19:19 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Apr 19 14:32:23 2016 -0700

----------------------------------------------------------------------
 fs/nffs/src/nffs_priv.h               | 4 ++--
 fs/nffs/src/nffs_restore.c            | 9 +++++----
 fs/nffs/src/test/arch/sim/nffs_test.c | 1 -
 3 files changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a6f234c/fs/nffs/src/nffs_priv.h
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_priv.h b/fs/nffs/src/nffs_priv.h
index a83256d..3670251 100644
--- a/fs/nffs/src/nffs_priv.h
+++ b/fs/nffs/src/nffs_priv.h
@@ -431,8 +431,8 @@ int nffs_restore_full(const struct nffs_area_desc *area_descs);
 int nffs_write_to_file(struct nffs_file *file, const void *data, int len);
 
 
-#define NFFS_HASH_FOREACH(entry, i)                                      \
-    for ((i) = 0; (i) < NFFS_HASH_SIZE; (i)++)                 \
+#define NFFS_HASH_FOREACH(entry, i)                                     \
+    for ((i) = 0; (i) < NFFS_HASH_SIZE; (i)++)                          \
         SLIST_FOREACH((entry), &nffs_hash[i], nhe_next)
 
 #define NFFS_FLASH_LOC_NONE  nffs_flash_loc(NFFS_AREA_ID_NONE, 0)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a6f234c/fs/nffs/src/nffs_restore.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_restore.c b/fs/nffs/src/nffs_restore.c
index 8f9c9f8..28ea39a 100644
--- a/fs/nffs/src/nffs_restore.c
+++ b/fs/nffs/src/nffs_restore.c
@@ -975,10 +975,13 @@ nffs_restore_corrupt_scratch(void)
     return 0;
 }
 
-#ifdef notnow
 static void
 nffs_log_contents(void)
 {
+#if LOG_LEVEL > LOG_LEVEL_DEBUG
+    return;
+#endif
+
     struct nffs_inode_entry *inode_entry;
     struct nffs_hash_entry *entry;
     struct nffs_block block;
@@ -1030,7 +1033,6 @@ nffs_log_contents(void)
         }
     }
 }
-#endif
 
 /**
  * Searches for a valid nffs file system among the specified areas.  This
@@ -1168,10 +1170,9 @@ nffs_restore_full(const struct nffs_area_desc *area_descs)
         goto err;
     }
 
-#ifdef notnow
     NFFS_LOG(DEBUG, "CONTENTS\n");
     nffs_log_contents();
-#endif
+
     return 0;
 
 err:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1a6f234c/fs/nffs/src/test/arch/sim/nffs_test.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/test/arch/sim/nffs_test.c b/fs/nffs/src/test/arch/sim/nffs_test.c
index 42a7623..8b3b03a 100644
--- a/fs/nffs/src/test/arch/sim/nffs_test.c
+++ b/fs/nffs/src/test/arch/sim/nffs_test.c
@@ -2505,7 +2505,6 @@ int
 main(void)
 {
     tu_config.tc_print_results = 1;
-    tu_config.tc_system_assert = 1;
     tu_init();
 
     nffs_test_all();


[32/50] [abbrv] incubator-mynewt-core git commit: console; don't call os_time_delay() when OS is not running. This was asserting when there was a lot of output to console before OS starts.

Posted by ma...@apache.org.
console; don't call os_time_delay() when OS is not running.
This was asserting when there was a lot of output to console before
OS starts.


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

Branch: refs/heads/master
Commit: 75d32205598f9e10037f6ce3feacdcf3e9a91c42
Parents: 0892fd9
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Thu Apr 21 11:04:53 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Thu Apr 21 11:04:53 2016 -0700

----------------------------------------------------------------------
 libs/console/full/src/cons_tty.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/75d32205/libs/console/full/src/cons_tty.c
----------------------------------------------------------------------
diff --git a/libs/console/full/src/cons_tty.c b/libs/console/full/src/cons_tty.c
index d43f4b9..b7320be 100644
--- a/libs/console/full/src/cons_tty.c
+++ b/libs/console/full/src/cons_tty.c
@@ -102,7 +102,9 @@ console_queue_char(char ch)
         /* TX needs to drain */
         hal_uart_start_tx(CONSOLE_UART);
         OS_EXIT_CRITICAL(sr);
-        os_time_delay(1);
+	if (g_os_started) {
+            os_time_delay(1);
+	}
         OS_ENTER_CRITICAL(sr);
     }
     console_add_char(&ct->ct_tx, ch);


[08/50] [abbrv] incubator-mynewt-core git commit: ble host - major changes.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 85b630f..7da3d3f 100644
--- a/net/nimble/host/src/test/ble_gap_test.c
+++ b/net/nimble/host/src/test/ble_gap_test.c
@@ -110,27 +110,6 @@ ble_gap_test_util_connect_cb(int event, int status,
     return 0;
 }
 
-static int
-ble_gap_test_util_rx_hci_ack(int *cmd_idx, int cmd_fail_idx,
-                             uint8_t ogf, uint16_t ocf, uint8_t fail_status)
-{
-    uint16_t opcode;
-    int cur_idx;
-
-    opcode = (ogf << 10) | ocf;
-
-    cur_idx = *cmd_idx;
-    (*cmd_idx)++;
-
-    if (cur_idx == cmd_fail_idx) {
-        ble_hs_test_util_rx_ack(opcode, fail_status);
-        return 1;
-    } else {
-        ble_hs_test_util_rx_ack(opcode, 0);
-        return 0;
-    }
-}
-
 static void
 ble_gap_test_util_verify_tx_clear_wl(void)
 {
@@ -364,10 +343,14 @@ ble_gap_test_util_rx_update_complete(
     ble_gap_rx_update_complete(&evt);
 }
 
-static void
-ble_gap_test_util_rx_param_req(struct ble_gap_upd_params *params)
+static int
+ble_gap_test_util_rx_param_req(struct ble_gap_upd_params *params, int pos,
+                               int *cmd_idx, int cmd_fail_idx,
+                               uint8_t fail_status)
 {
     struct hci_le_conn_param_req evt;
+    uint16_t opcode;
+    uint8_t hci_status;
 
     evt.subevent_code = BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ;
     evt.connection_handle = 2;
@@ -375,8 +358,25 @@ ble_gap_test_util_rx_param_req(struct ble_gap_upd_params *params)
     evt.itvl_max = params->itvl_max;
     evt.latency = params->latency;
     evt.timeout = params->supervision_timeout;
+ 
+    if (pos) {
+        opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_REM_CONN_PARAM_RR);
+    } else {
+        opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                      BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR);
+    }
+    if (*cmd_idx == cmd_fail_idx) {
+        hci_status = fail_status;
+    } else {
+        hci_status = 0;
+    }
+    (*cmd_idx)++;
 
+    ble_hs_test_util_set_ack(opcode, hci_status);
     ble_gap_rx_param_req(&evt);
+
+    return hci_status;
 }
 
 /*****************************************************************************
@@ -521,7 +521,6 @@ ble_gap_test_util_disc(uint8_t disc_mode, uint8_t *peer_addr,
 
     if (cmd_fail_idx > 1) {
         /* Verify tx of scan enable command. */
-        ble_hci_sched_wakeup();
         ble_gap_test_util_verify_tx_scan_enable(1);
     }
 
@@ -576,7 +575,15 @@ TEST_CASE(ble_gap_test_case_conn_disc_good)
         ble_gap_test_util_disc(d, peer_addr, &adv, -1, 0);
 
         TEST_ASSERT(ble_gap_master_in_progress());
-        TEST_ASSERT(ble_gap_test_disc_event == -1);
+        TEST_ASSERT(ble_gap_test_disc_event == BLE_GAP_EVENT_DISC_SUCCESS);
+        TEST_ASSERT(ble_gap_test_disc_status == 0);
+        TEST_ASSERT(ble_gap_test_disc_desc.event_type ==
+                    BLE_HCI_ADV_TYPE_ADV_IND);
+        TEST_ASSERT(ble_gap_test_disc_desc.addr_type == BLE_ADDR_TYPE_PUBLIC);
+        TEST_ASSERT(ble_gap_test_disc_desc.length_data == 3);
+        TEST_ASSERT(ble_gap_test_disc_desc.rssi == 0);
+        TEST_ASSERT(memcmp(ble_gap_test_disc_desc.addr, adv.addr, 6) == 0);
+        TEST_ASSERT(ble_gap_test_disc_arg == NULL);
     }
 }
 
@@ -706,51 +713,10 @@ TEST_CASE(ble_gap_test_case_conn_dir_bad_args)
     TEST_ASSERT(rc == BLE_HS_EALREADY);
 }
 
-TEST_CASE(ble_gap_test_case_conn_dir_bad_addr)
-{
-    struct hci_le_conn_complete evt;
-    int rc;
-
-    uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
-
-    ble_gap_test_util_init();
-
-    TEST_ASSERT(!ble_gap_master_in_progress());
-
-    rc = ble_hs_test_util_conn_initiate(BLE_ADDR_TYPE_PUBLIC, peer_addr, NULL,
-                                        ble_gap_test_util_connect_cb, NULL, 0);
-    TEST_ASSERT(rc == 0);
-
-    TEST_ASSERT(ble_gap_master_in_progress());
-
-    /* Verify tx of create connection command. */
-    ble_gap_test_util_verify_tx_create_conn(BLE_HCI_CONN_FILT_NO_WL);
-    TEST_ASSERT(ble_gap_master_in_progress());
-    TEST_ASSERT(ble_hs_conn_find(2) == NULL);
-
-    /* Receive connection complete event. */
-    memset(&evt, 0, sizeof evt);
-    evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
-    evt.status = BLE_ERR_SUCCESS;
-    evt.connection_handle = 2;
-    evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
-    memcpy(evt.peer_addr, ((uint8_t[]){1,1,1,1,1,1}), 6);
-    rc = ble_gap_rx_conn_complete(&evt);
-    TEST_ASSERT(rc == BLE_HS_ECONTROLLER);
-
-    TEST_ASSERT(!ble_gap_master_in_progress());
-
-    TEST_ASSERT(ble_gap_test_conn_event == BLE_GAP_EVENT_CONN);
-    TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == BLE_HS_CONN_HANDLE_NONE);
-
-    TEST_ASSERT(ble_hs_conn_find(2) == NULL);
-}
-
 TEST_SUITE(ble_gap_test_suite_conn_dir)
 {
     ble_gap_test_case_conn_dir_good();
     ble_gap_test_case_conn_dir_bad_args();
-    ble_gap_test_case_conn_dir_bad_addr();
 }
 
 /*****************************************************************************
@@ -1232,7 +1198,6 @@ ble_gap_test_util_stop_adv(uint8_t disc_mode, uint8_t conn_mode,
     TEST_ASSERT(rc == BLE_HS_HCI_ERR(hci_status));
 
     /* Verify tx of advertising enable command. */
-    ble_hci_sched_wakeup();
     ble_gap_test_util_verify_tx_adv_enable(0);
 }
 
@@ -1334,7 +1299,7 @@ ble_gap_test_util_update(struct ble_gap_upd_params *params,
     TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
         params->supervision_timeout);
 
-    TEST_ASSERT(!ble_gap_update_in_progress(BLE_HS_CONN_HANDLE_NONE));
+    TEST_ASSERT(!ble_gap_update_in_progress(2));
 
     return;
 
@@ -1349,7 +1314,7 @@ fail:
                 BLE_GAP_INITIAL_CONN_LATENCY);
     TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
                 BLE_GAP_INITIAL_SUPERVISION_TIMEOUT);
-    TEST_ASSERT(!ble_gap_update_in_progress(BLE_HS_CONN_HANDLE_NONE));
+    TEST_ASSERT(!ble_gap_update_in_progress(2));
 }
 
 static void
@@ -1405,19 +1370,16 @@ ble_gap_test_util_update_req_pos(struct ble_gap_upd_params *peer_params,
     TEST_ASSERT(!ble_gap_master_in_progress());
 
     ble_gap_test_conn_self_params = *self_params;
-    ble_gap_test_util_rx_param_req(peer_params);
+    rc = ble_gap_test_util_rx_param_req(peer_params, 1, &cmd_idx, cmd_fail_idx,
+                                        hci_status);
+    if (rc != 0) {
+        goto hci_fail;
+    }
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_gap_update_in_progress(BLE_HS_CONN_HANDLE_NONE));
+    TEST_ASSERT(ble_gap_update_in_progress(2));
 
     /* Verify tx of connection parameters reply command. */
-    ble_hci_sched_wakeup();
     ble_gap_test_util_verify_tx_params_reply_pos();
-    rc = ble_gap_test_util_rx_hci_ack(&cmd_idx, cmd_fail_idx, BLE_HCI_OGF_LE,
-                                      BLE_HCI_OCF_LE_REM_CONN_PARAM_RR,
-                                      hci_status);
-    if (rc != 0) {
-        goto hci_fail;
-    }
 
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(ble_gap_update_in_progress(2));
@@ -1426,7 +1388,7 @@ ble_gap_test_util_update_req_pos(struct ble_gap_upd_params *peer_params,
     ble_gap_test_util_rx_update_complete(0, self_params);
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(BLE_HS_CONN_HANDLE_NONE));
+    TEST_ASSERT(!ble_gap_update_in_progress(2));
 
     TEST_ASSERT(ble_gap_test_conn_event == BLE_GAP_EVENT_CONN_UPDATED);
     TEST_ASSERT(ble_gap_test_conn_status == 0);
@@ -1470,24 +1432,21 @@ ble_gap_test_util_update_req_neg(struct ble_gap_upd_params *peer_params,
                                  &reason);
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(BLE_HS_CONN_HANDLE_NONE));
+    TEST_ASSERT(!ble_gap_update_in_progress(2));
 
-    ble_gap_test_util_rx_param_req(peer_params);
+    rc = ble_gap_test_util_rx_param_req(peer_params, 0, &cmd_idx, cmd_fail_idx,
+                                        hci_status);
+    if (rc != 0) {
+        goto hci_fail;
+    }
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_update_in_progress(2));
 
     /* Verify tx of connection parameters negative reply command. */
-    ble_hci_sched_wakeup();
     ble_gap_test_util_verify_tx_params_reply_neg(reason);
-    rc = ble_gap_test_util_rx_hci_ack(&cmd_idx, cmd_fail_idx, BLE_HCI_OGF_LE,
-                                      BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR,
-                                      hci_status);
-    if (rc != 0) {
-        goto hci_fail;
-    }
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(BLE_HS_CONN_HANDLE_NONE));
+    TEST_ASSERT(!ble_gap_update_in_progress(2));
 
     return;
 
@@ -1524,7 +1483,7 @@ ble_gap_test_util_update_req_concurrent(
                                  NULL);
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(BLE_HS_CONN_HANDLE_NONE));
+    TEST_ASSERT(!ble_gap_update_in_progress(2));
 
     hci_status = cmd_fail_idx == 0 ? fail_status : 0;
     rc = ble_hs_test_util_conn_update(2, init_params, hci_status);
@@ -1547,20 +1506,16 @@ ble_gap_test_util_update_req_concurrent(
 
     /* Receive connection parameter update request from peer. */
     ble_gap_test_conn_self_params = *self_params;
-    ble_gap_test_util_rx_param_req(peer_params);
+    rc = ble_gap_test_util_rx_param_req(peer_params, 1, &cmd_idx, cmd_fail_idx,
+                                        hci_status);
+    if (rc != 0) {
+        goto hci_fail;
+    }
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(ble_gap_update_in_progress(2));
 
     /* Verify tx of connection parameters reply command. */
-    ble_hci_sched_wakeup();
     ble_gap_test_util_verify_tx_params_reply_pos();
-    cmd_idx = 1;
-    rc = ble_gap_test_util_rx_hci_ack(&cmd_idx, cmd_fail_idx, BLE_HCI_OGF_LE,
-                                      BLE_HCI_OCF_LE_REM_CONN_PARAM_RR,
-                                      fail_status);
-    if (rc != 0) {
-        goto hci_fail;
-    }
 
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(ble_gap_update_in_progress(2));

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/test/ble_gatt_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_conn_test.c b/net/nimble/host/src/test/ble_gatt_conn_test.c
index 1f31122..994f719 100644
--- a/net/nimble/host/src/test/ble_gatt_conn_test.c
+++ b/net/nimble/host/src/test/ble_gatt_conn_test.c
@@ -84,9 +84,6 @@ ble_gatt_conn_test_write_cb(uint16_t conn_handle, struct ble_gatt_error *error,
     TEST_ASSERT(error->status == BLE_HS_ENOTCONN);
     TEST_ASSERT(attr != NULL);
     TEST_ASSERT(attr->handle == BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE);
-    TEST_ASSERT(attr->value_len == sizeof ble_gatt_conn_test_write_value);
-    TEST_ASSERT(memcmp(attr->value, ble_gatt_conn_test_write_value,
-                       sizeof ble_gatt_conn_test_write_value) == 0);
 
     return 0;
 }
@@ -159,6 +156,7 @@ TEST_CASE(ble_gatt_conn_test_disconnect)
     ble_gattc_connection_broken(BLE_GATT_BREAK_TEST_DISC_CHR_HANDLE);
     ble_gattc_connection_broken(BLE_GATT_BREAK_TEST_READ_HANDLE);
     ble_gattc_connection_broken(BLE_GATT_BREAK_TEST_WRITE_HANDLE);
+    /* XXX: Add remaining procedures. */
 
     TEST_ASSERT(disc_s_called == 1);
     TEST_ASSERT(disc_c_called == 1);
@@ -166,55 +164,9 @@ TEST_CASE(ble_gatt_conn_test_disconnect)
     TEST_ASSERT(write_called == 1);
 }
 
-TEST_CASE(ble_gatt_conn_test_congestion)
-{
-    struct ble_hs_conn *conn;
-    int rc;
-
-    ble_hs_test_util_init();
-
-    /* Allow only one outstanding packet per connection. */
-    ble_hs_cfg.max_outstanding_pkts_per_conn = 1;
-
-    /* Create a connection. */
-    conn = ble_hs_test_util_create_conn(1, ((uint8_t[]){1,2,3,4,5,6,7,8}),
-                                        NULL, NULL);
-
-    /* Try to send two data packets. */
-    rc = ble_gattc_write(1, 0x1234, ble_gatt_conn_test_write_value,
-                        sizeof ble_gatt_conn_test_write_value, NULL, NULL);
-    TEST_ASSERT_FATAL(rc == 0);
-
-    rc = ble_gattc_write(1, 0x1234, ble_gatt_conn_test_write_value,
-                        sizeof ble_gatt_conn_test_write_value, NULL, NULL);
-    TEST_ASSERT_FATAL(rc == 0);
-    ble_hs_test_util_tx_all();
-
-    /* Ensure only one packet got sent. */
-    TEST_ASSERT(conn->bhc_outstanding_pkts == 1);
-
-    /* Additional wakeups should not trigger the second send. */
-    ble_hs_test_util_tx_all();
-    TEST_ASSERT(conn->bhc_outstanding_pkts == 1);
-
-    /* Receive a num-packets-completed event. */
-    ble_hs_test_util_rx_num_completed_pkts_event(
-        (struct ble_hs_test_util_num_completed_pkts_entry []) {
-            { 1, 1 },
-            { 0 }});
-
-    /* Outstanding packet count should have been reduced to 0. */
-    TEST_ASSERT(conn->bhc_outstanding_pkts == 0);
-
-    /* Now the second write should get sent. */
-    ble_hs_test_util_tx_all();
-    TEST_ASSERT(conn->bhc_outstanding_pkts == 1);
-}
-
 TEST_SUITE(ble_gatt_break_suite)
 {
     ble_gatt_conn_test_disconnect();
-    ble_gatt_conn_test_congestion();
 }
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/test/ble_gatt_read_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_read_test.c b/net/nimble/host/src/test/ble_gatt_read_test.c
index 47392fb..edf7d63 100644
--- a/net/nimble/host/src/test/ble_gatt_read_test.c
+++ b/net/nimble/host/src/test/ble_gatt_read_test.c
@@ -43,9 +43,6 @@ int ble_gatt_read_test_complete;
 uint16_t ble_gatt_read_test_bad_conn_handle;
 int ble_gatt_read_test_bad_status;
 
-uint16_t ble_gatt_read_test_mult_handles[BLE_GATT_READ_TEST_MAX_ATTRS];
-uint8_t ble_gatt_read_test_mult_num_handles;
-
 static void
 ble_gatt_read_test_misc_init(void)
 {
@@ -97,6 +94,8 @@ ble_gatt_read_test_cb(uint16_t conn_handle, struct ble_gatt_error *error,
             ble_gatt_read_test_complete = 1;
             return 1;
         }
+    } else {
+        ble_gatt_read_test_complete = 1;
     }
 
     return 0;
@@ -149,46 +148,6 @@ ble_gatt_read_test_long_cb(uint16_t conn_handle, struct ble_gatt_error *error,
     return 0;
 }
 
-static int
-ble_gatt_read_test_mult_cb(uint16_t conn_handle, struct ble_gatt_error *error,
-                           uint16_t *attr_handles, uint8_t num_attr_handles,
-                           uint8_t *attr_data, uint16_t attr_data_len,
-                           void *arg)
-{
-    struct ble_gatt_read_test_attr *dst;
-    int i;
-
-    ble_gatt_read_test_mult_num_handles = num_attr_handles;
-    for (i = 0; i < num_attr_handles; i++) {
-        ble_gatt_read_test_mult_handles[i] = attr_handles[i];
-    }
-
-    if (error != NULL) {
-        ble_gatt_read_test_bad_conn_handle = conn_handle;
-        ble_gatt_read_test_bad_status = error->status;
-        ble_gatt_read_test_complete = 1;
-        return 0;
-    }
-
-    if (attr_data == NULL) {
-        ble_gatt_read_test_complete = 1;
-        return 0;
-    }
-
-    dst = ble_gatt_read_test_attrs + ble_gatt_read_test_num_attrs++;
-
-    TEST_ASSERT_FATAL(attr_data_len <= sizeof dst->value);
-
-    dst->conn_handle = conn_handle;
-    dst->handle = 0;
-    dst->value_len = attr_data_len;
-    memcpy(dst->value, attr_data, attr_data_len);
-
-    ble_gatt_read_test_complete = 1;
-
-    return 0;
-}
-
 static void
 ble_gatt_read_test_misc_rx_rsp_good_raw(struct ble_hs_conn *conn,
                                         uint8_t att_op,
@@ -500,7 +459,7 @@ ble_gatt_read_test_misc_mult_verify_good(struct ble_gatt_attr *attrs)
     }
 
     rc = ble_gattc_read_mult(conn->bhc_handle, handles, num_attrs,
-                             ble_gatt_read_test_mult_cb, NULL);
+                             ble_gatt_read_test_cb, NULL);
     TEST_ASSERT_FATAL(rc == 0);
 
     ble_gatt_read_test_misc_rx_rsp_good_raw(conn, BLE_ATT_OP_READ_MULT_RSP,
@@ -509,9 +468,6 @@ ble_gatt_read_test_misc_mult_verify_good(struct ble_gatt_attr *attrs)
     TEST_ASSERT(ble_gatt_read_test_complete);
     TEST_ASSERT(!ble_gattc_any_jobs());
     TEST_ASSERT(ble_gatt_read_test_attrs[0].conn_handle == conn->bhc_handle);
-    TEST_ASSERT(ble_gatt_read_test_mult_num_handles == num_attrs);
-    TEST_ASSERT(memcmp(ble_gatt_read_test_mult_handles, handles,
-                       num_attrs * 2) == 0);
     TEST_ASSERT(ble_gatt_read_test_attrs[0].value_len == off);
     TEST_ASSERT(memcmp(ble_gatt_read_test_attrs[0].value, expected_value,
                        off) == 0);
@@ -534,16 +490,13 @@ ble_gatt_read_test_misc_mult_verify_bad(uint8_t att_status,
     num_attrs = ble_gatt_read_test_misc_extract_handles(attrs, handles);
 
     rc = ble_gattc_read_mult(conn->bhc_handle, handles, num_attrs,
-                             ble_gatt_read_test_mult_cb, NULL);
+                             ble_gatt_read_test_cb, NULL);
     TEST_ASSERT_FATAL(rc == 0);
 
     ble_gatt_read_test_misc_rx_rsp_bad(conn, att_status, err_handle);
 
     TEST_ASSERT(ble_gatt_read_test_num_attrs == 0);
     TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == conn->bhc_handle);
-    TEST_ASSERT(ble_gatt_read_test_mult_num_handles == num_attrs);
-    TEST_ASSERT(memcmp(ble_gatt_read_test_mult_handles, handles,
-                       num_attrs * 2) == 0);
     TEST_ASSERT(ble_gatt_read_test_bad_status ==
                 BLE_HS_ERR_ATT_BASE + att_status);
     TEST_ASSERT(!ble_gattc_any_jobs());

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/test/ble_gatt_write_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_write_test.c b/net/nimble/host/src/test/ble_gatt_write_test.c
index 3c17114..b452e79 100644
--- a/net/nimble/host/src/test/ble_gatt_write_test.c
+++ b/net/nimble/host/src/test/ble_gatt_write_test.c
@@ -63,8 +63,6 @@ ble_gatt_write_test_cb_good(uint16_t conn_handle, struct ble_gatt_error *error,
     if (attr_len != NULL) {
         TEST_ASSERT(error == NULL);
         TEST_ASSERT(attr->handle == 100);
-        TEST_ASSERT(attr->value_len == *attr_len);
-        TEST_ASSERT(attr->value == ble_gatt_write_test_attr_value);
     } else {
         TEST_ASSERT(error != NULL);
         ble_gatt_write_test_error = *error;
@@ -348,15 +346,14 @@ TEST_CASE(ble_gatt_write_test_no_rsp)
 
     attr_len = 4;
     rc = ble_gattc_write_no_rsp(2, 100, ble_gatt_write_test_attr_value,
-                                attr_len, ble_gatt_write_test_cb_good,
-                                &attr_len);
+                                attr_len);
     TEST_ASSERT(rc == 0);
 
     /* Send the pending ATT Write Command. */
     ble_hs_test_util_tx_all();
 
-    /* No response expected; verify callback got called. */
-    TEST_ASSERT(ble_gatt_write_test_cb_called);
+    /* No response expected; verify callback not called. */
+    TEST_ASSERT(!ble_gatt_write_test_cb_called);
 }
 
 TEST_CASE(ble_gatt_write_test_rsp)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 778df9d..d451e7a 100644
--- a/net/nimble/host/src/test/ble_host_hci_test.c
+++ b/net/nimble/host/src/test/ble_host_hci_test.c
@@ -38,142 +38,9 @@ TEST_CASE(ble_host_hci_test_event_bad)
     TEST_ASSERT(rc == BLE_HS_ENOTSUP);
 }
 
-TEST_CASE(ble_host_hci_test_event_cmd_complete)
-{
-    uint8_t buf[BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN];
-    int rc;
-
-    ble_hs_test_util_init();
-
-    /*** Unsent OCF. */
-    ble_hs_test_util_build_cmd_complete(buf, sizeof buf, 1, 1, 12345);
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == BLE_HS_ENOENT);
-
-    /*** No error on NOP. */
-    ble_hs_test_util_build_cmd_complete(buf, sizeof buf, 1, 1,
-                                        BLE_HCI_OPCODE_NOP);
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == 0);
-
-    /*** Acknowledge sent command. */
-    rc = host_hci_cmd_le_set_adv_enable(0);
-    TEST_ASSERT(rc == 0);
-    ble_hs_test_util_build_cmd_complete(
-        buf, sizeof buf, 1, 1,
-        (BLE_HCI_OGF_LE << 10) | BLE_HCI_OCF_LE_SET_ADV_ENABLE);
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == 0);
-
-    /*** Duplicate ack is error. */
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == BLE_HS_ENOENT);
-}
-
-TEST_CASE(ble_host_hci_test_event_cmd_status)
-{
-    uint8_t buf[BLE_HCI_EVENT_CMD_STATUS_LEN];
-    int rc;
-
-    ble_hs_test_util_init();
-
-    /*** Unsent OCF. */
-    ble_hs_test_util_build_cmd_status(buf, sizeof buf, 0, 1, 12345);
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == BLE_HS_ENOENT);
-
-    /*** No error on NOP. */
-    ble_hs_test_util_build_cmd_complete(buf, sizeof buf, 0, 1,
-                                        BLE_HCI_OPCODE_NOP);
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == 0);
-
-    /*** Acknowledge sent command. */
-    rc = host_hci_cmd_le_set_adv_enable(0);
-    TEST_ASSERT(rc == 0);
-    ble_hs_test_util_build_cmd_status(
-        buf, sizeof buf, BLE_ERR_SUCCESS, 1,
-        (BLE_HCI_OGF_LE << 10) | BLE_HCI_OCF_LE_SET_ADV_ENABLE);
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == 0);
-
-    /*** Duplicate ack is error. */
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == BLE_HS_ENOENT);
-}
-
-static int ble_host_hci_test_tx_called;
-static uint8_t ble_host_hci_test_handle;
-
-static int
-ble_host_hci_test_util_tx_cb(void *arg)
-{
-    ble_host_hci_test_tx_called++;
-    return 0;
-}
-
-static void
-ble_host_hci_test_util_ack_cb(struct ble_hci_ack *ack, void *arg)
-{ }
-
-TEST_CASE(ble_host_hci_test_cancel_bad)
-{
-    int rc;
-
-    /*** Nonexistant handle. */
-    rc = ble_hci_sched_cancel(123);
-    TEST_ASSERT(rc == BLE_HS_ENOENT);
-}
-
-TEST_CASE(ble_host_hci_test_cancel_pending)
-{
-    uint8_t hci_handle;
-    int rc;
-
-    rc = ble_hci_sched_enqueue(ble_host_hci_test_util_tx_cb, NULL,
-                               &hci_handle);
-    TEST_ASSERT_FATAL(rc == 0);
-    TEST_ASSERT(hci_handle != BLE_HCI_SCHED_HANDLE_NONE);
-
-    rc = ble_hci_sched_cancel(hci_handle);
-    TEST_ASSERT(rc == 0);
-
-    ble_hci_sched_wakeup();
-    TEST_ASSERT(ble_host_hci_test_tx_called == 0);
-}
-
-TEST_CASE(ble_host_hci_test_cancel_cur)
-{
-    uint8_t hci_handle;
-    int rc;
-
-    ble_hci_sched_set_ack_cb(ble_host_hci_test_util_ack_cb, NULL);
-    rc = ble_hci_sched_enqueue(ble_host_hci_test_util_tx_cb, NULL,
-                               &hci_handle);
-    TEST_ASSERT_FATAL(rc == 0);
-    TEST_ASSERT(hci_handle != BLE_HCI_SCHED_HANDLE_NONE);
-
-    ble_host_hci_test_handle = hci_handle;
-
-    ble_hci_sched_wakeup();
-
-    TEST_ASSERT(ble_host_hci_test_tx_called == 1);
-    TEST_ASSERT(ble_hci_sched_get_ack_cb() != NULL);
-
-    rc = ble_hci_sched_cancel(hci_handle);
-    TEST_ASSERT_FATAL(rc == 0);
-
-    TEST_ASSERT(ble_hci_sched_get_ack_cb() == NULL);
-}
-
 TEST_SUITE(ble_host_hci_suite)
 {
     ble_host_hci_test_event_bad();
-    ble_host_hci_test_event_cmd_complete();
-    ble_host_hci_test_event_cmd_status();
-    ble_host_hci_test_cancel_bad();
-    ble_host_hci_test_cancel_pending();
-    ble_host_hci_test_cancel_cur();
 }
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/test/ble_hs_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_conn_test.c b/net/nimble/host/src/test/ble_hs_conn_test.c
index 5a23700..fa23c18 100644
--- a/net/nimble/host/src/test/ble_hs_conn_test.c
+++ b/net/nimble/host/src/test/ble_hs_conn_test.c
@@ -110,8 +110,6 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_success)
                                     NULL, 0, 0);
     TEST_ASSERT(rc == 0);
 
-    ble_hci_sched_wakeup();
-
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(ble_gap_slave_in_progress());
 
@@ -220,72 +218,6 @@ TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
     TEST_ASSERT(chan->blc_peer_mtu == 0);
     TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
 }
-TEST_CASE(ble_hs_conn_test_completed_pkts)
-{
-    struct ble_hs_conn *conn1;
-    struct ble_hs_conn *conn2;
-
-    ble_hs_test_util_init();
-
-    conn1 = ble_hs_test_util_create_conn(1, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                         NULL, NULL);
-    conn2 = ble_hs_test_util_create_conn(2, ((uint8_t[]){3,4,5,6,7,8,9,10}),
-                                         NULL, NULL);
-
-    conn1->bhc_outstanding_pkts = 5;
-    conn2->bhc_outstanding_pkts = 5;
-
-    /*** Event specifies nonexistent connection; no effect. */
-    ble_hs_test_util_rx_num_completed_pkts_event(
-        (struct ble_hs_test_util_num_completed_pkts_entry []) {
-            { 5, 5 },
-            { 0 }});
-    TEST_ASSERT(conn1->bhc_outstanding_pkts == 5);
-    TEST_ASSERT(conn2->bhc_outstanding_pkts == 5);
-
-    /*** Event specifies connection 1. */
-    ble_hs_test_util_rx_num_completed_pkts_event(
-        (struct ble_hs_test_util_num_completed_pkts_entry []) {
-            { 1, 1 },
-            { 0 }});
-    TEST_ASSERT(conn1->bhc_outstanding_pkts == 4);
-    TEST_ASSERT(conn2->bhc_outstanding_pkts == 5);
-
-    /*** Event specifies connection 2. */
-    ble_hs_test_util_rx_num_completed_pkts_event(
-        (struct ble_hs_test_util_num_completed_pkts_entry []) {
-            { 2, 1 },
-            { 0 }});
-    TEST_ASSERT(conn1->bhc_outstanding_pkts == 4);
-    TEST_ASSERT(conn2->bhc_outstanding_pkts == 4);
-
-    /*** Event specifies connections 1 and 2. */
-    ble_hs_test_util_rx_num_completed_pkts_event(
-        (struct ble_hs_test_util_num_completed_pkts_entry []) {
-            { 1, 2 },
-            { 2, 2 },
-            { 0 }});
-    TEST_ASSERT(conn1->bhc_outstanding_pkts == 2);
-    TEST_ASSERT(conn2->bhc_outstanding_pkts == 2);
-
-    /*** Event specifies connections 1, 2, and nonexistent. */
-    ble_hs_test_util_rx_num_completed_pkts_event(
-        (struct ble_hs_test_util_num_completed_pkts_entry []) {
-            { 1, 1 },
-            { 2, 1 },
-            { 10, 50 },
-            { 0 }});
-    TEST_ASSERT(conn1->bhc_outstanding_pkts == 1);
-    TEST_ASSERT(conn2->bhc_outstanding_pkts == 1);
-
-    /*** Don't wrap when count gets out of sync. */
-    ble_hs_test_util_rx_num_completed_pkts_event(
-        (struct ble_hs_test_util_num_completed_pkts_entry []) {
-            { 1, 10 },
-            { 0 }});
-    TEST_ASSERT(conn1->bhc_outstanding_pkts == 0);
-    TEST_ASSERT(conn2->bhc_outstanding_pkts == 1);
-}
 
 TEST_SUITE(conn_suite)
 {
@@ -294,7 +226,6 @@ TEST_SUITE(conn_suite)
     ble_hs_conn_test_direct_connectable_success();
     ble_hs_conn_test_direct_connectable_hci_errors();
     ble_hs_conn_test_undirect_connectable_success();
-    ble_hs_conn_test_completed_pkts();
 }
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 61150a6..183774e 100644
--- a/net/nimble/host/src/test/ble_hs_test.c
+++ b/net/nimble/host/src/test/ble_hs_test.c
@@ -49,28 +49,27 @@ int
 main(void)
 {
     tu_config.tc_print_results = 1;
-    tu_config.tc_system_assert = 1;
     tu_init();
 
-    ble_l2cap_test_all();
-    ble_l2cap_sm_test_all();
-    ble_att_svr_test_all();
     ble_att_clt_test_all();
-    ble_host_hci_test_all();
-    ble_hs_conn_test_all();
-    ble_os_test_all();
-    ble_uuid_test_all();
-    ble_gatt_disc_s_test_all();
+    ble_att_svr_test_all();
+    ble_gap_test_all();
+    ble_gatt_conn_test_all();
     ble_gatt_disc_c_test_all();
     ble_gatt_disc_d_test_all();
+    ble_gatt_disc_s_test_all();
+    ble_gatt_find_s_test_all();
     ble_gatt_read_test_all();
     ble_gatt_write_test_all();
-    ble_gatt_conn_test_all();
-    ble_hs_adv_test_all();
-    ble_gatts_reg_test_all();
     ble_gatts_notify_test_all();
-    ble_gatt_find_s_test_all();
-    ble_gap_test_all();
+    ble_gatts_reg_test_all();
+    ble_host_hci_test_all();
+    ble_hs_adv_test_all();
+    ble_hs_conn_test_all();
+    ble_l2cap_sm_test_all();
+    ble_l2cap_test_all();
+    ble_os_test_all();
+    ble_uuid_test_all();
 
     return tu_any_failed;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 0741cc3..d8c9dab 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -37,6 +37,8 @@
 #define BLE_HS_TEST_UTIL_LE_OPCODE(ocf) \
     host_hci_opcode_join(BLE_HCI_OGF_LE, (ocf))
 
+struct os_eventq ble_hs_test_util_evq;
+
 os_membuf_t ble_hs_test_util_mbuf_mpool_data[BLE_HS_TEST_UTIL_MEMPOOL_SIZE];
 struct os_mbuf_pool ble_hs_test_util_mbuf_pool;
 struct os_mempool ble_hs_test_util_mbuf_mpool;
@@ -134,7 +136,7 @@ ble_hs_test_util_build_cmd_status(uint8_t *dst, int len,
 struct ble_hs_test_util_phony_ack {
     uint16_t opcode;
     uint8_t status;
-    uint8_t *evt_params;
+    uint8_t evt_params[256];
     uint8_t evt_params_len;
 };
 
@@ -143,7 +145,7 @@ ble_hs_test_util_phony_acks[BLE_HS_TEST_UTIL_PHONY_ACK_MAX];
 static int ble_hs_test_util_num_phony_acks;
 
 static int
-ble_hs_test_util_phony_ack_cb(void *cmd, uint8_t *ack, int ack_buf_len)
+ble_hs_test_util_phony_ack_cb(uint8_t *ack, int ack_buf_len)
 {
     struct ble_hs_test_util_phony_ack *entry;
 
@@ -170,13 +172,30 @@ ble_hs_test_util_phony_ack_cb(void *cmd, uint8_t *ack, int ack_buf_len)
 }
 
 void
-ble_hs_test_util_set_ack(uint16_t opcode, uint8_t status)
+ble_hs_test_util_set_ack_params(uint16_t opcode, uint8_t status, void *params,
+                                uint8_t params_len)
 {
-    ble_hs_test_util_phony_acks[0].opcode = opcode;
-    ble_hs_test_util_phony_acks[0].status = status;
+    struct ble_hs_test_util_phony_ack *ack;
+
+    ack = ble_hs_test_util_phony_acks + 0;
+    ack->opcode = opcode;
+    ack->status = status;
+
+    if (params == NULL || params_len == 0) {
+        ack->evt_params_len = 0;
+    } else {
+        memcpy(ack->evt_params, params, params_len);
+        ack->evt_params_len = params_len;
+    }
     ble_hs_test_util_num_phony_acks = 1;
 
-    ble_hci_block_set_phony_ack_cb(ble_hs_test_util_phony_ack_cb);
+    ble_hci_set_phony_ack_cb(ble_hs_test_util_phony_ack_cb);
+}
+
+void
+ble_hs_test_util_set_ack(uint16_t opcode, uint8_t status)
+{
+    ble_hs_test_util_set_ack_params(opcode, status, NULL, 0);
 }
 
 static void
@@ -189,7 +208,7 @@ ble_hs_test_util_set_ack_seq(struct ble_hs_test_util_phony_ack *acks)
     }
     ble_hs_test_util_num_phony_acks = i;
 
-    ble_hci_block_set_phony_ack_cb(ble_hs_test_util_phony_ack_cb);
+    ble_hci_set_phony_ack_cb(ble_hs_test_util_phony_ack_cb);
 }
 
 struct ble_hs_conn *
@@ -320,7 +339,7 @@ ble_hs_test_util_adv_start(uint8_t discoverable_mode,
         acks[i] = (struct ble_hs_test_util_phony_ack) {
             BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR),
             fail_idx == i ? fail_status : 0,
-            (uint8_t[]) { 0 },
+            { 0 },
             1,
         };
         i++;
@@ -414,65 +433,16 @@ ble_hs_test_util_conn_update(uint16_t conn_handle,
     return rc;
 }
 
-void
-ble_hs_test_util_rx_ack_param(uint16_t opcode, uint8_t status, void *param,
-                              int param_len)
-{
-    uint8_t buf[256];
-    int rc;
-
-    ble_hs_test_util_build_cmd_complete(buf, sizeof buf, param_len + 1, 1,
-                                        opcode);
-    buf[BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN] = status;
-    memcpy(buf + BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN + 1, param, param_len);
-
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == 0);
-}
-
-void
-ble_hs_test_util_rx_ack(uint16_t opcode, uint8_t status)
-{
-    uint8_t buf[BLE_HCI_EVENT_CMD_STATUS_LEN];
-    int rc;
-
-    ble_hs_test_util_build_cmd_status(buf, sizeof buf, status, 1, opcode);
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == 0);
-}
-
-void
-ble_hs_test_util_rx_hci_buf_size_ack(uint16_t buf_size)
+int
+ble_hs_test_util_security_initiate(uint16_t conn_handle, uint8_t hci_status)
 {
-    uint8_t buf[BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN +
-                BLE_HCI_RD_BUF_SIZE_RSPLEN + 1];
     int rc;
 
-    ble_hs_test_util_build_cmd_complete(buf, sizeof buf,
-                                        BLE_HCI_RD_BUF_SIZE_RSPLEN + 1, 1,
-                                        (BLE_HCI_OGF_LE << 10) |
-                                            BLE_HCI_OCF_LE_RD_BUF_SIZE);
-
-    buf[BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN + 0] = 0;
-    htole16(buf + BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN + 1, buf_size);
-    buf[BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN + 3] = 1;
-
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == 0);
-}
-
-void
-ble_hs_test_util_rx_le_ack_param(uint16_t ocf, uint8_t status, void *param,
-                                 int param_len)
-{
-    ble_hs_test_util_rx_ack_param((BLE_HCI_OGF_LE << 10) | ocf, status, param,
-                                  param_len);
-}
+    ble_hs_test_util_set_ack(
+        BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_START_ENCRYPT), hci_status);
 
-void
-ble_hs_test_util_rx_le_ack(uint16_t ocf, uint8_t status)
-{
-    ble_hs_test_util_rx_ack((BLE_HCI_OGF_LE << 10) | ocf, status);
+    rc = ble_gap_security_initiate(conn_handle);
+    return rc;
 }
 
 int
@@ -560,24 +530,39 @@ ble_hs_test_util_rx_att_err_rsp(struct ble_hs_conn *conn, uint8_t req_op,
 }
 
 void
-ble_hs_test_util_rx_startup_acks(void)
+ble_hs_test_util_set_startup_acks(void)
 {
-    uint8_t supp_feat[8];
-
-    memset(supp_feat, 0, sizeof supp_feat);
-
     /* Receive acknowledgements for the startup sequence.  We sent the
      * corresponding requests when the host task was started.
      */
-    ble_hs_test_util_rx_ack(
-        (BLE_HCI_OGF_CTLR_BASEBAND << 10) | BLE_HCI_OCF_CB_RESET, 0);
-    ble_hs_test_util_rx_ack(
-        (BLE_HCI_OGF_CTLR_BASEBAND << 10) | BLE_HCI_OCF_CB_SET_EVENT_MASK,
-        0);
-    ble_hs_test_util_rx_le_ack(BLE_HCI_OCF_LE_SET_EVENT_MASK, 0);
-    ble_hs_test_util_rx_hci_buf_size_ack(0xffff);
-    ble_hs_test_util_rx_le_ack_param(BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT, 0,
-                                     supp_feat, sizeof supp_feat);
+    ble_hs_test_util_set_ack_seq(((struct ble_hs_test_util_phony_ack[]) {
+        {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_CTLR_BASEBAND,
+                                           BLE_HCI_OCF_CB_RESET),
+        },
+        {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_CTLR_BASEBAND,
+                                           BLE_HCI_OCF_CB_SET_EVENT_MASK),
+        },
+        {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                           BLE_HCI_OCF_LE_SET_EVENT_MASK),
+        },
+        {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                           BLE_HCI_OCF_LE_RD_BUF_SIZE),
+            .evt_params = { 0xff, 0xff, 1 },
+            .evt_params_len = 3,
+        },
+        {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                           BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT),
+            .evt_params = { 0 },
+            .evt_params_len = 8,
+        },
+
+        { 0 }
+    }));
 }
 
 void
@@ -641,11 +626,7 @@ ble_hs_test_util_verify_tx_hci(uint8_t ogf, uint16_t ocf,
 void
 ble_hs_test_util_tx_all(void)
 {
-    ble_gattc_wakeup();
-    ble_l2cap_sig_wakeup();
-    ble_l2cap_sm_wakeup();
     ble_hs_process_tx_data_queue();
-    ble_hci_sched_wakeup();
 }
 
 void
@@ -662,12 +643,14 @@ ble_hs_test_util_init(void)
 
     tu_init();
 
+    os_eventq_init(&ble_hs_test_util_evq);
+
     os_msys_reset();
     stats_module_reset();
 
     cfg = ble_hs_cfg_dflt;
     cfg.max_connections = 8;
-    rc = ble_hs_init(10, &cfg);
+    rc = ble_hs_init(&ble_hs_test_util_evq, &cfg);
     TEST_ASSERT_FATAL(rc == 0);
 
     rc = os_mempool_init(&ble_hs_test_util_mbuf_mpool,
@@ -686,7 +669,7 @@ ble_hs_test_util_init(void)
     rc = os_msys_register(&ble_hs_test_util_mbuf_pool);
     TEST_ASSERT_FATAL(rc == 0);
 
-    ble_hci_block_set_phony_ack_cb(NULL);
+    ble_hci_set_phony_ack_cb(NULL);
 
     /* Don't limit a connection's ability to transmit; simplify tests. */
     ble_hs_cfg.max_outstanding_pkts_per_conn = 0;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 0bbeb52..aea5f08 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.h
+++ b/net/nimble/host/src/test/ble_hs_test_util.h
@@ -26,6 +26,7 @@
 struct ble_hs_conn;
 struct ble_l2cap_chan;
 
+struct os_eventq ble_hs_test_util_evq;
 extern struct os_mbuf *ble_hs_test_util_prev_tx;
 
 struct ble_hs_test_util_num_completed_pkts_entry {
@@ -33,6 +34,8 @@ struct ble_hs_test_util_num_completed_pkts_entry {
     uint16_t num_pkts;
 };
 
+void ble_hs_test_util_set_ack_params(uint16_t opcode, uint8_t status,
+                                     void *params, uint8_t params_len);
 void ble_hs_test_util_set_ack(uint16_t opcode, uint8_t status);
 void *ble_hs_test_util_get_first_hci_tx(void);
 void *ble_hs_test_util_get_last_hci_tx(void);
@@ -71,10 +74,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);
-void ble_hs_test_util_rx_ack(uint16_t opcode, uint8_t status);
-void ble_hs_test_util_rx_ack_param(uint16_t opcode, uint8_t status,
-                                   void *param, int param_len);
-void ble_hs_test_util_rx_le_ack(uint16_t ocf, uint8_t 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(struct ble_hs_conn *conn,
                                          uint16_t cid,
                                          struct hci_data_hdr *hci_hdr,
@@ -82,15 +83,13 @@ int ble_hs_test_util_l2cap_rx_first_frag(struct ble_hs_conn *conn,
 int ble_hs_test_util_l2cap_rx(struct ble_hs_conn *conn,
                               struct hci_data_hdr *hci_hdr,
                               struct os_mbuf *om);
-void ble_hs_test_util_rx_le_ack_param(uint16_t ocf, uint8_t status,
-                                      void *param, int param_len);
 int ble_hs_test_util_l2cap_rx_payload_flat(struct ble_hs_conn *conn,
                                            struct ble_l2cap_chan *chan,
                                            const void *data, int len);
 void ble_hs_test_util_rx_hci_buf_size_ack(uint16_t buf_size);
 void ble_hs_test_util_rx_att_err_rsp(struct ble_hs_conn *conn, uint8_t req_op,
                                      uint8_t error_code, uint16_t err_handle);
-void ble_hs_test_util_rx_startup_acks(void);
+void ble_hs_test_util_set_startup_acks(void);
 void ble_hs_test_util_rx_num_completed_pkts_event(
     struct ble_hs_test_util_num_completed_pkts_entry *entries);
 uint8_t *ble_hs_test_util_verify_tx_hci(uint8_t ogf, uint16_t ocf,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/test/ble_l2cap_sm_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_l2cap_sm_test.c b/net/nimble/host/src/test/ble_l2cap_sm_test.c
index e0234ae..86b69c3 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -303,14 +303,15 @@ ble_l2cap_sm_test_util_verify_tx_lt_key_req_reply(uint16_t conn_handle,
 }
 
 static void
-ble_l2cap_sm_test_util_rx_lt_key_req_reply_ack(uint8_t status,
-                                               uint16_t conn_handle)
+ble_l2cap_sm_test_util_set_lt_key_req_reply_ack(uint8_t status,
+                                                uint16_t conn_handle)
 {
-    uint8_t params[BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN - 1];
+    static uint8_t params[BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN - 1];
 
     htole16(params, conn_handle);
-    ble_hs_test_util_rx_le_ack_param(BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY, status,
-                                     params, sizeof params);
+    ble_hs_test_util_set_ack_params(
+        host_hci_opcode_join(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY),
+        status, params, sizeof params);
 }
 
 static void
@@ -412,21 +413,16 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Receive a long term key request from the controller. */
+    ble_l2cap_sm_test_util_set_lt_key_req_reply_ack(0, 2);
     ble_l2cap_sm_test_util_rx_lt_key_req(2, r, ediv);
     TEST_ASSERT(!conn->bhc_sec_params.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected long term key request reply command. */
-    ble_hs_test_util_tx_all();
     ble_l2cap_sm_test_util_verify_tx_lt_key_req_reply(2, stk);
     TEST_ASSERT(!conn->bhc_sec_params.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Receive a command complete event. */
-    ble_l2cap_sm_test_util_rx_lt_key_req_reply_ack(0, 2);
-    TEST_ASSERT(!conn->bhc_sec_params.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
-
     /* Receive an encryption changed event. */
     ble_l2cap_sm_test_util_rx_enc_change(2, 0, 1);
 
@@ -493,7 +489,6 @@ ble_l2cap_sm_test_util_peer_lgcy_fail(
 
     /* Receive a pair random from the peer. */
     ble_l2cap_sm_test_util_rx_random(conn, random_req);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected pair fail. */
     ble_hs_test_util_tx_all();
@@ -568,8 +563,8 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_jw_good)
         BLE_L2CAP_SM_PAIR_ALG_JW,
         NULL,
         ((uint8_t[16]) {
-            0xe6, 0xb3, 0x05, 0xd4, 0xc3, 0x67, 0xf0, 0x45,
-            0x38, 0x8f, 0xe7, 0x33, 0x0d, 0x51, 0x8e, 0xa4,
+            0xa4, 0x8e, 0x51, 0x0d, 0x33, 0xe7, 0x8f, 0x38,
+            0x45, 0xf0, 0x67, 0xc3, 0xd4, 0x05, 0xb3, 0xe6,
         }),
         0,
         0
@@ -664,7 +659,7 @@ ble_l2cap_sm_test_util_us_lgcy_good(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
     /* Initiate the pairing procedure. */
-    rc = ble_gap_security_initiate(2);
+    rc = ble_hs_test_util_security_initiate(2, 0);
     TEST_ASSERT_FATAL(rc == 0);
 
     /* Ensure we sent the expected pair request. */
@@ -706,11 +701,6 @@ ble_l2cap_sm_test_util_us_lgcy_good(
     TEST_ASSERT(!conn->bhc_sec_params.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Receive a command status event. */
-    ble_hs_test_util_rx_le_ack(BLE_HCI_OCF_LE_START_ENCRYPT, 0);
-    TEST_ASSERT(!conn->bhc_sec_params.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
-
     /* Receive an encryption changed event. */
     ble_l2cap_sm_test_util_rx_enc_change(2, 0, 1);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/test/ble_l2cap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_l2cap_test.c b/net/nimble/host/src/test/ble_l2cap_test.c
index c9e116c..9cde642 100644
--- a/net/nimble/host/src/test/ble_l2cap_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_test.c
@@ -471,10 +471,6 @@ ble_l2cap_test_util_peer_updates(int accept)
     ble_l2cap_test_util_verify_tx_update_rsp(1, !accept);
 
     if (accept) {
-        /* Ensure update request gets sent. */
-        ble_gattc_wakeup();
-        ble_hci_sched_wakeup();
-
         params.itvl_min = 0x200;
         params.itvl_max = 0x300;
         params.latency = 0;
@@ -574,13 +570,11 @@ TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_master)
     params.timeout_multiplier = 0x100;
     rc = ble_l2cap_sig_update(conn->bhc_handle, &params,
                               ble_l2cap_test_util_update_cb, NULL);
-    TEST_ASSERT_FATAL(rc == 0);
+    TEST_ASSERT_FATAL(rc == BLE_HS_EINVAL);
 
+    /* Ensure callback never called. */
     ble_hs_test_util_tx_all();
-
-    /* Ensure callback indicates failure. */
-    TEST_ASSERT(ble_l2cap_test_update_status == BLE_HS_EINVAL);
-    TEST_ASSERT(ble_l2cap_test_update_arg == NULL);
+    TEST_ASSERT(ble_l2cap_test_update_status == -1);
 }
 
 TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_bad_id)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 b8f3901..e95e567 100644
--- a/net/nimble/host/src/test/ble_os_test.c
+++ b/net/nimble/host/src/test/ble_os_test.c
@@ -28,39 +28,51 @@
 
 #ifdef ARCH_sim
 #define BLE_OS_TEST_STACK_SIZE      1024
+#define BLE_OS_TEST_APP_STACK_SIZE  1024
 #else
 #define BLE_OS_TEST_STACK_SIZE      256
+#define BLE_OS_TEST_APP_STACK_SIZE  256
 #endif
 
-#define BLE_OS_TEST_HS_PRIO         10
+#define BLE_OS_TEST_APP_PRIO         9
+#define BLE_OS_TEST_TASK_PRIO        10
 
 static struct os_task ble_os_test_task;
+static struct os_task ble_os_test_app_task;
 static os_stack_t ble_os_test_stack[OS_STACK_ALIGN(BLE_OS_TEST_STACK_SIZE)];
 
+static os_stack_t
+ble_os_test_app_stack[OS_STACK_ALIGN(BLE_OS_TEST_APP_STACK_SIZE)];
+
 static uint8_t ble_os_test_peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
 
+static void ble_os_test_app_task_handler(void *arg);
+
 static void
-ble_os_test_misc_rx_ack(uint8_t ogf, uint8_t ocf, uint8_t status)
+ble_os_test_init_app_task(void)
 {
-    uint16_t opcode;
-    uint8_t *cmd;
     int rc;
 
-    cmd = os_memblock_get(&g_hci_cmd_pool);
-    TEST_ASSERT_FATAL(cmd != NULL);
-
-    opcode = (ogf << 10) | ocf;
-    ble_hs_test_util_build_cmd_status(cmd, BLE_HCI_EVENT_CMD_STATUS_LEN,
-                                      status, 1, opcode);
-
-    rc = ble_hci_transport_ctlr_event_send(cmd);
-    TEST_ASSERT(rc == 0);
+    rc = os_task_init(&ble_os_test_app_task,
+                      "ble_gap_terminate_test_task",
+                      ble_os_test_app_task_handler, NULL,
+                      BLE_OS_TEST_APP_PRIO, OS_WAIT_FOREVER,
+                      ble_os_test_app_stack,
+                      OS_STACK_ALIGN(BLE_OS_TEST_APP_STACK_SIZE));
+    TEST_ASSERT_FATAL(rc == 0);
 }
 
 static void
-ble_os_test_misc_rx_le_ack(uint16_t ocf, uint8_t status)
+ble_os_test_misc_init(void)
 {
-    ble_os_test_misc_rx_ack(BLE_HCI_OGF_LE, ocf, status);
+    ble_hs_test_util_init();
+
+    ble_os_test_init_app_task();
+
+    /* Receive acknowledgements for the startup sequence.  We sent the
+     * corresponding requests when the host task was started.
+     */
+    ble_hs_test_util_set_startup_acks();
 }
 
 static int
@@ -90,11 +102,6 @@ ble_gap_direct_connect_test_task_handler(void *arg)
     int cb_called;
     int rc;
 
-    /* Receive acknowledgements for the startup sequence.  We sent the
-     * corresponding requests when the host task was started.
-     */
-    ble_hs_test_util_rx_startup_acks();
-
     /* Set the connect callback so we can verify that it gets called with the
      * proper arguments.
      */
@@ -130,12 +137,12 @@ ble_gap_direct_connect_test_task_handler(void *arg)
 
 TEST_CASE(ble_gap_direct_connect_test_case)
 {
-    ble_hs_test_util_init();
+    ble_os_test_misc_init();
 
     os_task_init(&ble_os_test_task,
                  "ble_gap_direct_connect_test_task",
                  ble_gap_direct_connect_test_task_handler, NULL,
-                 BLE_OS_TEST_HS_PRIO + 1, OS_WAIT_FOREVER, ble_os_test_stack,
+                 BLE_OS_TEST_TASK_PRIO, OS_WAIT_FOREVER, ble_os_test_stack,
                  OS_STACK_ALIGN(BLE_OS_TEST_STACK_SIZE));
 
     os_start();
@@ -163,7 +170,7 @@ ble_gap_gen_disc_test_task_handler(void *arg)
     /* Receive acknowledgements for the startup sequence.  We sent the
      * corresponding requests when the host task was started.
      */
-    ble_hs_test_util_rx_startup_acks();
+    ble_hs_test_util_set_startup_acks();
 
     /* Set the connect callback so we can verify that it gets called with the
      * proper arguments.
@@ -177,7 +184,7 @@ ble_gap_gen_disc_test_task_handler(void *arg)
     TEST_ASSERT(!ble_gap_master_in_progress());
 
     /* Initiate the general discovery procedure with a 200 ms timeout. */
-    rc = ble_hs_test_util_disc(200, BLE_GAP_DISC_MODE_GEN,
+    rc = ble_hs_test_util_disc(300, BLE_GAP_DISC_MODE_GEN,
                                BLE_HCI_SCAN_TYPE_ACTIVE,
                                BLE_HCI_SCAN_FILT_NO_WL,
                                ble_gap_gen_disc_test_connect_cb,
@@ -198,9 +205,12 @@ ble_gap_gen_disc_test_task_handler(void *arg)
     TEST_ASSERT(ble_gap_master_in_progress());
     TEST_ASSERT(!cb_called);
 
-    /* Wait 150 more ms; verify scan completed. */
-    os_time_delay(150 * OS_TICKS_PER_SEC / 1000);
-    ble_os_test_misc_rx_le_ack(BLE_HCI_OCF_LE_SET_SCAN_ENABLE, 0);
+    ble_hs_test_util_set_ack(
+        host_hci_opcode_join(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_ENABLE),
+        0);
+
+    /* Wait 250 more ms; verify scan completed. */
+    os_time_delay(250 * OS_TICKS_PER_SEC / 1000);
     TEST_ASSERT(ble_hs_conn_first() == NULL);
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(cb_called);
@@ -210,12 +220,12 @@ ble_gap_gen_disc_test_task_handler(void *arg)
 
 TEST_CASE(ble_gap_gen_disc_test_case)
 {
-    ble_hs_test_util_init();
+    ble_os_test_misc_init();
 
     os_task_init(&ble_os_test_task,
                  "ble_gap_gen_disc_test_task",
                  ble_gap_gen_disc_test_task_handler, NULL,
-                 BLE_OS_TEST_HS_PRIO + 1, OS_WAIT_FOREVER, ble_os_test_stack,
+                 BLE_OS_TEST_TASK_PRIO, OS_WAIT_FOREVER, ble_os_test_stack,
                  OS_STACK_ALIGN(BLE_OS_TEST_STACK_SIZE));
 
     os_start();
@@ -252,7 +262,7 @@ ble_gap_terminate_test_task_handler(void *arg)
     /* Receive acknowledgements for the startup sequence.  We sent the
      * corresponding requests when the host task was started.
      */
-    ble_hs_test_util_rx_startup_acks();
+    ble_hs_test_util_set_startup_acks();
 
     /* Set the connect callback so we can verify that it gets called with the
      * proper arguments.
@@ -314,14 +324,39 @@ ble_gap_terminate_test_task_handler(void *arg)
     tu_restart();
 }
 
+static void
+ble_os_test_app_task_handler(void *arg)
+{
+    struct os_callout_func *cf;
+    struct os_event *ev;
+    int rc;
+
+    rc = ble_hs_start();
+    TEST_ASSERT(rc == 0);
+
+    while (1) {
+        ev = os_eventq_get(&ble_hs_test_util_evq);
+        switch (ev->ev_type) {
+        case OS_EVENT_T_TIMER:
+            cf = (struct os_callout_func *)ev;
+            assert(cf->cf_func);
+            cf->cf_func(cf->cf_arg);
+            break;
+        default:
+            assert(0);
+            break;
+        }
+    }
+}
+
 TEST_CASE(ble_gap_terminate_test_case)
 {
-    ble_hs_test_util_init();
+    ble_os_test_misc_init();
 
     os_task_init(&ble_os_test_task,
                  "ble_gap_terminate_test_task",
                  ble_gap_terminate_test_task_handler, NULL,
-                 BLE_OS_TEST_HS_PRIO + 1, OS_WAIT_FOREVER, ble_os_test_stack,
+                 BLE_OS_TEST_TASK_PRIO, OS_WAIT_FOREVER, ble_os_test_stack,
                  OS_STACK_ALIGN(BLE_OS_TEST_STACK_SIZE));
 
     os_start();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/include/nimble/hci_common.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h
index e2874a7..2d43652 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -142,7 +142,7 @@
 
 /* --- LE read buffer size (OCF 0x0002) --- */
 #define BLE_HCI_RD_BUF_SIZE_LEN             (0)
-#define BLE_HCI_RD_BUF_SIZE_RSPLEN          (3)
+#define BLE_HCI_RD_BUF_SIZE_RSPLEN          (3) /* No status byte. */
 
 /* --- LE read local supported features (OCF 0x0003) --- */
 #define BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN     (8)


[06/50] [abbrv] incubator-mynewt-core git commit: nffs - delete cached blocks after gc.

Posted by ma...@apache.org.
nffs - delete cached blocks after gc.

Garbage collection deletes and recreates data blocks.  Any cached data
blocks are potentially invalid after a garbage collection cycle.
Garbage collection does not delete any inodes, but it may move them
around in flash.

This fix implements the following changes:
    * After GC is performed, delete all cached data blocks.
    * After GC is performed, refresh all cached inodes (recache them).
    * For higher level operations that use pointers to cached data
      blocks, detect when garbage collection occurs, and reset the
      pointers as necessary.


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

Branch: refs/heads/master
Commit: 2f430d3c9cf6014e2fd1928af07358c5d96abbea
Parents: 3abe740
Author: Christopher Collins <cc...@apache.org>
Authored: Tue Apr 19 14:01:55 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Apr 19 14:32:23 2016 -0700

----------------------------------------------------------------------
 fs/nffs/src/nffs_cache.c | 85 +++++++++++++++++++++++++++++++++++++------
 fs/nffs/src/nffs_gc.c    | 34 +++++++++++++++++
 fs/nffs/src/nffs_priv.h  |  2 +
 fs/nffs/src/nffs_write.c | 32 +++++++++++++---
 4 files changed, 137 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2f430d3c/fs/nffs/src/nffs_cache.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_cache.c b/fs/nffs/src/nffs_cache.c
index 580d52e..51ebc30 100644
--- a/fs/nffs/src/nffs_cache.c
+++ b/fs/nffs/src/nffs_cache.c
@@ -26,7 +26,7 @@ TAILQ_HEAD(nffs_cache_inode_list, nffs_cache_inode);
 static struct nffs_cache_inode_list nffs_cache_inode_list =
     TAILQ_HEAD_INITIALIZER(nffs_cache_inode_list);
 
-static void nffs_cache_collect_blocks(void);
+static void nffs_cache_reclaim_blocks(void);
 
 static struct nffs_cache_block *
 nffs_cache_block_alloc(void)
@@ -56,7 +56,7 @@ nffs_cache_block_acquire(void)
 
     cache_block = nffs_cache_block_alloc();
     if (cache_block == NULL) {
-        nffs_cache_collect_blocks();
+        nffs_cache_reclaim_blocks();
         cache_block = nffs_cache_block_alloc();
     }
 
@@ -91,8 +91,7 @@ nffs_cache_inode_alloc(void)
     entry = os_memblock_get(&nffs_cache_inode_pool);
     if (entry != NULL) {
         memset(entry, 0, sizeof *entry);
-        entry->nci_block_list = (struct nffs_cache_block_list)
-            TAILQ_HEAD_INITIALIZER(entry->nci_block_list);
+        TAILQ_INIT(&entry->nci_block_list);
     }
 
     return entry;
@@ -216,7 +215,7 @@ nffs_cache_inode_range(const struct nffs_cache_inode *cache_inode,
 }
 
 static void
-nffs_cache_collect_blocks(void)
+nffs_cache_reclaim_blocks(void)
 {
     struct nffs_cache_inode *cache_inode;
 
@@ -279,6 +278,73 @@ done:
 }
 
 /**
+ * Recaches all cached inodes.  All cached blocks are deleted from the cache
+ * during this operation.  This function should be called after garbage
+ * collection occurs to ensure the cache is consistent.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int
+nffs_cache_inode_refresh(void)
+{
+    struct nffs_cache_inode *cache_inode;
+    struct nffs_inode_entry *inode_entry;
+    int rc;
+
+    TAILQ_FOREACH(cache_inode, &nffs_cache_inode_list, nci_link) {
+        /* Clear entire block list. */
+        nffs_cache_inode_free_blocks(cache_inode);
+
+        inode_entry = cache_inode->nci_inode.ni_inode_entry;
+        rc = nffs_inode_from_entry(&cache_inode->nci_inode, inode_entry);
+        if (rc != 0) {
+            return rc;
+        }
+
+        /* File size remains valid. */
+    }
+
+    return 0;
+}
+
+static void
+nffs_cache_log_block(struct nffs_cache_inode *cache_inode,
+                     struct nffs_cache_block *cache_block)
+{
+    NFFS_LOG(DEBUG, "id=%u inode=%u flash_off=0x%08x "
+                    "file_off=%u len=%d (entry=%p)\n",
+             cache_block->ncb_block.nb_hash_entry->nhe_id,
+             cache_inode->nci_inode.ni_inode_entry->nie_hash_entry.nhe_id,
+             cache_block->ncb_block.nb_hash_entry->nhe_flash_loc,
+             cache_block->ncb_file_offset,
+             cache_block->ncb_block.nb_data_len,
+             cache_block->ncb_block.nb_hash_entry);
+}
+
+static void
+nffs_cache_log_insert_block(struct nffs_cache_inode *cache_inode,
+                            struct nffs_cache_block *cache_block,
+                            int tail)
+{
+    NFFS_LOG(DEBUG, "caching block (%s): ", tail ? "tail" : "head");
+    nffs_cache_log_block(cache_inode, cache_block);
+}
+
+void
+nffs_cache_insert_block(struct nffs_cache_inode *cache_inode,
+                        struct nffs_cache_block *cache_block,
+                        int tail)
+{
+    if (tail) {
+        TAILQ_INSERT_TAIL(&cache_inode->nci_block_list, cache_block, ncb_link);
+    } else {
+        TAILQ_INSERT_HEAD(&cache_inode->nci_block_list, cache_block, ncb_link);
+    }
+
+    nffs_cache_log_insert_block(cache_inode, cache_block, tail);
+}
+
+/**
  * Finds the data block containing the specified offset within a file inode.
  * If the block is not yet cached, it gets cached as a result of this
  * operation.  This function modifies the inode's cached block list according
@@ -364,8 +430,7 @@ nffs_cache_seek(struct nffs_cache_inode *cache_inode, uint32_t seek_offset,
                 return rc;
             }
 
-            TAILQ_INSERT_HEAD(&cache_inode->nci_block_list, cache_block,
-                              ncb_link);
+            nffs_cache_insert_block(cache_inode, cache_block, 0);
         }
 
         /* Calculate the file offset of the start of this block.  This is used
@@ -406,12 +471,10 @@ nffs_cache_seek(struct nffs_cache_inode *cache_inode, uint32_t seek_offset,
                 if (last_cached_entry != NULL &&
                     last_cached_entry == pred_entry) {
 
-                    TAILQ_INSERT_TAIL(&cache_inode->nci_block_list,
-                                      cache_block, ncb_link);
+                    nffs_cache_insert_block(cache_inode, cache_block, 1);
                 } else {
                     nffs_cache_inode_free_blocks(cache_inode);
-                    TAILQ_INSERT_HEAD(&cache_inode->nci_block_list,
-                                      cache_block, ncb_link);
+                    nffs_cache_insert_block(cache_inode, cache_block, 0);
                 }
             }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2f430d3c/fs/nffs/src/nffs_gc.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_gc.c b/fs/nffs/src/nffs_gc.c
index b11c1aa..01882ea 100644
--- a/fs/nffs/src/nffs_gc.c
+++ b/fs/nffs/src/nffs_gc.c
@@ -24,6 +24,13 @@
 #include "nffs_priv.h"
 #include "nffs/nffs.h"
 
+/**
+ * Keeps track of the number of garbage collections performed.  The exact
+ * number is not important, but it is useful to compare against an older copy
+ * to determine if garbage collection occurred.
+ */
+unsigned int nffs_gc_count;
+
 static int
 nffs_gc_copy_object(struct nffs_hash_entry *entry, uint16_t object_size,
                     uint8_t to_area_idx)
@@ -420,6 +427,18 @@ nffs_gc_inode_blocks(struct nffs_inode_entry *inode_entry,
  *      number is incremented prior to rewriting the header.  This area is now
  *      the new scratch sector.
  *
+ * NOTE:
+ *     Garbage collection invalidates all cached data blocks.  Whenever this
+ *     function is called, all existing nffs_cache_block pointers are rendered
+ *     invalid.  If you maintain any such pointers, you need to reset them
+ *     after calling this function.  Cached inodes are not invalidated by
+ *     garbage collection.
+ *
+ *     If a parent function potentially calls this function, the caller of the
+ *     parent function needs to explicitly check if garbage collection
+ *     occurred.  This is done by inspecting the nffs_gc_count variable before
+ *     and after calling the function.
+ *
  * @param out_area_idx      On success, the ID of the cleaned up area gets
  *                              written here.  Pass null if you do not need
  *                              this information.
@@ -502,6 +521,21 @@ nffs_gc(uint8_t *out_area_idx)
 
     nffs_scratch_area_idx = from_area_idx;
 
+    /* Garbage collection renders the cache invalid:
+     *     o All cached blocks are now invalid; drop them.
+     *     o Flash locations of inodes may have changed; the cached inodes need
+     *       updated to reflect this.
+     */
+    rc = nffs_cache_inode_refresh();
+    if (rc != 0) {
+        return rc;
+    }
+
+    /* Increment the garbage collection counter so that client code knows to
+     * reset its pointers to cached objects.
+     */
+    nffs_gc_count++;
+
     return 0;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2f430d3c/fs/nffs/src/nffs_priv.h
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_priv.h b/fs/nffs/src/nffs_priv.h
index 7b1159a..a83256d 100644
--- a/fs/nffs/src/nffs_priv.h
+++ b/fs/nffs/src/nffs_priv.h
@@ -231,6 +231,7 @@ extern struct nffs_area *nffs_areas;
 extern uint8_t nffs_num_areas;
 extern uint8_t nffs_scratch_area_idx;
 extern uint16_t nffs_block_max_data_sz;
+extern unsigned int nffs_gc_count;
 
 #define NFFS_FLASH_BUF_SZ        256
 extern uint8_t nffs_flash_buf[NFFS_FLASH_BUF_SZ];
@@ -278,6 +279,7 @@ int nffs_block_read_data(const struct nffs_block *block, uint16_t offset,
 void nffs_cache_inode_delete(const struct nffs_inode_entry *inode_entry);
 int nffs_cache_inode_ensure(struct nffs_cache_inode **out_entry,
                             struct nffs_inode_entry *inode_entry);
+int nffs_cache_inode_refresh(void);
 void nffs_cache_inode_range(const struct nffs_cache_inode *cache_inode,
                             uint32_t *out_start, uint32_t *out_end);
 int nffs_cache_seek(struct nffs_cache_inode *cache_inode, uint32_t to,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2f430d3c/fs/nffs/src/nffs_write.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/nffs_write.c b/fs/nffs/src/nffs_write.c
index 5bcc655..8888016 100644
--- a/fs/nffs/src/nffs_write.c
+++ b/fs/nffs/src/nffs_write.c
@@ -210,7 +210,7 @@ nffs_write_over_block(struct nffs_hash_entry *entry, uint16_t left_copy_len,
  */
 static int
 nffs_write_append(struct nffs_cache_inode *cache_inode, const void *data,
-                 uint16_t len)
+                  uint16_t len)
 {
     struct nffs_inode_entry *inode_entry;
     struct nffs_hash_entry *entry;
@@ -271,10 +271,12 @@ nffs_write_append(struct nffs_cache_inode *cache_inode, const void *data,
  * @return                      0 on success; nonzero on failure.
  */
 static int
-nffs_write_chunk(struct nffs_cache_inode *cache_inode, uint32_t file_offset,
-                const void *data, uint16_t data_len)
+nffs_write_chunk(struct nffs_inode_entry *inode_entry, uint32_t file_offset,
+                 const void *data, uint16_t data_len)
 {
+    struct nffs_cache_inode *cache_inode;
     struct nffs_cache_block *cache_block;
+    unsigned int gc_count;
     uint32_t append_len;
     uint32_t data_offset;
     uint32_t block_end;
@@ -285,6 +287,11 @@ nffs_write_chunk(struct nffs_cache_inode *cache_inode, uint32_t file_offset,
 
     assert(data_len <= nffs_block_max_data_sz);
 
+    rc = nffs_cache_inode_ensure(&cache_inode, inode_entry);
+    if (rc != 0) {
+        return rc;
+    }
+
     /** Handle the simple append case first. */
     if (file_offset == cache_inode->nci_file_size) {
         rc = nffs_write_append(cache_inode, data, data_len);
@@ -324,6 +331,12 @@ nffs_write_chunk(struct nffs_cache_inode *cache_inode, uint32_t file_offset,
             chunk_sz += (int)(dst_off - block_end);
         }
 
+        /* Remember the current garbage collection count.  If the count
+         * increases during the write, then the block cache has been
+         * invalidated and we need to reset our pointers.
+         */
+        gc_count = nffs_gc_count;
+
         data_offset = cache_block->ncb_file_offset + chunk_off - file_offset;
         rc = nffs_write_over_block(cache_block->ncb_block.nb_hash_entry,
                                    chunk_off, data + data_offset, chunk_sz);
@@ -332,7 +345,16 @@ nffs_write_chunk(struct nffs_cache_inode *cache_inode, uint32_t file_offset,
         }
 
         dst_off -= chunk_sz;
-        cache_block = TAILQ_PREV(cache_block, nffs_cache_block_list, ncb_link);
+
+        if (gc_count != nffs_gc_count) {
+            /* Garbage collection occurred; the current cached block pointer is
+             * invalid, so reset it.  The cached inode is still valid.
+             */
+            cache_block = NULL;
+        } else {
+            cache_block = TAILQ_PREV(cache_block, nffs_cache_block_list,
+                                     ncb_link);
+        }
     } while (data_offset > 0);
 
     cache_inode->nci_file_size += append_len;
@@ -385,7 +407,7 @@ nffs_write_to_file(struct nffs_file *file, const void *data, int len)
             chunk_size = len;
         }
 
-        rc = nffs_write_chunk(cache_inode, file->nf_offset, data_ptr,
+        rc = nffs_write_chunk(file->nf_inode_entry, file->nf_offset, data_ptr,
                               chunk_size);
         if (rc != 0) {
             return rc;