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