You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2015/12/02 04:07:02 UTC

incubator-mynewt-larva git commit: Remove generic work queue; add hci batch queue.

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master b612bf4bb -> ddf578631


Remove generic work queue; add hci batch queue.


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

Branch: refs/heads/master
Commit: ddf5786319b3037f6fbd4ffdc68ad22ac9abc97d
Parents: b612bf4
Author: Christopher Collins <cc...@gmail.com>
Authored: Tue Dec 1 19:06:49 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Tue Dec 1 19:06:49 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_hs.h       |   4 +-
 net/nimble/host/include/host/host_hci.h     |   3 +-
 net/nimble/host/src/ble_gap.c               |  30 ++--
 net/nimble/host/src/ble_gap_conn.c          |   8 +-
 net/nimble/host/src/ble_hs.c                |  34 ++---
 net/nimble/host/src/ble_hs_att.c            |  11 ++
 net/nimble/host/src/ble_hs_att.h            |   9 ++
 net/nimble/host/src/ble_hs_att_batch.c      | 138 +++++++++++++------
 net/nimble/host/src/ble_hs_att_clt.c        |  87 +++++++++++-
 net/nimble/host/src/ble_hs_att_svr.c        |  39 ++----
 net/nimble/host/src/ble_hs_hci_batch.c      | 166 +++++++++++++++++++++++
 net/nimble/host/src/ble_hs_hci_batch.h      |  54 ++++++++
 net/nimble/host/src/ble_hs_work.c           | 110 ---------------
 net/nimble/host/src/ble_hs_work.h           |  53 --------
 net/nimble/host/src/host_hci.c              |  36 +----
 net/nimble/host/src/test/ble_gap_test.c     |   6 +-
 net/nimble/host/src/test/ble_hs_conn_test.c |  16 ++-
 net/nimble/host/src/test/ble_hs_test_util.c |   5 +-
 18 files changed, 497 insertions(+), 312 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/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 93bd714..f25f1f1 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -21,7 +21,7 @@
 struct os_mbuf;
 
 #define BLE_HOST_HCI_EVENT_CTLR_EVENT   (OS_EVENT_T_PERUSER + 0)
-#define BLE_HS_KICK_EVENT               (OS_EVENT_T_PERUSER + 1)
+#define BLE_HS_KICK_HCI_EVENT           (OS_EVENT_T_PERUSER + 1)
 #define BLE_HS_RX_DATA_EVENT            (OS_EVENT_T_PERUSER + 2)
 #define BLE_HS_TX_DATA_EVENT            (OS_EVENT_T_PERUSER + 3)
 
@@ -32,7 +32,7 @@ void ble_hs_process_tx_data_queue(void);
 void ble_hs_task_handler(void *arg);
 int ble_hs_rx_data(struct os_mbuf *om);
 int ble_hs_tx_data(struct os_mbuf *om);
-void ble_hs_kick(void);
+void ble_hs_kick_hci(void);
 int ble_hs_init(uint8_t prio);
 
 #endif /* _BLE_HOST_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/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 154e34f..f48dd76 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -21,7 +21,6 @@
 struct ble_hs_conn;
 struct os_mbuf;
 
-int host_hci_read_buf_size(void);
 int host_hci_os_event_proc(struct os_event *ev);
 int host_hci_event_rx(uint8_t *data);
 int host_hci_cmd_le_set_scan_rsp_data(uint8_t *data, uint8_t len);
@@ -41,6 +40,8 @@ int host_hci_cmd_le_read_whitelist(void);
 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);
 
+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);
 
 int host_hci_data_rx(struct os_mbuf *om);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/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 bac76e8..e970c61 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -18,7 +18,7 @@
 #include <errno.h>
 #include <string.h>
 #include "host/ble_gap.h"
-#include "ble_hs_work.h"
+#include "ble_hs_hci_batch.h"
 #include "ble_gap_conn.h"
 
 /**
@@ -52,19 +52,19 @@ ble_gap_set_connect_cb(ble_gap_connect_fn *cb, void *arg)
 int
 ble_gap_direct_connection_establishment(uint8_t addr_type, uint8_t *addr)
 {
-    struct ble_hs_work_entry *entry;
+    struct ble_hs_hci_batch_entry *entry;
 
-    entry = ble_hs_work_entry_alloc();
+    entry = ble_hs_hci_batch_entry_alloc();
     if (entry == NULL) {
         return ENOMEM;
     }
 
-    entry->bwe_type = BLE_HS_WORK_TYPE_DIRECT_CONNECT;
-    entry->bwe_direct_connect.bwdc_peer_addr_type = addr_type;
-    memcpy(entry->bwe_direct_connect.bwdc_peer_addr, addr,
-           sizeof entry->bwe_direct_connect.bwdc_peer_addr);
+    entry->bhb_type = BLE_HS_HCI_BATCH_TYPE_DIRECT_CONNECT;
+    entry->bhb_direct_connect.bwdc_peer_addr_type = addr_type;
+    memcpy(entry->bhb_direct_connect.bwdc_peer_addr, addr,
+           sizeof entry->bhb_direct_connect.bwdc_peer_addr);
 
-    ble_hs_work_enqueue(entry);
+    ble_hs_hci_batch_enqueue(entry);
 
     return 0;
 }
@@ -85,19 +85,19 @@ ble_gap_direct_connection_establishment(uint8_t addr_type, uint8_t *addr)
 int
 ble_gap_directed_connectable(uint8_t addr_type, uint8_t *addr)
 {
-    struct ble_hs_work_entry *entry;
+    struct ble_hs_hci_batch_entry *entry;
 
-    entry = ble_hs_work_entry_alloc();
+    entry = ble_hs_hci_batch_entry_alloc();
     if (entry == NULL) {
         return ENOMEM;
     }
 
-    entry->bwe_type = BLE_HS_WORK_TYPE_DIRECT_ADVERTISE;
-    entry->bwe_direct_advertise.bwda_peer_addr_type = addr_type;
-    memcpy(entry->bwe_direct_advertise.bwda_peer_addr, addr,
-           sizeof entry->bwe_direct_advertise.bwda_peer_addr);
+    entry->bhb_type = BLE_HS_HCI_BATCH_TYPE_DIRECT_ADVERTISE;
+    entry->bhb_direct_advertise.bwda_peer_addr_type = addr_type;
+    memcpy(entry->bhb_direct_advertise.bwda_peer_addr, addr,
+           sizeof entry->bhb_direct_advertise.bwda_peer_addr);
 
-    ble_hs_work_enqueue(entry);
+    ble_hs_hci_batch_enqueue(entry);
 
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_gap_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_conn.c b/net/nimble/host/src/ble_gap_conn.c
index c2ab8de..3a3953a 100644
--- a/net/nimble/host/src/ble_gap_conn.c
+++ b/net/nimble/host/src/ble_gap_conn.c
@@ -22,7 +22,7 @@
 #include "ble_hs_ack.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_ack.h"
-#include "ble_hs_work.h"
+#include "ble_hs_hci_batch.h"
 #include "ble_gap_conn.h"
 
 #define BLE_GAP_CONN_STATE_IDLE                     0
@@ -71,7 +71,7 @@ ble_gap_conn_notify_app(uint8_t status, struct ble_hs_conn *conn)
 /**
  * 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 work item can be processed.
+ * the host task that the next hci_batch item can be processed.
  */
 static void
 ble_gap_conn_master_failed(uint8_t status)
