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/03 00:15:25 UTC

incubator-mynewt-larva git commit: Initial GATT work.

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 4c1031604 -> 41db2873e


Initial GATT work.


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

Branch: refs/heads/master
Commit: 41db2873e957b70864d66be6b0fe4616cd226c0b
Parents: 4c10316
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Dec 2 15:15:08 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Dec 2 15:15:08 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_gatt.h |  19 ++
 net/nimble/host/include/host/ble_hs.h   |   6 +-
 net/nimble/host/src/ble_gatt.c          | 430 +++++++++++++++++++++++++++
 net/nimble/host/src/ble_hs.c            |  21 +-
 net/nimble/host/src/ble_hs_att.h        |  12 -
 net/nimble/host/src/ble_hs_att_batch.c  | 294 ------------------
 net/nimble/host/src/ble_hs_att_clt.c    |   7 +-
 7 files changed, 477 insertions(+), 312 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/41db2873/net/nimble/host/include/host/ble_gatt.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gatt.h b/net/nimble/host/include/host/ble_gatt.h
new file mode 100644
index 0000000..50ed37d
--- /dev/null
+++ b/net/nimble/host/include/host/ble_gatt.h
@@ -0,0 +1,19 @@
+#ifndef H_BLE_GATT_
+#define H_BLE_GATT_
+
+#include <inttypes.h>
+struct ble_hs_conn;
+struct ble_hs_att_error_rsp;
+
+void ble_gatt_rx_error(struct ble_hs_conn *conn,
+                       struct ble_hs_att_error_rsp *rsp);
+void ble_gatt_wakeup(void);
+void ble_gatt_rx_mtu(struct ble_hs_conn *conn, uint16_t chan_mtu);
+int ble_gatt_mtu(uint16_t conn_handle);
+void ble_gatt_rx_find_info(struct ble_hs_conn *conn, int status,
+                           uint16_t last_handle_id);
+int ble_gatt_find_info(uint16_t conn_handle_id, uint16_t att_start_handle,
+                       uint16_t att_end_handle);
+int ble_gatt_init(void);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/41db2873/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 f25f1f1..63411a0 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -22,8 +22,9 @@ struct os_mbuf;
 
 #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_RX_DATA_EVENT            (OS_EVENT_T_PERUSER + 2)
-#define BLE_HS_TX_DATA_EVENT            (OS_EVENT_T_PERUSER + 3)
+#define BLE_HS_KICK_GATT_EVENT          (OS_EVENT_T_PERUSER + 2)
+#define BLE_HS_RX_DATA_EVENT            (OS_EVENT_T_PERUSER + 3)
+#define BLE_HS_TX_DATA_EVENT            (OS_EVENT_T_PERUSER + 4)
 
 extern struct os_mbuf_pool ble_hs_mbuf_pool;
 extern struct os_eventq ble_hs_evq;
@@ -33,6 +34,7 @@ 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_hci(void);
+void ble_hs_kick_gatt(void);
 int ble_hs_init(uint8_t prio);
 
 #endif /* _BLE_HOST_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/41db2873/net/nimble/host/src/ble_gatt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatt.c b/net/nimble/host/src/ble_gatt.c
