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:09 UTC

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

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;
 }