@@ -84,7 +84,7 @@ ble_gap_conn_master_failed(uint8_t status)
 /**
  * Called when an error is encountered while the slave-connection-fsm is
  * active.  Resets the state machine, clears the HCI ack callback, and notifies
- * the host task that the next work item can be processed.
+ * the host task that the next hci_batch item can be processed.
  */
 static void
 ble_gap_conn_slave_failed(uint8_t status)
@@ -108,6 +108,7 @@ ble_gap_conn_master_ack(struct ble_hs_ack *ack, void *arg)
         ble_gap_conn_master_failed(ack->bha_status);
     } else {
         ble_gap_conn_master_state = BLE_GAP_CONN_STATE_MASTER_DIRECT_ACKED;
+        ble_hs_hci_batch_done();
     }
 }
 
@@ -139,6 +140,7 @@ ble_gap_conn_slave_ack(struct ble_hs_ack *ack, void *arg)
             ble_gap_conn_slave_failed(ack->bha_status);
         } else {
             ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_SLAVE_ENABLE_ACKED;
+            ble_hs_hci_batch_done();
         }
         break;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/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 8665ab4..b751f20 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -23,7 +23,7 @@
 #include "ble_hs_att.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_ack.h"
-#include "ble_hs_work.h"
+#include "ble_hs_hci_batch.h"
 #include "ble_gap_conn.h"
 #ifdef PHONY_TRANSPORT
 #include "host/ble_hs_test.h"
@@ -68,7 +68,7 @@ struct os_mbuf_pool ble_hs_mbuf_pool;
 
 /* Host HCI Task Events */
 struct os_eventq ble_hs_evq;
-static struct os_event ble_hs_kick_ev;
+static struct os_event ble_hs_kick_hci_ev;
 
 
 struct ble_hs_pkt {
@@ -115,16 +115,16 @@ ble_hs_process_rx_data_queue(void)
 static int
 ble_hs_read_hci_buf_size(void)
 {
-    struct ble_hs_work_entry *entry;
+    struct ble_hs_hci_batch_entry *entry;
 
-    entry = ble_hs_work_entry_alloc();
+    entry = ble_hs_hci_batch_entry_alloc();
     if (entry == NULL) {
         return ENOMEM;
     }
 
-    entry->bwe_type = BLE_HS_WORK_TYPE_READ_HCI_BUF_SIZE;
+    entry->bhb_type = BLE_HS_HCI_BATCH_TYPE_READ_HCI_BUF_SIZE;
 
-    ble_hs_work_enqueue(entry);
+    ble_hs_hci_batch_enqueue(entry);
 
     return 0;
 }
@@ -161,18 +161,14 @@ ble_hs_task_handler(void *arg)
             ble_hs_process_tx_data_queue();
             break;
 
-        case BLE_HS_KICK_EVENT:
+        case BLE_HS_KICK_HCI_EVENT:
+            ble_hs_hci_batch_process_next();
             break;
 
         default:
             assert(0);
             break;
         }
-
-        /* Process all pending jobs in the work queue. */
-        do {
-            rc = ble_hs_work_process_next();
-        } while (rc == EAGAIN);
     }
 }
 
@@ -220,12 +216,12 @@ ble_hs_tx_data(struct os_mbuf *om)
 }
 
 /**
- * Wakes the BLE host task so that it can process work events.
+ * Wakes the BLE host task so that it can process hci_batch events.
  */
 void
-ble_hs_kick(void)
+ble_hs_kick_hci(void)
 {
-    os_eventq_put(&ble_hs_evq, &ble_hs_kick_ev);
+    os_eventq_put(&ble_hs_evq, &ble_hs_kick_hci_ev);
 }
 
 static void
@@ -326,14 +322,14 @@ ble_hs_init(uint8_t prio)
 
     ble_hs_ack_init();
 
-    rc = ble_hs_work_init();
+    rc = ble_hs_hci_batch_init();
     if (rc != 0) {
         goto err;
     }
 
-    ble_hs_kick_ev.ev_queued = 0;
-    ble_hs_kick_ev.ev_type = BLE_HS_KICK_EVENT;
-    ble_hs_kick_ev.ev_arg = NULL;
+    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;
 
     os_task_init(&ble_hs_task, "ble_hs", ble_hs_task_handler, NULL, prio,
                  OS_WAIT_FOREVER, ble_hs_stack, BLE_HS_STACK_SIZE);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_hs_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_att.c b/net/nimble/host/src/ble_hs_att.c
