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/11/05 04:10:03 UTC

[2/2] incubator-mynewt-larva git commit: Use mbufs in l2cap channels; basic att-read handler.

Use mbufs in l2cap channels; basic att-read handler.


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

Branch: refs/heads/master
Commit: 38067a3dfe43435f7439970a46f2de65a309a2e2
Parents: 6fc73da
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Nov 4 19:09:47 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Nov 4 19:09:47 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/src/ble_hs_att.c     | 66 +++++++++++++++++++++++++++----
 net/nimble/host/src/ble_l2cap.c      | 44 ++++++++++++++++++++-
 net/nimble/host/src/ble_l2cap.h      |  8 ++--
 net/nimble/host/src/ble_l2cap_util.c | 58 +++++++++++++++++++++++++++
 net/nimble/host/src/ble_l2cap_util.h | 27 +++++++++++++
 5 files changed, 191 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/38067a3d/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 7d4db8b..0d28723 100644
--- a/net/nimble/host/src/ble_hs_att.c
+++ b/net/nimble/host/src/ble_hs_att.c
@@ -16,17 +16,17 @@
 
 #include <string.h>
 #include <errno.h>
-
+#include <assert.h>
 #include "os/os.h"
 #include "nimble/ble.h"
 #include "host/attr.h"
 #include "ble_l2cap.h"
+#include "ble_l2cap_util.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_att.h"
 
 typedef int ble_hs_att_rx_fn(struct ble_hs_conn *conn,
-                             struct ble_l2cap_chan *chan,
-                             void *buf, int len);
+                             struct ble_l2cap_chan *chan);
 struct ble_hs_att_rx_dispatch_entry {
     uint8_t bde_op;
     ble_hs_att_rx_fn *bde_fn;
@@ -34,8 +34,12 @@ struct ble_hs_att_rx_dispatch_entry {
 
 #define BLE_HS_ATT_OP_READ          0x0a
 
+/** Dispatch table for incoming ATT requests.  Sorted by op code. */
+static int ble_hs_att_rx_read(struct ble_hs_conn *conn,
+                              struct ble_l2cap_chan *chan);
+
 struct ble_hs_att_rx_dispatch_entry ble_hs_att_rx_dispatch[] = {
-    { BLE_HS_ATT_OP_READ, NULL },
+    { BLE_HS_ATT_OP_READ, ble_hs_att_rx_read },
 };
 
 #define BLE_HS_ATT_RX_DISPATCH_SZ \
@@ -272,11 +276,53 @@ ble_hs_att_rx_dispatch_entry_find(uint8_t op)
         if (entry->bde_op == op) {
             return entry;
         }
+
+        if (entry->bde_op > op) {
+            break;
+        }
     }
 
     return NULL;
 }
 