new file mode 100644
index 0000000..1533317
--- /dev/null
+++ b/net/nimble/host/src/ble_gatt.c
@@ -0,0 +1,430 @@
+/**
+ * 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 <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include "os/os_mempool.h"
+#include "host/ble_gatt.h"
+#include "host/ble_hs.h"
+#include "ble_hs_conn.h"
+#include "ble_hs_att_cmd.h"
+#include "ble_hs_att.h"
+
+struct ble_gatt_entry {
+    STAILQ_ENTRY(ble_gatt_entry) next;
+
+    uint8_t op;
+    uint8_t flags;
+    uint16_t conn_handle;
+    union {
+        struct {
+            int (*cb)(int status, uint16_t conn_handle, void *arg);
+            void *cb_arg;
+        } mtu;
+
+        struct {
+            uint16_t next_handle;
+            uint16_t end_handle;
+
+            int (*cb)(int status, uint16_t conn_handle, void *arg);
+            void *cb_arg;
+        } find_info;
+    };
+};
+
+#define BLE_GATT_OP_NONE           UINT8_MAX
+#define BLE_GATT_OP_MTU            0
+#define BLE_GATT_OP_FIND_INFO      1
+#define BLE_GATT_OP_MAX            2
+
+typedef int ble_gatt_kick_fn(struct ble_gatt_entry *entry);
+
+static int ble_gatt_kick_mtu(struct ble_gatt_entry *entry);
+static int ble_gatt_kick_find_info(struct ble_gatt_entry *entry);
+
+static ble_gatt_kick_fn *ble_gatt_kick_fns[BLE_GATT_OP_MAX] = {
+    [BLE_GATT_OP_MTU] =        ble_gatt_kick_mtu,
+    [BLE_GATT_OP_FIND_INFO] =  ble_gatt_kick_find_info,
+};
+
+#define BLE_GATT_ENTRY_F_PENDING    0x01
+#define BLE_GATT_ENTRY_F_EXPECTING  0x02
+
+#define BLE_GATT_NUM_ENTRIES          4
+static void *ble_gatt_entry_mem;
+static struct os_mempool ble_gatt_entry_pool;
+
+static STAILQ_HEAD(, ble_gatt_entry) ble_gatt_list;
+
+static struct ble_gatt_entry *
+ble_gatt_entry_alloc(void)
+{
+    struct ble_gatt_entry *entry;
+
+    entry = os_memblock_get(&ble_gatt_entry_pool);
+    if (entry != NULL) {
+        memset(entry, 0, sizeof *entry);
+    }
+
+    return entry;
+}
+
+static void
+ble_gatt_entry_free(struct ble_gatt_entry *entry)
+{
+    int rc;
+
+    rc = os_memblock_put(&ble_gatt_entry_pool, entry);
+    assert(rc == 0);
+}
+
+static void
+ble_gatt_entry_remove(struct ble_gatt_entry *entry,
+                      struct ble_gatt_entry *prev)
+{
+    if (prev == NULL) {
+        assert(STAILQ_FIRST(&ble_gatt_list) == entry);
+        STAILQ_REMOVE_HEAD(&ble_gatt_list, next);
+    } else {
+        STAILQ_NEXT(prev, next) = STAILQ_NEXT(entry, next);
+    }
+}
+
+static void
+ble_gatt_entry_remove_free(struct ble_gatt_entry *entry,
+                           struct ble_gatt_entry *prev)
+{
+    ble_gatt_entry_remove(entry, prev);
+    ble_gatt_entry_free(entry);
+}
+
+static int
+ble_gatt_entry_matches(struct ble_gatt_entry *entry, uint16_t conn_handle,
+                       uint8_t att_op, int expecting_only)
+{
+    if (conn_handle != entry->conn_handle) {
+        return 0;
+    }
+
+    if (att_op != entry->op && att_op != BLE_GATT_OP_NONE) {
+        return 0;
+    }
+
+    if (expecting_only &&
+        !(entry->flags & BLE_GATT_ENTRY_F_EXPECTING)) {
+
+        return 0;
+    }
+
+    return 1;
+}
+
+static struct ble_gatt_entry *
+ble_gatt_find(uint16_t conn_handle, uint8_t att_op, int expecting_only,
+              struct ble_gatt_entry **out_prev)
+{
+    struct ble_gatt_entry *entry;
+    struct ble_gatt_entry *prev;
+
+    prev = NULL;
+    STAILQ_FOREACH(entry, &ble_gatt_list, next) {
+        if (ble_gatt_entry_matches(entry, conn_handle, att_op,
+                                           expecting_only)) {
+            if (out_prev != NULL) {
+                *out_prev = prev;
+            }
+            return entry;
+        }
+
+        prev = entry;
+    }
+
+    return NULL;
+}
+
+static void
+ble_gatt_entry_set_pending(struct ble_gatt_entry *entry)
+{
+    assert(!(entry->flags & BLE_GATT_ENTRY_F_PENDING));
+    assert(!(entry->flags & BLE_GATT_ENTRY_F_EXPECTING));
+
+    entry->flags |= BLE_GATT_ENTRY_F_PENDING;
+    ble_hs_kick_gatt();
+}
+
+static void
+ble_gatt_entry_set_expecting(struct ble_gatt_entry *entry,
+                             struct ble_gatt_entry *prev)
+{
+    assert(!(entry->flags & BLE_GATT_ENTRY_F_PENDING));
+    assert(!(entry->flags & BLE_GATT_ENTRY_F_EXPECTING));
+
+    ble_gatt_entry_remove(entry, prev);
+    entry->flags |= BLE_GATT_ENTRY_F_EXPECTING;
+    STAILQ_INSERT_TAIL(&ble_gatt_list, entry, next);
+}
+
+static int
+ble_gatt_new_entry(uint16_t conn_handle, struct ble_gatt_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_gatt_entry_alloc();
+    if (*entry == NULL) {
+        return ENOMEM;
+    }
+
+    memset(*entry, 0, sizeof **entry);
+    (*entry)->conn_handle = conn_handle;
+
+    STAILQ_INSERT_TAIL(&ble_gatt_list, *entry, next);
+
+    ble_gatt_entry_set_pending(*entry);
+
+    return 0;
+}
+
+static int
+ble_gatt_kick_mtu(struct ble_gatt_entry *entry)
+{
+    struct ble_hs_att_mtu_cmd req;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    conn = ble_hs_conn_find(entry->conn_handle);
+    if (conn == NULL) {
+        return ENOTCONN;
+    }
+
+    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+    assert(chan != NULL);
+
+    req.bhamc_mtu = chan->blc_my_mtu;
+    rc = ble_hs_att_clt_tx_mtu(conn, &req);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+static int
+ble_gatt_kick_find_info(struct ble_gatt_entry *entry)
+{
+    struct ble_hs_att_find_info_req req;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    conn = ble_hs_conn_find(entry->conn_handle);
+    if (conn == NULL) {
+        return ENOTCONN;
+    }
+
+    req.bhafq_start_handle = entry->find_info.next_handle;
+    req.bhafq_end_handle = entry->find_info.end_handle;
+    rc = ble_hs_att_clt_tx_find_info(conn, &req);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+void
+ble_gatt_wakeup(void)
+{
+    struct ble_gatt_entry *entry;
+    struct ble_gatt_entry *prev;
+    struct ble_gatt_entry *next;
+    struct ble_gatt_entry *last;
+    int rc;
+
+    last = STAILQ_LAST(&ble_gatt_list, ble_gatt_entry, next);
+
+    prev = NULL;
+    entry = STAILQ_FIRST(&ble_gatt_list);
+    while (prev != last) {
+        next = STAILQ_NEXT(entry, next);
+
+        if (entry->flags & BLE_GATT_ENTRY_F_PENDING) {
+            assert(entry->op < BLE_GATT_OP_MAX);
+
+            rc = ble_gatt_kick_fns[entry->op](entry);
+            if (rc == 0) {
+                ble_gatt_entry_set_expecting(entry, prev);
+            } else {
+                ble_gatt_entry_remove_free(entry, prev);
+            }
+        }
+
+        prev = entry;
+        entry = next;
+    }
+}
+
+void
+ble_gatt_rx_error(struct ble_hs_conn *conn, struct ble_hs_att_error_rsp *rsp)
+{
+    struct ble_gatt_entry *entry;
+    struct ble_gatt_entry *prev;
+
+    entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_NONE, 1, &prev);
+    if (entry == NULL) {
+        /* Not expecting a response from this device. */
+        return;
+    }
+
+    switch (entry->op) {
+    case BLE_GATT_OP_NONE:
+    case BLE_GATT_OP_MTU:
+        break;
+
+    case BLE_GATT_OP_FIND_INFO:
+        /* XXX: Branch on error status. */
+        break;
+
+    default:
+        assert(0);
+        break;
+    }
+}
+
+void
+ble_gatt_rx_mtu(struct ble_hs_conn *conn, uint16_t chan_mtu)
+{
+    struct ble_gatt_entry *entry;
+    struct ble_gatt_entry *prev;
+
+    entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_MTU, 1, &prev);
+    if (entry == NULL) {
+        /* Not expecting a response from this device. */
+        return;
+    }
+
+    /* XXX: Call success callback. */
+    ble_gatt_entry_remove_free(entry, prev);
+}
+
+int
+ble_gatt_mtu(uint16_t conn_handle)
+{
+    struct ble_gatt_entry *entry;
+    int rc;
+
+    rc = ble_gatt_new_entry(conn_handle, &entry);
+    if (rc != 0) {
+        return rc;
+    }
+    entry->op = BLE_GATT_OP_MTU;
+
+    return 0;
+}
+
+void
+ble_gatt_rx_find_info(struct ble_hs_conn *conn, int status,
+                      uint16_t last_handle_id)
+{
+    struct ble_gatt_entry *entry;
+    struct ble_gatt_entry *prev;
+
+    entry = ble_gatt_find(conn->bhc_handle, BLE_GATT_OP_FIND_INFO, 1, &prev);
+    if (entry == NULL) {
+        /* Not expecting a response from this device. */
+        return;
+    }
+
+    if (status != 0) {
+        /* XXX: Call failure callback. */
+        ble_gatt_entry_remove_free(entry, prev);
+        return;
+    }
+
+    if (last_handle_id == 0xffff) {
+        /* XXX: Call success callback. */
+        ble_gatt_entry_remove_free(entry, prev);
+        return;
+    }
+
+    /* Send follow-up request. */
+    entry->find_info.next_handle = last_handle_id + 1;
+    ble_gatt_entry_set_pending(entry);
+}
+
+int
+ble_gatt_find_info(uint16_t conn_handle, uint16_t att_start_handle,
+                   uint16_t att_end_handle)
+{
+    struct ble_gatt_entry *entry;
+    int rc;
+
+    rc = ble_gatt_new_entry(conn_handle, &entry);
+    if (rc != 0) {
+        return rc;
+    }
+    entry->op = BLE_GATT_OP_FIND_INFO;
+    entry->conn_handle = conn_handle;
+    entry->find_info.next_handle = att_start_handle;
+    entry->find_info.end_handle = att_end_handle;
+
+    return 0;
+}
+
+int
+ble_gatt_init(void)
+{
+    int rc;
+
+    free(ble_gatt_entry_mem);
+
+    ble_gatt_entry_mem = malloc(
+        OS_MEMPOOL_BYTES(BLE_GATT_NUM_ENTRIES,
+                         sizeof (struct ble_gatt_entry)));
+    if (ble_gatt_entry_mem == NULL) {
+        rc = ENOMEM;
+        goto err;
+    }
+
+    rc = os_mempool_init(&ble_gatt_entry_pool,
+                         BLE_GATT_NUM_ENTRIES,
+                         sizeof (struct ble_gatt_entry),
+                         ble_gatt_entry_mem,
+                         "ble_gatt_entry_pool");
+    if (rc != 0) {
+        goto err;
+    }
+
+    STAILQ_INIT(&ble_gatt_list);
+
+    return 0;
+
+err:
+    free(ble_gatt_entry_mem);
+    ble_gatt_entry_mem = NULL;
+
+    return rc;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/41db2873/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 b751f20..916cc1a 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -19,6 +19,7 @@
 #include "util/tpq.h"
 #include "os/os.h"
 #include "host/host_hci.h"
+#include "host/ble_gatt.h"
 #include "host/ble_hs.h"
 #include "ble_hs_att.h"
 #include "ble_hs_conn.h"
@@ -69,7 +70,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_hci_ev;
-
+static struct os_event ble_hs_kick_gatt_ev;
 
 struct ble_hs_pkt {
     struct tpq_elem bhp_tpq_elem;
@@ -165,6 +166,10 @@ ble_hs_task_handler(void *arg)
             ble_hs_hci_batch_process_next();
             break;
 
+        case BLE_HS_KICK_GATT_EVENT:
+            ble_gatt_wakeup();
+            break;
+
         default:
             assert(0);
             break;
@@ -224,6 +229,15 @@ 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 att_batch events.
+ */
+void
+ble_hs_kick_gatt(void)
+{
+    os_eventq_put(&ble_hs_evq, &ble_hs_kick_gatt_ev);
+}
+
 static void
 ble_hs_free_mem(void)
 {
@@ -331,10 +345,13 @@ ble_hs_init(uint8_t prio)
     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;
+
     os_task_init(&ble_hs_task, "ble_hs", ble_hs_task_handler, NULL, prio,
                  OS_WAIT_FOREVER, ble_hs_stack, BLE_HS_STACK_SIZE);
 
-
     tpq_init(&ble_hs_rx_q, BLE_HS_RX_DATA_EVENT, NULL);
     tpq_init(&ble_hs_tx_q, BLE_HS_TX_DATA_EVENT, NULL);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/41db2873/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 1762e8e..013405a 100644
--- a/net/nimble/host/src/ble_hs_att.h
+++ b/net/nimble/host/src/ble_hs_att.h
@@ -157,16 +157,4 @@ int ble_hs_att_clt_rx_find_info(struct ble_hs_conn *conn,
                                 struct os_mbuf *om);
 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,
-                               uint16_t att_start_handle,
-                               uint16_t att_end_handle);
-int ble_hs_att_batch_init(void);
-
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/41db2873/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
deleted file mode 100644
index d715d29..0000000
--- a/net/nimble/host/src/ble_hs_att_batch.c
+++ /dev/null
@@ -1,294 +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 <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include "os/os_mempool.h"
-#include "ble_hs_conn.h"
-#include "ble_hs_att_cmd.h"
-#include "ble_hs_att.h"
-
-#define BLE_HS_ATT_BATCH_OP_NONE            0
-#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;
-
-    uint8_t op;
-    uint16_t conn_handle;
-    union {
-        struct {
-            int (*cb)(int status, uint16_t conn_handle, void *arg);
-            void *cb_arg;
-        } mtu;
-
-        struct {
-            uint16_t end_handle;
-
-            int (*cb)(int status, uint16_t conn_handle, void *arg);
-            void *cb_arg;
-        } find_info;
-    };
-};
-
-#define BLE_HS_ATT_BATCH_NUM_ENTRIES          4
-static void *ble_hs_att_batch_entry_mem;
-static struct os_mempool ble_hs_att_batch_entry_pool;
-
-static SLIST_HEAD(, ble_hs_att_batch_entry) ble_hs_att_batch_list;
-
-static struct ble_hs_att_batch_entry *
-ble_hs_att_batch_entry_alloc(void)
-{
-    struct ble_hs_att_batch_entry *entry;
-
-    entry = os_memblock_get(&ble_hs_att_batch_entry_pool);
-    if (entry != NULL) {
-        memset(entry, 0, sizeof *entry);
-    }
-
-    return entry;
-}
-
-static void
-ble_hs_att_batch_entry_free(struct ble_hs_att_batch_entry *entry)
-{
-    int rc;
-
-    rc = os_memblock_put(&ble_hs_att_batch_entry_pool, entry);
-    assert(rc == 0);
-}
-
-static struct ble_hs_att_batch_entry *
-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) {
-            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, BLE_HS_ATT_BATCH_OP_NONE);
-    if (entry == NULL) {
-        /* Not expecting a response from this device. */
-        return;
-    }
-
-    switch (entry->op) {
-    case BLE_HS_ATT_BATCH_OP_NONE:
-        break;
-
-    case BLE_HS_ATT_BATCH_OP_FIND_INFO:
-        /* XXX: Branch on error status. */
-        break;
-
-    default:
-        assert(0);
-        break;
-    }
-}
-
-void
-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, BLE_HS_ATT_BATCH_OP_MTU);
-    if (entry == NULL) {
-        /* Not expecting a response from this device. */
-        return;
-    }
-
-    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;
-    }
-
-    if (status != 0) {
-        /* XXX: Call failure callback. */
-        return;
-    }
-
-    if (last_handle_id == 0xffff) {
-        /* XXX: Call success callback. */
-        return;
-    }
-
-    /* XXX: Send follow up request. */
-}
-
-int
-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 *entry;
-    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_FIND_INFO;
-    entry->conn_handle = conn_handle;
-    entry->find_info.end_handle = att_end_handle;
-
-    req.bhafq_start_handle = att_start_handle;
-    req.bhafq_end_handle = att_end_handle;
-    rc = ble_hs_att_clt_tx_find_info(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;
-}
-
-int
-ble_hs_att_batch_init(void)
-{
-    int rc;
-
-    free(ble_hs_att_batch_entry_mem);
-
-    ble_hs_att_batch_entry_mem = malloc(
-        OS_MEMPOOL_BYTES(BLE_HS_ATT_BATCH_NUM_ENTRIES,
-                         sizeof (struct ble_hs_att_batch_entry)));
-    if (ble_hs_att_batch_entry_mem == NULL) {
-        rc = ENOMEM;
-        goto err;
-    }
-
-    rc = os_mempool_init(&ble_hs_att_batch_entry_pool,
-                         BLE_HS_ATT_BATCH_NUM_ENTRIES,
-                         sizeof (struct ble_hs_att_batch_entry),
-                         ble_hs_att_batch_entry_mem,
-                         "ble_hs_att_batch_entry_pool");
-    if (rc != 0) {
-        goto err;
-    }
-
-    SLIST_INIT(&ble_hs_att_batch_list);
-
-    return 0;
-
-err:
-    free(ble_hs_att_batch_entry_mem);
-    ble_hs_att_batch_entry_mem = NULL;
-
-    return rc;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/41db2873/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 fbc9809..5da4bb5 100644
--- a/net/nimble/host/src/ble_hs_att_clt.c
+++ b/net/nimble/host/src/ble_hs_att_clt.c
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include "os/os_mempool.h"
 #include "nimble/ble.h"
+#include "host/ble_gatt.h"
 #include "host/ble_hs.h"
 #include "ble_hs_uuid.h"
 #include "ble_hs_conn.h"
@@ -208,7 +209,9 @@ ble_hs_att_clt_rx_mtu(struct ble_hs_conn *conn,
         return rc;
     }
 
-    ble_hs_att_batch_rx_mtu(conn, rsp.bhamc_mtu);
+    ble_hs_att_set_peer_mtu(chan, rsp.bhamc_mtu);
+
+    ble_gatt_rx_mtu(conn, ble_l2cap_chan_mtu(chan));
 
     return 0;
 }
@@ -330,7 +333,7 @@ ble_hs_att_clt_rx_find_info(struct ble_hs_conn *conn,
     rc = 0;
 
 done:
-    ble_hs_att_batch_rx_find_info(conn, -rc, handle_id);
+    ble_gatt_rx_find_info(conn, -rc, handle_id);
     return rc;
 }