index 0aaef1f..7d20934 100644
--- a/net/nimble/host/src/ble_hs_att.c
+++ b/net/nimble/host/src/ble_hs_att.c
@@ -31,6 +31,7 @@ struct ble_hs_att_rx_dispatch_entry {
 
 static struct ble_hs_att_rx_dispatch_entry ble_hs_att_rx_dispatch[] = {
     { BLE_HS_ATT_OP_MTU_REQ,              ble_hs_att_svr_rx_mtu },
+    { BLE_HS_ATT_OP_MTU_RSP,              ble_hs_att_clt_rx_mtu },
     { BLE_HS_ATT_OP_FIND_INFO_REQ,        ble_hs_att_svr_rx_find_info },
     { BLE_HS_ATT_OP_FIND_INFO_RSP,        ble_hs_att_clt_rx_find_info },
     { BLE_HS_ATT_OP_FIND_TYPE_VALUE_REQ,  ble_hs_att_svr_rx_find_type_value },
@@ -88,6 +89,16 @@ ble_hs_att_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     return 0;
 }
 
+void
+ble_hs_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu)
+{
+    if (peer_mtu < BLE_HS_ATT_MTU_DFLT) {
+        peer_mtu = BLE_HS_ATT_MTU_DFLT;
+    }
+
+    chan->blc_peer_mtu = peer_mtu;
+}
+
 struct ble_l2cap_chan *
 ble_hs_att_create_chan(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_hs_att.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_att.h b/net/nimble/host/src/ble_hs_att.h
index 7a0da3e..1762e8e 100644
--- a/net/nimble/host/src/ble_hs_att.h
+++ b/net/nimble/host/src/ble_hs_att.h
@@ -24,6 +24,7 @@ struct ble_hs_conn;
 struct ble_l2cap_chan;
 struct ble_hs_att_find_info_req;
 struct ble_hs_att_error_rsp;
+struct ble_hs_att_mtu_cmd;
 
 #define BLE_HS_ATT_MTU_DFLT         23  /* Also the minimum. */
 #define BLE_HS_ATT_MTU_MAX          256 /* XXX: I'm making this up! */
@@ -109,6 +110,7 @@ SLIST_HEAD(ble_hs_att_clt_entry_list, ble_hs_att_clt_entry);
 
 /*** @gen */
 struct ble_l2cap_chan *ble_hs_att_create_chan(void);
+void ble_hs_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu);
 
 /*** @svr */
 int ble_hs_att_svr_register(uint8_t *uuid, uint8_t flags, uint16_t *handle_id,
@@ -143,6 +145,11 @@ uint16_t ble_hs_att_clt_find_entry_uuid128(struct ble_hs_conn *conn,
                                            void *uuid128);
 uint16_t ble_hs_att_clt_find_entry_uuid16(struct ble_hs_conn *conn,
                                           uint16_t uuid16);
+int ble_hs_att_clt_tx_mtu(struct ble_hs_conn *conn,
+                          struct ble_hs_att_mtu_cmd *req);
+int ble_hs_att_clt_rx_mtu(struct ble_hs_conn *conn,
+                          struct ble_l2cap_chan *chan,
+                          struct os_mbuf *om);
 int ble_hs_att_clt_tx_find_info(struct ble_hs_conn *conn,
                                 struct ble_hs_att_find_info_req *req);
 int ble_hs_att_clt_rx_find_info(struct ble_hs_conn *conn,
@@ -153,6 +160,8 @@ int ble_hs_att_clt_init(void);
 /*** @batch */
 void ble_hs_att_batch_rx_error(struct ble_hs_conn *conn,
                                struct ble_hs_att_error_rsp *rsp);
+void ble_hs_att_batch_rx_mtu(struct ble_hs_conn *conn, uint16_t peer_mtu);
+int ble_hs_att_batch_mtu(uint16_t conn_handle);
 void ble_hs_att_batch_rx_find_info(struct ble_hs_conn *conn, int status,
                                    uint16_t last_handle_id);
 int ble_hs_att_batch_find_info(uint16_t conn_handle_id,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_hs_att_batch.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_att_batch.c b/net/nimble/host/src/ble_hs_att_batch.c
index b885ce9..d715d29 100644
--- a/net/nimble/host/src/ble_hs_att_batch.c
+++ b/net/nimble/host/src/ble_hs_att_batch.c
@@ -25,7 +25,8 @@
 #include "ble_hs_att.h"
 
 #define BLE_HS_ATT_BATCH_OP_NONE            0
-#define BLE_HS_ATT_BATCH_OP_FIND_INFO       1
+#define BLE_HS_ATT_BATCH_OP_MTU             1
+#define BLE_HS_ATT_BATCH_OP_FIND_INFO       2
 
 struct ble_hs_att_batch_entry {
     SLIST_ENTRY(ble_hs_att_batch_entry) next;
@@ -34,9 +35,15 @@ struct ble_hs_att_batch_entry {
     uint16_t conn_handle;
     union {
         struct {
-            uint16_t start_handle;
+            int (*cb)(int status, uint16_t conn_handle, void *arg);
+            void *cb_arg;
+        } mtu;
+
+        struct {
             uint16_t end_handle;
-            /* XXX: Callback. */
+
+            int (*cb)(int status, uint16_t conn_handle, void *arg);
+            void *cb_arg;
         } find_info;
     };
 };
@@ -70,26 +77,55 @@ ble_hs_att_batch_entry_free(struct ble_hs_att_batch_entry *entry)
 }
 
 static struct ble_hs_att_batch_entry *
-ble_hs_att_batch_find(uint16_t conn_handle)
+ble_hs_att_batch_find(uint16_t conn_handle, uint8_t att_op)
 {
     struct ble_hs_att_batch_entry *entry;
 
     SLIST_FOREACH(entry, &ble_hs_att_batch_list, next) {
         if (entry->conn_handle == conn_handle) {
-            return entry;
+            if (att_op == entry->op || att_op == BLE_HS_ATT_BATCH_OP_NONE) {
+                return entry;
+            } else {
+                return NULL;
+            }
         }
     }
 
     return NULL;
 }
 
+static int
+ble_hs_att_batch_new_entry(uint16_t conn_handle,
+                           struct ble_hs_att_batch_entry **entry,
+                           struct ble_hs_conn **conn)
+{
+    *entry = NULL;
+
+    /* Ensure we have a connection with the specified handle. */
+    *conn = ble_hs_conn_find(conn_handle);
+    if (*conn == NULL) {
+        return ENOTCONN;
+    }
+
+    *entry = ble_hs_att_batch_entry_alloc();
+    if (*entry == NULL) {
+        return ENOMEM;
+    }
+
+    (*entry)->conn_handle = conn_handle;
+
+    SLIST_INSERT_HEAD(&ble_hs_att_batch_list, *entry, next);
+
+    return 0;
+}
+
 void
 ble_hs_att_batch_rx_error(struct ble_hs_conn *conn,
                           struct ble_hs_att_error_rsp *rsp)
 {
     struct ble_hs_att_batch_entry *entry;
 
-    entry = ble_hs_att_batch_find(conn->bhc_handle);
+    entry = ble_hs_att_batch_find(conn->bhc_handle, BLE_HS_ATT_BATCH_OP_NONE);
     if (entry == NULL) {
         /* Not expecting a response from this device. */
         return;
@@ -110,19 +146,68 @@ ble_hs_att_batch_rx_error(struct ble_hs_conn *conn,
 }
 
 void
-ble_hs_att_batch_rx_find_info(struct ble_hs_conn *conn, int status,
-                              uint16_t last_handle_id)
+ble_hs_att_batch_rx_mtu(struct ble_hs_conn *conn, uint16_t peer_mtu)
 {
     struct ble_hs_att_batch_entry *entry;
+    struct ble_l2cap_chan *chan;
 
-    entry = ble_hs_att_batch_find(conn->bhc_handle);
+    entry = ble_hs_att_batch_find(conn->bhc_handle, BLE_HS_ATT_BATCH_OP_MTU);
     if (entry == NULL) {
         /* Not expecting a response from this device. */
         return;
     }
 
-    if (entry->op != BLE_HS_ATT_BATCH_OP_FIND_INFO) {
-        /* Not expecting a find info response from this device. */
+    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+    assert(chan != NULL);
+
+    ble_hs_att_set_peer_mtu(chan, peer_mtu);
+
+    /* XXX: Call success callback. */
+}
+
+int
+ble_hs_att_batch_mtu(uint16_t conn_handle)
+{
+    struct ble_hs_att_mtu_cmd req;
+    struct ble_hs_att_batch_entry *entry;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    rc = ble_hs_att_batch_new_entry(conn_handle, &entry, &conn);
+    if (rc != 0) {
+        goto err;
+    }
+    entry->op = BLE_HS_ATT_BATCH_OP_MTU;
+
+    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+
+    req.bhamc_mtu = chan->blc_my_mtu;
+    rc = ble_hs_att_clt_tx_mtu(conn, &req);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return 0;
+
+err:
+    if (entry != NULL) {
+        SLIST_REMOVE_HEAD(&ble_hs_att_batch_list, next);
+        ble_hs_att_batch_entry_free(entry);
+    }
+    return rc;
+}
+
+void
+ble_hs_att_batch_rx_find_info(struct ble_hs_conn *conn, int status,
+                              uint16_t last_handle_id)
+{
+    struct ble_hs_att_batch_entry *entry;
+
+    entry = ble_hs_att_batch_find(conn->bhc_handle,
+                                  BLE_HS_ATT_BATCH_OP_FIND_INFO);
+    if (entry == NULL) {
+        /* Not expecting a response from this device. */
         return;
     }
 
@@ -132,7 +217,8 @@ ble_hs_att_batch_rx_find_info(struct ble_hs_conn *conn, int status,
     }
 
     if (last_handle_id == 0xffff) {
-        /* Call success callback. */
+        /* XXX: Call success callback. */
+        return;
     }
 
     /* XXX: Send follow up request. */
@@ -143,42 +229,18 @@ ble_hs_att_batch_find_info(uint16_t conn_handle, uint16_t att_start_handle,
                            uint16_t att_end_handle)
 {
     struct ble_hs_att_find_info_req req;
-    struct ble_hs_att_batch_entry *existing_entry;
     struct ble_hs_att_batch_entry *entry;
     struct ble_hs_conn *conn;
     int rc;
 
-    entry = NULL;
-
-    /* Ensure we have a connection with the specified handle. */
-    conn = ble_hs_conn_find(conn_handle);
-    if (conn == NULL) {
-        rc = ENOTCONN;
-        goto err;
-    }
-
-    /* Ensure there isn't already an ATT job in progress for this
-     * connection.
-     */
-    existing_entry = ble_hs_att_batch_find(conn_handle);
-    if (existing_entry != NULL) {
-        rc = EALREADY;
-        goto err;
-    }
-
-    entry = ble_hs_att_batch_entry_alloc();
-    if (entry == NULL) {
-        rc = ENOMEM;
+    rc = ble_hs_att_batch_new_entry(conn_handle, &entry, &conn);
+    if (rc != 0) {
         goto err;
     }
-
     entry->op = BLE_HS_ATT_BATCH_OP_FIND_INFO;
     entry->conn_handle = conn_handle;
-    entry->find_info.start_handle = att_start_handle;
     entry->find_info.end_handle = att_end_handle;
 
-    SLIST_INSERT_HEAD(&ble_hs_att_batch_list, entry, next);
-
     req.bhafq_start_handle = att_start_handle;
     req.bhafq_end_handle = att_end_handle;
     rc = ble_hs_att_clt_tx_find_info(conn, &req);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_hs_att_clt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_att_clt.c b/net/nimble/host/src/ble_hs_att_clt.c
index 5ad2dd5..fbc9809 100644
--- a/net/nimble/host/src/ble_hs_att_clt.c
+++ b/net/nimble/host/src/ble_hs_att_clt.c
@@ -118,6 +118,21 @@ ble_hs_att_clt_find_entry_uuid128(struct ble_hs_conn *conn, void *uuid128)
     return 0;
 }
 
+static int
+ble_hs_att_clt_prep_req(struct ble_hs_conn *conn, struct ble_l2cap_chan **chan,
+                        struct os_mbuf **txom)
+{
+    *chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+    assert(*chan != NULL);
+
+    *txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    if (*txom == NULL) {
+        return ENOMEM;
+    }
+
+    return 0;
+}
+
 uint16_t
 ble_hs_att_clt_find_entry_uuid16(struct ble_hs_conn *conn, uint16_t uuid16)
 {
@@ -135,6 +150,70 @@ ble_hs_att_clt_find_entry_uuid16(struct ble_hs_conn *conn, uint16_t uuid16)
 }
 
 int
+ble_hs_att_clt_tx_mtu(struct ble_hs_conn *conn, struct ble_hs_att_mtu_cmd *req)
+{
+    struct ble_l2cap_chan *chan;
+    struct os_mbuf *txom;
+    void *buf;
+    int rc;
+
+    txom = NULL;
+
+    if (req->bhamc_mtu < BLE_HS_ATT_MTU_DFLT) {
+        rc = EINVAL;
+        goto err;
+    }
+
+    rc = ble_hs_att_clt_prep_req(conn, &chan, &txom);
+    if (rc != 0) {
+        goto err;
+    }
+
+    buf = os_mbuf_extend(txom, BLE_HS_ATT_MTU_CMD_SZ);
+    if (buf == NULL) {
+        rc = ENOMEM;
+        goto err;
+    }
+
+    rc = ble_hs_att_mtu_req_write(buf, BLE_HS_ATT_MTU_CMD_SZ, req);
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = ble_l2cap_tx(chan, txom);
+    txom = NULL;
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = 0;
+
+err:
+    os_mbuf_free_chain(txom);
+    return rc;
+}
+
+int
+ble_hs_att_clt_rx_mtu(struct ble_hs_conn *conn,
+                      struct ble_l2cap_chan *chan,
+                      struct os_mbuf *om)
+{
+    struct ble_hs_att_mtu_cmd rsp;
+    int rc;
+
+    /* XXX: Pull up om */
+
+    rc = ble_hs_att_mtu_cmd_parse(om->om_data, om->om_len, &rsp);
+    if (rc != 0) {
+        return rc;
+    }
+
+    ble_hs_att_batch_rx_mtu(conn, rsp.bhamc_mtu);
+
+    return 0;
+}
+
+int
 ble_hs_att_clt_tx_find_info(struct ble_hs_conn *conn,
                             struct ble_hs_att_find_info_req *req)
 {
@@ -152,12 +231,8 @@ ble_hs_att_clt_tx_find_info(struct ble_hs_conn *conn,
         goto err;
     }
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    assert(chan != NULL);
-
-    txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
-    if (txom == NULL) {
-        rc = ENOMEM;
+    rc = ble_hs_att_clt_prep_req(conn, &chan, &txom);
+    if (rc != 0) {
         goto err;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_hs_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_att_svr.c b/net/nimble/host/src/ble_hs_att_svr.c
index a03b8cd..8b9dcb3 100644
--- a/net/nimble/host/src/ble_hs_att_svr.c
+++ b/net/nimble/host/src/ble_hs_att_svr.c
@@ -114,7 +114,7 @@ ble_hs_att_svr_next_id(void)
  */
 int
 ble_hs_att_svr_register(uint8_t *uuid, uint8_t flags, uint16_t *handle_id,
-                    ble_hs_att_svr_handle_func *fn)
+                        ble_hs_att_svr_handle_func *fn)
 {
     struct ble_hs_att_svr_entry *entry;
 
@@ -315,7 +315,6 @@ ble_hs_att_svr_tx_mtu_rsp(struct ble_l2cap_chan *chan, uint8_t op,
     void *dst;
     int rc;
 
-    assert(!(chan->blc_flags & BLE_L2CAP_CHAN_F_TXED_MTU));
     assert(op == BLE_HS_ATT_OP_MTU_REQ || op == BLE_HS_ATT_OP_MTU_RSP);
     assert(mtu >= BLE_HS_ATT_MTU_DFLT);
 
@@ -356,21 +355,14 @@ ble_hs_att_svr_rx_mtu(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                       struct os_mbuf *om)
 {
     struct ble_hs_att_mtu_cmd cmd;
-    uint8_t buf[BLE_HS_ATT_MTU_CMD_SZ];
     int rc;
 
-    rc = os_mbuf_copydata(om, 0, sizeof buf, buf);
-    assert(rc == 0);
+    /* XXX: Pull up om. */
 
-    rc = ble_hs_att_mtu_cmd_parse(buf, sizeof buf, &cmd);
+    rc = ble_hs_att_mtu_cmd_parse(om->om_data, om->om_len, &cmd);
     assert(rc == 0);
 
-    if (cmd.bhamc_mtu < BLE_HS_ATT_MTU_DFLT) {
-        cmd.bhamc_mtu = BLE_HS_ATT_MTU_DFLT;
-    }
-
-    chan->blc_peer_mtu = cmd.bhamc_mtu;
-
+    ble_hs_att_set_peer_mtu(chan, cmd.bhamc_mtu);
     rc = ble_hs_att_svr_tx_mtu_rsp(chan, BLE_HS_ATT_OP_MTU_RSP,
                                    chan->blc_my_mtu);
     if (rc != 0) {
@@ -507,23 +499,20 @@ ble_hs_att_svr_rx_find_info(struct ble_hs_conn *conn,
     struct ble_hs_att_find_info_req req;
     struct ble_hs_att_find_info_rsp rsp;
     struct os_mbuf *txom;
-    uint8_t buf[max(BLE_HS_ATT_FIND_INFO_REQ_SZ,
-                    BLE_HS_ATT_FIND_INFO_RSP_MIN_SZ)];
+    void *buf;
     int rc;
 
     txom = NULL;
 
-    rc = os_mbuf_copydata(rxom, 0, BLE_HS_ATT_FIND_INFO_REQ_SZ, buf);
+    /* XXX: Pull up rxom. */
+
+    rc = ble_hs_att_find_info_req_parse(rxom->om_data, rxom->om_len, &req);
     if (rc != 0) {
         req.bhafq_start_handle = 0;
         rc = BLE_HS_ATT_ERR_INVALID_PDU;
         goto err;
     }
 
-    rc = ble_hs_att_find_info_req_parse(buf, BLE_HS_ATT_FIND_INFO_REQ_SZ,
-                                        &req);
-    assert(rc == 0);
-
     /* Tx error response if start handle is greater than end handle or is equal
      * to 0 (Vol. 3, Part F, 3.4.3.1).
      */
@@ -543,16 +532,16 @@ ble_hs_att_svr_rx_find_info(struct ble_hs_conn *conn,
     /* Write the response base at the start of the buffer.  The format field is
      * unknown at this point; it will be filled in later.
      */
-    rc = ble_hs_att_find_info_rsp_write(buf, BLE_HS_ATT_FIND_INFO_RSP_MIN_SZ,
-                                        &rsp);
-    assert(rc == 0);
-    rc = os_mbuf_append(txom, buf,
-                        BLE_HS_ATT_FIND_INFO_RSP_MIN_SZ);
-    if (rc != 0) {
+    buf = os_mbuf_extend(txom, BLE_HS_ATT_FIND_INFO_RSP_MIN_SZ);
+    if (buf == NULL) {
         rc = BLE_HS_ATT_ERR_INSUFFICIENT_RES;
         goto err;
     }
 
+    rc = ble_hs_att_find_info_rsp_write(buf, BLE_HS_ATT_FIND_INFO_RSP_MIN_SZ,
+                                        &rsp);
+    assert(rc == 0);
+
     /* Write the variable length Information Data field, populating the format
      * field as appropriate.
      */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_hs_hci_batch.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_hci_batch.c b/net/nimble/host/src/ble_hs_hci_batch.c
new file mode 100644
index 0000000..09f0e7d
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_hci_batch.c
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed 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 <errno.h>
+#include "os/os.h"
+#include "host/host_hci.h"
+#include "host/ble_hs.h"
+#include "ble_hs_ack.h"
+#include "ble_gap_conn.h"
+#include "ble_hs_hci_batch.h"
+
+#define BLE_HS_HCI_BATCH_NUM_ENTRIES     16
+
+static void *ble_hs_hci_batch_entry_mem;
+static struct os_mempool ble_hs_hci_batch_entry_pool;
+static STAILQ_HEAD(, ble_hs_hci_batch_entry) ble_hs_hci_batch_queue;
+
+static struct ble_hs_hci_batch_entry *ble_hs_hci_batch_cur_entry;
+
+struct ble_hs_hci_batch_entry *
+ble_hs_hci_batch_entry_alloc(void)
+{
+    struct ble_hs_hci_batch_entry *entry;
+
+    entry = os_memblock_get(&ble_hs_hci_batch_entry_pool);
+    return entry;
+}
+
+void
+ble_hs_hci_batch_enqueue(struct ble_hs_hci_batch_entry *entry)
+{
+    STAILQ_INSERT_TAIL(&ble_hs_hci_batch_queue, entry, bhb_next);
+    if (ble_hs_hci_batch_cur_entry == NULL) {
+        ble_hs_kick_hci();
+    }
+}
+
+void
+ble_hs_hci_batch_done(void)
+{
+    assert(ble_hs_hci_batch_cur_entry != NULL);
+    os_memblock_put(&ble_hs_hci_batch_entry_pool, ble_hs_hci_batch_cur_entry);
+    ble_hs_hci_batch_cur_entry = NULL;
+
+    if (!STAILQ_EMPTY(&ble_hs_hci_batch_queue)) {
+        ble_hs_kick_hci();
+    }
+}
+
+static void
+ble_hs_hci_read_buf_size_ack(struct ble_hs_ack *ack, void *arg)
+{
+    uint16_t pktlen;
+    uint8_t max_pkts;
+    int rc;
+
+    if (ack->bha_status != 0) {
+        /* XXX: Log / stat this. */
+        return;
+    }
+
+    if (ack->bha_params_len != BLE_HCI_RD_BUF_SIZE_RSPLEN + 1) {
+        /* XXX: Log / stat this. */
+        return;
+    }
+
+    pktlen = le16toh(ack->bha_params + 1);
+    max_pkts = ack->bha_params[3];
+
+    rc = host_hci_set_buf_size(pktlen, max_pkts);
+    if (rc != 0) {
+        /* XXX: Send BR command instead. */
+        return;
+    }
+
+    ble_hs_hci_batch_done();
+}
+
+void
+ble_hs_hci_batch_process_next(void)
+{
+    struct ble_hs_hci_batch_entry *entry;
+    int rc;
+
+    entry = STAILQ_FIRST(&ble_hs_hci_batch_queue);
+    if (entry == NULL) {
+        return;
+    }
+
+    STAILQ_REMOVE_HEAD(&ble_hs_hci_batch_queue, bhb_next);
+    ble_hs_hci_batch_cur_entry = entry;
+
+    switch (entry->bhb_type) {
+    case BLE_HS_HCI_BATCH_TYPE_DIRECT_CONNECT:
+        rc = ble_gap_conn_direct_connect(
+            entry->bhb_direct_connect.bwdc_peer_addr_type,
+            entry->bhb_direct_connect.bwdc_peer_addr);
+        break;
+
+    case BLE_HS_HCI_BATCH_TYPE_DIRECT_ADVERTISE:
+        rc = ble_gap_conn_direct_advertise(
+            entry->bhb_direct_advertise.bwda_peer_addr_type,
+            entry->bhb_direct_advertise.bwda_peer_addr);
+        break;
+
+    case BLE_HS_HCI_BATCH_TYPE_READ_HCI_BUF_SIZE:
+        ble_hs_ack_set_callback(ble_hs_hci_read_buf_size_ack, NULL);
+        rc = host_hci_cmd_le_read_buffer_size();
+        if (rc != 0) {
+            /* XXX: Call callback. */
+        }
+        break;
+
+    default:
+        assert(0);
+        break;
+    }
+
+    if (rc != 0) {
+        ble_hs_hci_batch_done();
+    }
+}
+
+int
+ble_hs_hci_batch_init(void)
+{
+    int rc;
+
+    free(ble_hs_hci_batch_entry_mem);
+    ble_hs_hci_batch_entry_mem = malloc(
+        OS_MEMPOOL_BYTES(BLE_HS_HCI_BATCH_NUM_ENTRIES,
+                         sizeof (struct ble_hs_hci_batch_entry)));
+    if (ble_hs_hci_batch_entry_mem == NULL) {
+        return ENOMEM;
+    }
+
+    rc = os_mempool_init(&ble_hs_hci_batch_entry_pool,
+                         BLE_HS_HCI_BATCH_NUM_ENTRIES,
+                         sizeof (struct ble_hs_hci_batch_entry),
+                         ble_hs_hci_batch_entry_mem,
+                         "ble_hs_hci_batch_entry_pool");
+    if (rc != 0) {
+        return EINVAL; // XXX
+    }
+
+    STAILQ_INIT(&ble_hs_hci_batch_queue);
+
+    ble_hs_hci_batch_cur_entry = NULL;
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_hs_hci_batch.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_hci_batch.h b/net/nimble/host/src/ble_hs_hci_batch.h
new file mode 100644
index 0000000..3d0a4e7
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_hci_batch.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed 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_BATCH_
+#define H_BLE_HCI_BATCH_
+
+#include <inttypes.h>
+#include "os/queue.h"
+
+#define BLE_HS_HCI_BATCH_TYPE_DIRECT_CONNECT     0
+#define BLE_HS_HCI_BATCH_TYPE_DIRECT_ADVERTISE   1
+#define BLE_HS_HCI_BATCH_TYPE_READ_HCI_BUF_SIZE  2
+#define BLE_HS_HCI_BATCH_TYPE_MAX                3
+
+struct ble_hs_hci_batch_direct_connect {
+    uint8_t bwdc_peer_addr[8];
+    uint8_t bwdc_peer_addr_type;
+};
+
+struct ble_hs_hci_batch_direct_advertise {
+    uint8_t bwda_peer_addr[8];
+    uint8_t bwda_peer_addr_type;
+};
+
+struct ble_hs_hci_batch_entry {
+    int bhb_type;
+    STAILQ_ENTRY(ble_hs_hci_batch_entry) bhb_next;
+
+    union {
+        struct ble_hs_hci_batch_direct_connect bhb_direct_connect;
+        struct ble_hs_hci_batch_direct_advertise bhb_direct_advertise;
+    };
+};
+
+struct ble_hs_hci_batch_entry *ble_hs_hci_batch_entry_alloc(void);
+void ble_hs_hci_batch_enqueue(struct ble_hs_hci_batch_entry *entry);
+void ble_hs_hci_batch_done(void);
+void ble_hs_hci_batch_process_next(void);
+int ble_hs_hci_batch_init(void);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_hs_work.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_work.c b/net/nimble/host/src/ble_hs_work.c
deleted file mode 100644
index e971aa5..0000000
--- a/net/nimble/host/src/ble_hs_work.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed 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 <errno.h>
-#include "os/os.h"
-#include "host/host_hci.h"
-#include "host/ble_hs.h"
-#include "ble_gap_conn.h"
-#include "ble_hs_work.h"
-
-#define BLE_HS_WORK_NUM_ENTRIES     16
-
-static void *ble_hs_work_entry_mem;
-static struct os_mempool ble_hs_work_entry_pool;
-static STAILQ_HEAD(, ble_hs_work_entry) ble_hs_work_queue;
-
-struct ble_hs_work_entry *
-ble_hs_work_entry_alloc(void)
-{
-    struct ble_hs_work_entry *entry;
-
-    entry = os_memblock_get(&ble_hs_work_entry_pool);
-    return entry;
-}
-
-void
-ble_hs_work_enqueue(struct ble_hs_work_entry *entry)
-{
-    STAILQ_INSERT_TAIL(&ble_hs_work_queue, entry, bwe_next);
-    ble_hs_kick();
-}
-
-int
-ble_hs_work_process_next(void)
-{
-    struct ble_hs_work_entry *entry;
-
-    entry = STAILQ_FIRST(&ble_hs_work_queue);
-    if (entry == NULL) {
-        return 0;
-    }
-
-    STAILQ_REMOVE_HEAD(&ble_hs_work_queue, bwe_next);
-
-    switch (entry->bwe_type) {
-    case BLE_HS_WORK_TYPE_DIRECT_CONNECT:
-        ble_gap_conn_direct_connect(
-            entry->bwe_direct_connect.bwdc_peer_addr_type,
-            entry->bwe_direct_connect.bwdc_peer_addr);
-        break;
-
-    case BLE_HS_WORK_TYPE_DIRECT_ADVERTISE:
-        ble_gap_conn_direct_advertise(
-            entry->bwe_direct_advertise.bwda_peer_addr_type,
-            entry->bwe_direct_advertise.bwda_peer_addr);
-        break;
-
-    case BLE_HS_WORK_TYPE_READ_HCI_BUF_SIZE:
-        host_hci_read_buf_size();
-        break;
-
-    default:
-        assert(0);
-        break;
-    }
-
-    os_memblock_put(&ble_hs_work_entry_pool, entry);
-
-    return EAGAIN;
-}
-
-int
-ble_hs_work_init(void)
-{
-    int rc;
-
-    free(ble_hs_work_entry_mem);
-    ble_hs_work_entry_mem = malloc(
-        OS_MEMPOOL_BYTES(BLE_HS_WORK_NUM_ENTRIES,
-                         sizeof (struct ble_hs_work_entry)));
-    if (ble_hs_work_entry_mem == NULL) {
-        return ENOMEM;
-    }
-
-    rc = os_mempool_init(&ble_hs_work_entry_pool, BLE_HS_WORK_NUM_ENTRIES,
-                         sizeof (struct ble_hs_work_entry),
-                         ble_hs_work_entry_mem, "ble_hs_work_entry_pool");
-    if (rc != 0) {
-        return EINVAL; // XXX
-    }
-
-    STAILQ_INIT(&ble_hs_work_queue);
-
-    return 0;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/net/nimble/host/src/ble_hs_work.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_work.h b/net/nimble/host/src/ble_hs_work.h
deleted file mode 100644
index 7b9a554..0000000
--- a/net/nimble/host/src/ble_hs_work.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed 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_WORK_
-#define H_BLE_WORK_
-
-#include <inttypes.h>
-#include "os/queue.h"
-
-#define BLE_HS_WORK_TYPE_DIRECT_CONNECT     0
-#define BLE_HS_WORK_TYPE_DIRECT_ADVERTISE   1
-#define BLE_HS_WORK_TYPE_READ_HCI_BUF_SIZE  2
-#define BLE_HS_WORK_TYPE_MAX                3
-
-struct ble_hs_work_direct_connect {
-    uint8_t bwdc_peer_addr[8];
-    uint8_t bwdc_peer_addr_type;
-};
-
-struct ble_hs_work_direct_advertise {
-    uint8_t bwda_peer_addr[8];
-    uint8_t bwda_peer_addr_type;
-};
-
-struct ble_hs_work_entry {
-    int bwe_type;
-    STAILQ_ENTRY(ble_hs_work_entry) bwe_next;
-
-    union {
-        struct ble_hs_work_direct_connect bwe_direct_connect;
-        struct ble_hs_work_direct_advertise bwe_direct_advertise;
-    };
-};
-
-struct ble_hs_work_entry *ble_hs_work_entry_alloc(void);
-void ble_hs_work_enqueue(struct ble_hs_work_entry *entry);
-int ble_hs_work_process_next(void);
-int ble_hs_work_init(void);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/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 52295be..bb82d94 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -26,7 +26,6 @@
 #include "host/ble_hs.h"
 #include "host_dbg.h"
 #include "ble_hs_conn.h"
-#include "ble_hs_work.h"
 #include "ble_l2cap.h"
 #include "ble_hs_ack.h"
 #include "ble_gap_conn.h"
@@ -304,44 +303,15 @@ host_hci_rx_le_conn_complete(uint8_t subevent, uint8_t *data, int len)
     return 0;
 }
 
-static void
-host_hci_rx_read_buf_size_ack(struct ble_hs_ack *ack, void *arg)
+int
+host_hci_set_buf_size(uint16_t pktlen, uint8_t max_pkts)
 {
-    uint16_t pktlen;
-    uint8_t max_pkts;
-
-    if (ack->bha_status != 0) {
-        /* XXX: Log / stat this. */
-        return;
-    }
-
-    if (ack->bha_params_len != BLE_HCI_RD_BUF_SIZE_RSPLEN + 1) {
-        /* XXX: Log / stat this. */
-        return;
-    }
-
-    pktlen = le16toh(ack->bha_params + 1);
-    max_pkts = ack->bha_params[3];
-
     if (pktlen == 0 || max_pkts == 0) {
-        /* XXX: Send BR command instead. */
-        return;
+        return EINVAL;
     }
 
     host_hci_buffer_sz = pktlen;
     host_hci_max_pkts = max_pkts;
-}
-
-int
-host_hci_read_buf_size(void)
-{
-    int rc;
-
-    ble_hs_ack_set_callback(host_hci_rx_read_buf_size_ack, NULL);
-    rc = host_hci_cmd_le_read_buffer_size();
-    if (rc != 0) {
-        return rc;
-    }
 
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/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 4be9147..b769dc8 100644
--- a/net/nimble/host/src/test/ble_gap_test.c
+++ b/net/nimble/host/src/test/ble_gap_test.c
@@ -24,7 +24,7 @@
 #include "host/ble_gap.h"
 #include "ble_hs_test_util.h"
 #include "ble_hs_conn.h"
-#include "ble_hs_work.h"
+#include "ble_hs_hci_batch.h"
 #include "ble_gap_conn.h"
 
 #ifdef ARCH_sim
@@ -121,13 +121,13 @@ TEST_CASE(ble_gap_test_case)
 {
     os_init();
 
+    ble_hs_test_util_init();
+
     os_task_init(&ble_gap_test_task, "ble_gap_test_task",
                  ble_gap_test_task_handler, NULL,
                  BLE_GAP_TEST_HS_PRIO + 1, OS_WAIT_FOREVER, ble_gap_test_stack,
                  OS_STACK_ALIGN(BLE_GAP_TEST_STACK_SIZE));
 
-    ble_hs_test_util_init();
-
     os_start();
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/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 e1f6186..5dc46d5 100644
--- a/net/nimble/host/src/test/ble_hs_conn_test.c
+++ b/net/nimble/host/src/test/ble_hs_conn_test.c
@@ -25,6 +25,7 @@
 #include "ble_hs_att.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_ack.h"
+#include "ble_hs_hci_batch.h"
 #include "ble_gap_conn.h"
 #include "ble_hs_test_util.h"
 #include "testutil/testutil.h"
@@ -44,8 +45,11 @@ TEST_CASE(ble_hs_conn_test_master_direct_success)
     TEST_ASSERT(ble_hs_conn_first() == NULL);
 
     /* Initiate connection. */
-    rc = ble_gap_conn_direct_connect(0, addr);
+    rc = ble_gap_direct_connection_establishment(0, addr);
     TEST_ASSERT(rc == 0);
+
+    ble_hs_hci_batch_process_next();
+
     TEST_ASSERT(ble_gap_conn_master_in_progress());
 
     /* Receive command status event. */
@@ -87,8 +91,11 @@ TEST_CASE(ble_hs_conn_test_master_direct_hci_errors)
     TEST_ASSERT(ble_hs_conn_first() == NULL);
 
     /* Initiate connection. */
-    rc = ble_gap_conn_direct_connect(0, addr);
+    rc = ble_gap_direct_connection_establishment(0, addr);
     TEST_ASSERT(rc == 0);
+
+    ble_hs_hci_batch_process_next();
+
     TEST_ASSERT(ble_gap_conn_master_in_progress());
 
     /* Receive connection complete event without intervening command status. */
@@ -129,8 +136,11 @@ TEST_CASE(ble_hs_conn_test_slave_direct_success)
     TEST_ASSERT(ble_hs_conn_first() == NULL);
 
     /* Initiate advertising. */
-    rc = ble_gap_conn_direct_advertise(0, addr);
+    rc = ble_gap_directed_connectable(0, addr);
     TEST_ASSERT(rc == 0);
+
+    ble_hs_hci_batch_process_next();
+
     TEST_ASSERT(!ble_gap_conn_master_in_progress());
     TEST_ASSERT(ble_gap_conn_slave_in_progress());
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ddf57863/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 0eb2371..53974dd 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -24,6 +24,7 @@
 #include "ble_hs_ack.h"
 #include "ble_hs_conn.h"
 #include "ble_gap_conn.h"
+#include "ble_hs_hci_batch.h"
 #include "ble_l2cap.h"
 #include "ble_hs_test_util.h"
 
@@ -62,9 +63,11 @@ ble_hs_test_util_create_conn(uint16_t handle, uint8_t *addr)
     struct hci_le_conn_complete evt;
     int rc;
 
-    rc = ble_gap_conn_direct_connect(0, addr);
+    rc = ble_gap_direct_connection_establishment(0, addr);
     TEST_ASSERT(rc == 0);
 
+    ble_hs_hci_batch_process_next();
+
     ble_hs_test_util_rx_le_ack(BLE_HCI_OCF_LE_CREATE_CONN, BLE_ERR_SUCCESS);
 
     memset(&evt, 0, sizeof evt);