+/**
+ * | Parameter          | Size (octets) |
+ * +--------------------+---------------+
+ * | Attribute Opcode   | 1             |
+ * | Attribute Handle   | 2             |
+ */
+static int
+ble_hs_att_rx_read(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
+{
+    uint16_t handle;
+    uint8_t op;
+    int off;
+    int rc;
+
+    off = 0;
+
+    rc = os_mbuf_copydata(chan->blc_rx_buf, off, 1, &op);
+    if (rc != 0) {
+        return EMSGSIZE;
+    }
+    off += 1;
+
+    assert(op == BLE_HS_ATT_OP_READ);
+
+    rc = ble_l2cap_read_uint16(chan, off, &handle);
+    if (rc != 0) {
+        return EMSGSIZE;
+    }
+    off += 2;
+
+    /* XXX: Perform read. */
+
+    /* Strip ATT read request from the buffer. */
+    ble_l2cap_strip(chan, off);
+
+    return 0;
+}
+
 static int
 ble_hs_att_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -284,18 +330,22 @@ ble_hs_att_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     uint8_t op;
     int rc;
 
-    if (chan->blc_rx_buf_sz < 1) {
+    rc = os_mbuf_copydata(chan->blc_rx_buf, 0, 1, &op);
+    if (rc != 0) {
         return EMSGSIZE;
     }
 
-    op = chan->blc_rx_buf[0];
     entry = ble_hs_att_rx_dispatch_entry_find(op);
     if (entry == NULL) {
         return EINVAL;
     }
 
-    rc = entry->bde_fn(conn, chan, chan->blc_rx_buf, chan->blc_rx_buf_sz);
-    return rc;
+    rc = entry->bde_fn(conn, chan);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
 }
 
 struct ble_l2cap_chan *

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/38067a3d/net/nimble/host/src/ble_l2cap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap.c b/net/nimble/host/src/ble_l2cap.c
index 04e4f25..8ca851c 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -25,6 +25,18 @@
 
 #define BLE_L2CAP_CHAN_MAX  32
 
+#define BLE_L2CAP_NUM_MBUFS      (16)
+#define BLE_L2CAP_BUF_SIZE       (256)
+#define BLE_L2CAP_MEMBLOCK_SIZE  \
+    (BLE_L2CAP_BUF_SIZE + sizeof(struct os_mbuf) + \
+     sizeof(struct os_mbuf_pkthdr))
+
+#define BLE_L2CAP_MEMPOOL_SIZE  \
+    OS_MEMPOOL_SIZE(BLE_L2CAP_NUM_MBUFS, BLE_L2CAP_MEMBLOCK_SIZE)
+
+struct os_mbuf_pool ble_l2cap_mbuf_pool;
+
+static struct os_mempool ble_l2cap_mbuf_mempool;
 static struct os_mempool ble_l2cap_chan_pool;
 
 struct ble_l2cap_chan *
@@ -121,7 +133,20 @@ ble_l2cap_rx(struct ble_hs_conn *conn,
         return ENOENT;
     }
 
-    /* XXX: Append incoming data to channel buffer. */
+    if (chan->blc_rx_buf == NULL) {
+        chan->blc_rx_buf = os_mbuf_get(&ble_l2cap_mbuf_pool, 0);
+        if (chan->blc_rx_buf == NULL) {
+            /* XXX Need to deal with this in a way that prevents starvation. */
+            return ENOMEM;
+        }
+    }
+
+    rc = os_mbuf_append(&ble_l2cap_mbuf_pool, chan->blc_rx_buf,
+                        u8ptr + BLE_L2CAP_HDR_SZ, l2cap_hdr.blh_len);
+    if (rc != 0) {
+        /* XXX Need to deal with this in a way that prevents starvation. */
+        return rc;
+    }
 
     rc = chan->blc_rx_fn(conn, chan);
     if (rc != 0) {
@@ -135,6 +160,7 @@ int
 ble_l2cap_init(void)
 {
     os_membuf_t *chan_mem;
+    os_membuf_t *mbuf_mem;
     int rc;
 
     chan_mem = malloc(
@@ -151,5 +177,21 @@ ble_l2cap_init(void)
         return EINVAL; // XXX
     }
 
+    mbuf_mem = malloc(BLE_L2CAP_MEMPOOL_SIZE);
+    if (mbuf_mem == NULL) {
+        return ENOMEM;
+    }
+    rc = os_mempool_init(&ble_l2cap_mbuf_mempool, BLE_L2CAP_NUM_MBUFS,
+                         BLE_L2CAP_MEMBLOCK_SIZE,
+                         mbuf_mem, "ble_l2cap_mbuf_pool");
+    if (rc != 0) {
+        return EINVAL; // XXX
+    }
+    rc = os_mbuf_pool_init(&ble_l2cap_mbuf_pool, &ble_l2cap_mbuf_mempool,
+                           0, BLE_L2CAP_MEMBLOCK_SIZE, BLE_L2CAP_NUM_MBUFS);
+    if (rc != 0) {
+        return EINVAL; // XXX
+    }
+
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/38067a3d/net/nimble/host/src/ble_l2cap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap.h b/net/nimble/host/src/ble_l2cap.h
index a1694ff..5f07dd9 100644
--- a/net/nimble/host/src/ble_l2cap.h
+++ b/net/nimble/host/src/ble_l2cap.h
@@ -18,6 +18,7 @@
 #define H_L2CAP_
 
 #include <inttypes.h>
+#include "os/os_mbuf.h"
 struct ble_hs_conn;
 struct hci_data_hdr;
 
@@ -44,9 +45,7 @@ struct ble_l2cap_chan
     uint16_t blc_cid;
     ble_l2cap_rx_fn *blc_rx_fn;
 
-    /* XXX: These will probably be replaced by an mbuf. */
-    uint8_t blc_rx_buf[BLE_L2CAP_CHAN_BUF_CAP];
-    int blc_rx_buf_sz;
+    struct os_mbuf *blc_rx_buf;
 
     // tx mbuf
     // tx callback
@@ -58,10 +57,13 @@ SLIST_HEAD(ble_l2cap_chan_list, ble_l2cap_chan);
 struct ble_l2cap_chan *ble_l2cap_chan_alloc(void);
 void ble_l2cap_chan_free(struct ble_l2cap_chan *chan);
 
+
 int ble_l2cap_rx(struct ble_hs_conn *connection,
                  struct hci_data_hdr *hci_hdr,
                  void *pkt);
 
 int ble_l2cap_init(void);
 
+extern struct os_mbuf_pool ble_l2cap_mbuf_pool;
+
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/38067a3d/net/nimble/host/src/ble_l2cap_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_util.c b/net/nimble/host/src/ble_l2cap_util.c
new file mode 100644
index 0000000..df1dcd0
--- /dev/null
+++ b/net/nimble/host/src/ble_l2cap_util.c
@@ -0,0 +1,58 @@
+/**
+ * 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 "os/os.h"
+#include "nimble/ble.h"
+#include "ble_l2cap.h"
+#include "ble_l2cap_util.h"
+
+/**
+ * Reads a uint16 from the specified L2CAP channel's buffer and converts it to
+ * little endian.
+ *
+ * @return                      0 on success; nonzero if the channel buffer
+ *                                  did not contain the requested data.
+ */
+int
+ble_l2cap_read_uint16(const struct ble_l2cap_chan *chan, int off,
+                      uint16_t *u16)
+{
+    int rc;
+
+    rc = os_mbuf_copydata(chan->blc_rx_buf, off, sizeof *u16, u16);
+    if (rc != 0) {
+        return -1;
+    }
+
+    *u16 = le16toh((void *)u16);
+
+    return 0;
+}
+
+/**
+ * Removes the specified number of bytes from the front of an L2CAP channel's
+ * buffer.  If the buffer is empty as a result, it is freed.
+ */
+void
+ble_l2cap_strip(struct ble_l2cap_chan *chan, int delta)
+{
+    os_mbuf_adj(&ble_l2cap_mbuf_pool, chan->blc_rx_buf, delta);
+
+    if (OS_MBUF_PKTHDR(chan->blc_rx_buf)->omp_len == 0) {
+        os_mbuf_free_chain(&ble_l2cap_mbuf_pool, chan->blc_rx_buf);
+        chan->blc_rx_buf = NULL;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/38067a3d/net/nimble/host/src/ble_l2cap_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_util.h b/net/nimble/host/src/ble_l2cap_util.h
new file mode 100644
index 0000000..ff30c8c
--- /dev/null
+++ b/net/nimble/host/src/ble_l2cap_util.h
@@ -0,0 +1,27 @@
+/**
+ * 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_L2CAP_
+#define H_BLE_L2CAP_
+
+#include <inttypes.h>
+struct ble_l2cap_chan;
+
+int ble_l2cap_read_uint16(const struct ble_l2cap_chan *chan, int off,
+                          uint16_t *u16);
+void ble_l2cap_strip(struct ble_l2cap_chan *chan, int delta);
+
+#endif