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

[1/2] incubator-mynewt-larva git commit: Add os_mbuf_adj().

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master ec8c7024d -> 38067a3df


Add os_mbuf_adj().


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

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

----------------------------------------------------------------------
 libs/os/include/os/os_mbuf.h |  3 ++
 libs/os/src/os_mbuf.c        | 74 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/6fc73dad/libs/os/include/os/os_mbuf.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_mbuf.h b/libs/os/include/os/os_mbuf.h
index 0fc590a..8edbe89 100644
--- a/libs/os/include/os/os_mbuf.h
+++ b/libs/os/include/os/os_mbuf.h
@@ -214,4 +214,7 @@ int os_mbuf_free(struct os_mbuf_pool *omp, struct os_mbuf *mb);
 /* Free a mbuf chain */
 int os_mbuf_free_chain(struct os_mbuf_pool *omp, struct os_mbuf *om);
 
+void os_mbuf_adj(struct os_mbuf_pool *omp, struct os_mbuf *mp, int req_len);
+
+
 #endif /* _OS_MBUF_H */ 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/6fc73dad/libs/os/src/os_mbuf.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os_mbuf.c b/libs/os/src/os_mbuf.c
index 5aebd26..18e5571 100644
--- a/libs/os/src/os_mbuf.c
+++ b/libs/os/src/os_mbuf.c
@@ -359,6 +359,80 @@ os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst)
     return (len > 0 ? -1 : 0);
 }
 
+void
+os_mbuf_adj(struct os_mbuf_pool *omp, struct os_mbuf *mp, int req_len)
+{
+    int len = req_len;
+    struct os_mbuf *m;
+    int count;
+
+    if ((m = mp) == NULL)
+        return;
+    if (len >= 0) {
+        /*
+         * Trim from head.
+         */
+        while (m != NULL && len > 0) {
+            if (m->om_len <= len) {
+                len -= m->om_len;
+                m->om_len = 0;
+                m = SLIST_NEXT(m, om_next);
+            } else {
+                m->om_len -= len;
+                m->om_data += len;
+                len = 0;
+            }
+        }
+        if (OS_MBUF_IS_PKTHDR(mp))
+            OS_MBUF_PKTHDR(mp)->omp_len -= (req_len - len);
+    } else {
+        /*
+         * Trim from tail.  Scan the mbuf chain,
+         * calculating its length and finding the last mbuf.
+         * If the adjustment only affects this mbuf, then just
+         * adjust and return.  Otherwise, rescan and truncate
+         * after the remaining size.
+         */
+        len = -len;
+        count = 0;
+        for (;;) {
+            count += m->om_len;
+            if (SLIST_NEXT(m, om_next) == (struct os_mbuf *)0)
+                break;
+            m = SLIST_NEXT(m, om_next);
+        }
+        if (m->om_len >= len) {
+            m->om_len -= len;
+            if (OS_MBUF_IS_PKTHDR(mp))
+                OS_MBUF_PKTHDR(mp)->omp_len -= len;
+            return;
+        }
+        count -= len;
+        if (count < 0)
+            count = 0;
+        /*
+         * Correct length for chain is "count".
+         * Find the mbuf with last data, adjust its length,
+         * and toss data from remaining mbufs on chain.
+         */
+        m = mp;
+        if (OS_MBUF_IS_PKTHDR(m))
+            OS_MBUF_PKTHDR(m)->omp_len = count;
+        for (; m; m = SLIST_NEXT(m, om_next)) {
+            if (m->om_len >= count) {
+                m->om_len = count;
+                if (SLIST_NEXT(m, om_next) != NULL) {
+                    os_mbuf_free_chain(omp, SLIST_NEXT(m, om_next));
+                    SLIST_NEXT(m, om_next) = NULL;
+                }
+                break;
+            }
+            count -= m->om_len;
+        }
+    }
+}
+
+
 #if 0
 
 /**


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

Posted by cc...@apache.org.
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