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 01:23:23 UTC
incubator-mynewt-larva git commit: Plug att stub into l2cap / hci.
Repository: incubator-mynewt-larva
Updated Branches:
refs/heads/master fd08bee97 -> b6cc8f81f
Plug att stub into l2cap / hci.
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/b6cc8f81
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/b6cc8f81
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/b6cc8f81
Branch: refs/heads/master
Commit: b6cc8f81fe501fb22fd5a8bcd1d14ce61a49842b
Parents: fd08bee
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Nov 4 16:22:48 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Nov 4 16:23:15 2015 -0800
----------------------------------------------------------------------
net/nimble/host/include/host/host_task.h | 16 --
net/nimble/host/src/arch/sim/itf.c | 98 ++++----
net/nimble/host/src/attr.c | 249 --------------------
net/nimble/host/src/ble_hs_att.c | 315 ++++++++++++++++++++++++++
net/nimble/host/src/ble_hs_att.h | 22 ++
net/nimble/host/src/ble_hs_conn.c | 128 +++++++++++
net/nimble/host/src/ble_hs_conn.h | 39 ++++
net/nimble/host/src/ble_l2cap.c | 155 +++++++++++++
net/nimble/host/src/ble_l2cap.h | 67 ++++++
net/nimble/host/src/host_hci.c | 25 +-
net/nimble/host/src/host_task.c | 72 +++---
net/nimble/host/src/l2cap.c | 59 -----
net/nimble/host/src/l2cap.h | 41 ----
13 files changed, 818 insertions(+), 468 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/net/nimble/host/include/host/host_task.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/host_task.h b/net/nimble/host/include/host/host_task.h
index e90bd7a..f9a3a94 100644
--- a/net/nimble/host/include/host/host_task.h
+++ b/net/nimble/host/include/host/host_task.h
@@ -19,24 +19,8 @@
#include <inttypes.h>
-
-/**
- * ---
- * XXX: This is all temporary.
- */
-#define BLE_HOST_MAX_CONNECTIONS 16
-
-struct ble_host_connection {
- uint16_t bc_handle;
- int bc_fd;
-};
-
extern int ble_host_listen_enabled;
-extern struct ble_host_connection
- ble_host_connections[BLE_HOST_MAX_CONNECTIONS];
-extern int ble_host_num_connections;
-struct ble_host_connection *ble_host_find_connection(uint16_t con_handle);
/** --- */
void ble_host_task_handler(void *arg);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/net/nimble/host/src/arch/sim/itf.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/arch/sim/itf.c b/net/nimble/host/src/arch/sim/itf.c
index b3c6f29..0d4d110 100644
--- a/net/nimble/host/src/arch/sim/itf.c
+++ b/net/nimble/host/src/arch/sim/itf.c
@@ -30,11 +30,9 @@
#include "host/attr.h"
#include "host/host_task.h"
#include "host/host_hci.h"
+#include "ble_hs_conn.h"
#include "itf.h"
-#define BLE_L2CAP_CID_ATT 4
-#define BLE_L2CAP_CID_SIG 5
-
#define BLE_SIM_BASE_PORT 10000
static void
@@ -52,23 +50,25 @@ set_nonblock(int fd)
int
ble_sim_listen(uint16_t con_handle)
{
- struct ble_host_connection *connection;
+ struct ble_hs_conn *conn;
struct sockaddr_in sin;
struct hostent *ent;
int fd;
int rc;
- if (ble_host_num_connections >= BLE_HOST_MAX_CONNECTIONS) {
- return EINVAL; // XXX
+ conn = ble_hs_conn_alloc();
+ if (conn == NULL) {
+ rc = ENOMEM;
+ goto err;
}
- connection = ble_host_connections + ble_host_num_connections;
/* resolve host addr first, then create a socket and bind() to
* that address.
*/
ent = gethostbyname("localhost");
if (ent == NULL) {
- return errno;
+ rc = errno;
+ goto err;
}
memset(&sin, 0, sizeof(sin));
@@ -78,7 +78,8 @@ ble_sim_listen(uint16_t con_handle)
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
- return errno;
+ rc = errno;
+ goto err;
}
set_nonblock(fd);
@@ -86,31 +87,35 @@ ble_sim_listen(uint16_t con_handle)
rc = bind(fd, (struct sockaddr *)&sin, sizeof sin);
if (rc != 0) {
close(fd);
- return errno;
+ rc = errno;
+ goto err;
}
- memset(connection, 0, sizeof *connection);
- connection->bc_handle = con_handle;
- connection->bc_fd = fd;
-
- ble_host_num_connections++;
+ memset(conn, 0, sizeof *conn);
+ conn->bhc_handle = con_handle;
+ conn->bhc_fd = fd;
return 0;
+
+err:
+ ble_hs_conn_free(conn);
+ return rc;
}
static int
-ble_sim_connect(uint16_t con_handle)
+ble_sim_connect(uint16_t con_handle, struct ble_hs_conn **out_conn)
{
- struct ble_host_connection *connection;
+ struct ble_hs_conn *conn;
struct sockaddr_in sin;
struct hostent *ent;
int fd;
int rc;
- if (ble_host_num_connections >= BLE_HOST_MAX_CONNECTIONS) {
- return EINVAL; // XXX
+ conn = ble_hs_conn_alloc();
+ if (conn == NULL) {
+ rc = ENOMEM;
+ goto err;
}
- connection = ble_host_connections + ble_host_num_connections;
/* resolve host addr first, then create a socket and bind() to
* that address.
@@ -140,46 +145,44 @@ ble_sim_connect(uint16_t con_handle)
goto err;
}
- memset(connection, 0, sizeof *connection);
- connection->bc_handle = con_handle;
- connection->bc_fd = fd;
+ memset(conn, 0, sizeof *conn);
+ conn->bhc_handle = con_handle;
+ conn->bhc_fd = fd;
- ble_host_num_connections++;
+ *out_conn = conn;
return 0;
err:
+ ble_hs_conn_free(conn);
+ *out_conn = NULL;
return rc;
}
static int
-ble_sim_ensure_connection(uint16_t con_handle,
- struct ble_host_connection **connection)
+ble_sim_ensure_connection(uint16_t con_handle, struct ble_hs_conn **conn)
{
int rc;
- *connection = ble_host_find_connection(con_handle);
- if (*connection != NULL) {
- return 0;
- }
-
- rc = ble_sim_connect(con_handle);
- if (rc != 0) {
- return rc;
+ *conn = ble_hs_conn_find(con_handle);
+ if (*conn == NULL) {
+ rc = ble_sim_connect(con_handle, conn);
+ if (rc != 0) {
+ return rc;
+ }
}
- *connection = ble_host_connections + ble_host_num_connections - 1;
return 0;
}
static int
ble_sim_send(uint16_t con_handle, const void *data, uint16_t len)
{
- struct ble_host_connection *connection;
+ struct ble_hs_conn *conn;
int rc;
int i;
- rc = ble_sim_ensure_connection(con_handle, &connection);
+ rc = ble_sim_ensure_connection(con_handle, &conn);
if (rc != 0) {
return rc;
}
@@ -191,7 +194,7 @@ ble_sim_send(uint16_t con_handle, const void *data, uint16_t len)
printf("\n");
while (len > 0) {
- rc = send(connection->bc_fd, data, len, 0);
+ rc = send(conn->bhc_fd, data, len, 0);
if (rc >= 0) {
data += rc;
len -= rc;
@@ -236,7 +239,7 @@ int
ble_host_sim_poll(void)
{
static uint8_t buf[1024];
- struct ble_host_connection *conn;
+ struct ble_hs_conn *conn;
fd_set r_fd_set;
fd_set w_fd_set;
uint16_t pkt_size;
@@ -250,8 +253,11 @@ ble_host_sim_poll(void)
FD_ZERO(&w_fd_set);
max_fd = 0;
- for (i = 0; i < ble_host_num_connections; i++) {
- fd = ble_host_connections[i].bc_fd;
+ for (conn = ble_hs_conn_first();
+ conn != NULL;
+ conn = SLIST_NEXT(conn, bhc_next)) {
+
+ fd = conn->bhc_fd;
FD_SET(fd, &r_fd_set);
FD_SET(fd, &w_fd_set);
if (fd > max_fd) {
@@ -264,11 +270,13 @@ ble_host_sim_poll(void)
} while (nevents < 0 && errno == EINTR);
if (nevents > 0) {
- for (i = 0; i < ble_host_num_connections; i++) {
- if (FD_ISSET(ble_host_connections[i].bc_fd, &r_fd_set)) {
- conn = ble_host_connections + i;
+ for (conn = ble_hs_conn_first();
+ conn != NULL;
+ conn = SLIST_NEXT(conn, bhc_next)) {
+
+ if (FD_ISSET(conn->bhc_fd, &r_fd_set)) {
while (1) {
- rc = recv(conn->bc_fd, buf, sizeof buf, 0);
+ rc = recv(conn->bhc_fd, buf, sizeof buf, 0);
if (rc <= 0) {
break;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/net/nimble/host/src/attr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/attr.c b/net/nimble/host/src/attr.c
deleted file mode 100644
index 35a04ab..0000000
--- a/net/nimble/host/src/attr.c
+++ /dev/null
@@ -1,249 +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 <os/os.h>
-#include <string.h>
-
-#include <nimble/ble.h>
-#include <host/attr.h>
-
-static STAILQ_HEAD(, host_attr) g_host_attr_list =
- STAILQ_HEAD_INITIALIZER(g_host_attr_list);
-static uint16_t g_host_attr_id;
-
-static struct os_mutex g_host_attr_list_mutex;
-
-/**
- * Lock the host attribute list.
- *
- * @return 0 on success, non-zero error code on failure.
- */
-static int
-host_attr_list_lock(void)
-{
- int rc;
-
- rc = os_mutex_pend(&g_host_attr_list_mutex, OS_WAIT_FOREVER);
- if (rc != 0) {
- goto err;
- }
-
- return (0);
-err:
- return (rc);
-}
-
-/**
- * Unlock the host attribute list
- *
- * @return 0 on success, non-zero error code on failure.
- */
-static int
-host_attr_list_unlock(void)
-{
- int rc;
-
- rc = os_mutex_release(&g_host_attr_list_mutex);
- if (rc != 0) {
- goto err;
- }
-
- return (0);
-err:
- return (rc);
-}
-
-
-/**
- * Allocate the next handle id and return it.
- *
- * @return A new 16-bit handle ID.
- */
-static uint16_t
-host_attr_next_id(void)
-{
- return (++g_host_attr_id);
-}
-
-/**
- * Register a host attribute with the BLE stack.
- *
- * @param ha A filled out host_attr structure to register
- * @param handle_id A pointer to a 16-bit handle ID, which will be the
- * handle that is allocated.
- *
- * @return 0 on success, non-zero error code on failure.
- */
-int
-host_attr_register(struct host_attr *ha, uint16_t *handle_id)
-{
- int rc;
-
- *handle_id = host_attr_next_id();
- ha->ha_handle_id = *handle_id;
-
- rc = host_attr_list_lock();
- if (rc != 0) {
- goto err;
- }
-
- STAILQ_INSERT_TAIL(&g_host_attr_list, ha, ha_next);
-
- rc = host_attr_list_unlock();
- if (rc != 0) {
- goto err;
- }
-
- return (0);
-err:
- return (rc);
-}
-
-/**
- * Walk the host attribute list, calling walk_func on each entry with argument.
- * If walk_func wants to stop iteration, it returns 1. To continue iteration
- * it returns 0.
- *
- * @param walk_func The function to call for each element in the host attribute
- * list.
- * @param arg The argument to provide to walk_func
- * @param ha_ptr A pointer to a pointer which will be set to the last
- * host_attr element processed, or NULL if the entire list has
- * been processed
- *
- * @return 1 on stopped, 0 on fully processed and an error code otherwise.
- */
-int
-host_attr_walk(host_attr_walk_func_t walk_func, void *arg,
- struct host_attr **ha_ptr)
-{
- struct host_attr *ha;
- int rc;
-
- rc = host_attr_list_lock();
- if (rc != 0) {
- goto err;
- }
-
- *ha_ptr = NULL;
- ha = NULL;
- STAILQ_FOREACH(ha, &g_host_attr_list, ha_next) {
- rc = walk_func(ha, arg);
- if (rc == 1) {
- rc = host_attr_list_unlock();
- if (rc != 0) {
- goto err;
- }
- *ha_ptr = ha;
- return (1);
- }
- }
-
- rc = host_attr_list_unlock();
- if (rc != 0) {
- goto err;
- }
-
- return (0);
-err:
- return (rc);
-}
-
-static int
-host_attr_match_handle(struct host_attr *ha, void *arg)
-{
- if (ha->ha_handle_id == *(uint16_t *) arg) {
- return (1);
- } else {
- return (0);
- }
-}
-
-
-/**
- * Find a host attribute by handle id.
- *
- * @param handle_id The handle_id to search for
- * @param host_attr A pointer to a pointer to put the matching host attr into.
- *
- * @return 0 on success, BLE_ERR_ATTR_NOT_FOUND on not found, and non-zero on
- * error.
- */
-int
-host_attr_find_by_handle(uint16_t handle_id, struct host_attr **ha_ptr)
-{
- int rc;
-
- rc = host_attr_walk(host_attr_match_handle, &handle_id, ha_ptr);
- if (rc == 1) {
- /* Found a matching handle */
- return (0);
- } else if (rc == 0) {
- /* Not found */
- return (BLE_ERR_ATTR_NOT_FOUND);
- } else {
- return (rc);
- }
-}
-
-static int
-host_attr_match_uuid(struct host_attr *ha, void *arg)
-{
- ble_uuid_t *uuid;
-
- uuid = (ble_uuid_t *) arg;
-
- if (memcmp(&ha->ha_uuid, uuid, sizeof(*uuid)) == 0) {
- return (1);
- } else {
- return (0);
- }
-}
-
-
-/**
- * Find a host attribute by UUID.
- *
- * @param uuid The ble_uuid_t to search for
- * @param ha_ptr A pointer to a pointer to put the matching host attr into.
- *
- * @return 0 on success, BLE_ERR_ATTR_NOT_FOUND on not found, and non-zero on
- * error.
- */
-int
-host_attr_find_by_uuid(ble_uuid_t *uuid, struct host_attr **ha_ptr)
-{
- int rc;
-
- rc = host_attr_walk(host_attr_match_uuid, uuid, ha_ptr);
- if (rc == 1) {
- /* Found a matching handle */
- return (0);
- } else if (rc == 0) {
- /* No match */
- return (BLE_ERR_ATTR_NOT_FOUND);
- } else {
- return (rc);
- }
-}
-
-#if 0
-int
-ble_host_att_rx(void *pkt, int len)
-{
-
-}
-#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/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
new file mode 100644
index 0000000..7d4db8b
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_att.c
@@ -0,0 +1,315 @@
+/**
+ * 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 <string.h>
+#include <errno.h>
+
+#include "os/os.h"
+#include "nimble/ble.h"
+#include "host/attr.h"
+#include "ble_l2cap.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_hs_att_rx_dispatch_entry {
+ uint8_t bde_op;
+ ble_hs_att_rx_fn *bde_fn;
+};
+
+#define BLE_HS_ATT_OP_READ 0x0a
+
+struct ble_hs_att_rx_dispatch_entry ble_hs_att_rx_dispatch[] = {
+ { BLE_HS_ATT_OP_READ, NULL },
+};
+
+#define BLE_HS_ATT_RX_DISPATCH_SZ \
+ (sizeof ble_hs_att_rx_dispatch / sizeof ble_hs_att_rx_dispatch[0])
+
+static STAILQ_HEAD(, host_attr) g_host_attr_list =
+ STAILQ_HEAD_INITIALIZER(g_host_attr_list);
+static uint16_t g_host_attr_id;
+
+static struct os_mutex g_host_attr_list_mutex;
+
+/**
+ * Lock the host attribute list.
+ *
+ * @return 0 on success, non-zero error code on failure.
+ */
+static int
+host_attr_list_lock(void)
+{
+ int rc;
+
+ rc = os_mutex_pend(&g_host_attr_list_mutex, OS_WAIT_FOREVER);
+ if (rc != 0) {
+ goto err;
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+/**
+ * Unlock the host attribute list
+ *
+ * @return 0 on success, non-zero error code on failure.
+ */
+static int
+host_attr_list_unlock(void)
+{
+ int rc;
+
+ rc = os_mutex_release(&g_host_attr_list_mutex);
+ if (rc != 0) {
+ goto err;
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+
+/**
+ * Allocate the next handle id and return it.
+ *
+ * @return A new 16-bit handle ID.
+ */
+static uint16_t
+host_attr_next_id(void)
+{
+ return (++g_host_attr_id);
+}
+
+/**
+ * Register a host attribute with the BLE stack.
+ *
+ * @param ha A filled out host_attr structure to register
+ * @param handle_id A pointer to a 16-bit handle ID, which will be the
+ * handle that is allocated.
+ *
+ * @return 0 on success, non-zero error code on failure.
+ */
+int
+host_attr_register(struct host_attr *ha, uint16_t *handle_id)
+{
+ int rc;
+
+ *handle_id = host_attr_next_id();
+ ha->ha_handle_id = *handle_id;
+
+ rc = host_attr_list_lock();
+ if (rc != 0) {
+ goto err;
+ }
+
+ STAILQ_INSERT_TAIL(&g_host_attr_list, ha, ha_next);
+
+ rc = host_attr_list_unlock();
+ if (rc != 0) {
+ goto err;
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+/**
+ * Walk the host attribute list, calling walk_func on each entry with argument.
+ * If walk_func wants to stop iteration, it returns 1. To continue iteration
+ * it returns 0.
+ *
+ * @param walk_func The function to call for each element in the host attribute
+ * list.
+ * @param arg The argument to provide to walk_func
+ * @param ha_ptr A pointer to a pointer which will be set to the last
+ * host_attr element processed, or NULL if the entire list has
+ * been processed
+ *
+ * @return 1 on stopped, 0 on fully processed and an error code otherwise.
+ */
+int
+host_attr_walk(host_attr_walk_func_t walk_func, void *arg,
+ struct host_attr **ha_ptr)
+{
+ struct host_attr *ha;
+ int rc;
+
+ rc = host_attr_list_lock();
+ if (rc != 0) {
+ goto err;
+ }
+
+ *ha_ptr = NULL;
+ ha = NULL;
+ STAILQ_FOREACH(ha, &g_host_attr_list, ha_next) {
+ rc = walk_func(ha, arg);
+ if (rc == 1) {
+ rc = host_attr_list_unlock();
+ if (rc != 0) {
+ goto err;
+ }
+ *ha_ptr = ha;
+ return (1);
+ }
+ }
+
+ rc = host_attr_list_unlock();
+ if (rc != 0) {
+ goto err;
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+static int
+host_attr_match_handle(struct host_attr *ha, void *arg)
+{
+ if (ha->ha_handle_id == *(uint16_t *) arg) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+
+/**
+ * Find a host attribute by handle id.
+ *
+ * @param handle_id The handle_id to search for
+ * @param host_attr A pointer to a pointer to put the matching host attr into.
+ *
+ * @return 0 on success, BLE_ERR_ATTR_NOT_FOUND on not found, and non-zero on
+ * error.
+ */
+int
+host_attr_find_by_handle(uint16_t handle_id, struct host_attr **ha_ptr)
+{
+ int rc;
+
+ rc = host_attr_walk(host_attr_match_handle, &handle_id, ha_ptr);
+ if (rc == 1) {
+ /* Found a matching handle */
+ return (0);
+ } else if (rc == 0) {
+ /* Not found */
+ return (BLE_ERR_ATTR_NOT_FOUND);
+ } else {
+ return (rc);
+ }
+}
+
+static int
+host_attr_match_uuid(struct host_attr *ha, void *arg)
+{
+ ble_uuid_t *uuid;
+
+ uuid = (ble_uuid_t *) arg;
+
+ if (memcmp(&ha->ha_uuid, uuid, sizeof(*uuid)) == 0) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+
+/**
+ * Find a host attribute by UUID.
+ *
+ * @param uuid The ble_uuid_t to search for
+ * @param ha_ptr A pointer to a pointer to put the matching host attr into.
+ *
+ * @return 0 on success, BLE_ERR_ATTR_NOT_FOUND on not found, and non-zero on
+ * error.
+ */
+int
+host_attr_find_by_uuid(ble_uuid_t *uuid, struct host_attr **ha_ptr)
+{
+ int rc;
+
+ rc = host_attr_walk(host_attr_match_uuid, uuid, ha_ptr);
+ if (rc == 1) {
+ /* Found a matching handle */
+ return (0);
+ } else if (rc == 0) {
+ /* No match */
+ return (BLE_ERR_ATTR_NOT_FOUND);
+ } else {
+ return (rc);
+ }
+}
+
+static struct ble_hs_att_rx_dispatch_entry *
+ble_hs_att_rx_dispatch_entry_find(uint8_t op)
+{
+ struct ble_hs_att_rx_dispatch_entry *entry;
+ int i;
+
+ for (i = 0; i < BLE_HS_ATT_RX_DISPATCH_SZ; i++) {
+ entry = ble_hs_att_rx_dispatch + i;
+ if (entry->bde_op == op) {
+ return entry;
+ }
+ }
+
+ return NULL;
+}
+
+static int
+ble_hs_att_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
+{
+ struct ble_hs_att_rx_dispatch_entry *entry;
+ uint8_t op;
+ int rc;
+
+ if (chan->blc_rx_buf_sz < 1) {
+ 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;
+}
+
+struct ble_l2cap_chan *
+ble_hs_att_create_chan(void)
+{
+ struct ble_l2cap_chan *chan;
+
+ chan = ble_l2cap_chan_alloc();
+ if (chan == NULL) {
+ return NULL;
+ }
+
+ chan->blc_cid = BLE_L2CAP_CID_ATT;
+ chan->blc_rx_fn = ble_hs_att_rx;
+
+ return chan;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/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
new file mode 100644
index 0000000..9ad7d9b
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_att.h
@@ -0,0 +1,22 @@
+/**
+ * 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_HS_ATT_
+#define H_BLE_HS_ATT_
+
+struct ble_l2cap_chan *ble_hs_att_create_chan(void);
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/net/nimble/host/src/ble_hs_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.c b/net/nimble/host/src/ble_hs_conn.c
new file mode 100644
index 0000000..a745f73
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -0,0 +1,128 @@
+/**
+ * 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 <assert.h>
+#include <errno.h>
+#include "os/os.h"
+#include "ble_l2cap.h"
+#include "ble_hs_conn.h"
+#include "ble_hs_att.h"
+
+#define BLE_HS_CONN_MAX 16
+
+static SLIST_HEAD(, ble_hs_conn) ble_hs_conns =
+ SLIST_HEAD_INITIALIZER(ble_hs_conns);
+
+static struct os_mempool ble_hs_conn_pool;
+
+struct ble_hs_conn *
+ble_hs_conn_alloc(void)
+{
+ struct ble_l2cap_chan *chan;
+ struct ble_hs_conn *conn;
+
+ conn = os_memblock_get(&ble_hs_conn_pool);
+ if (conn == NULL) {
+ goto err;
+ }
+
+ SLIST_INIT(&conn->bhc_channels);
+
+ chan = ble_hs_att_create_chan();
+ if (chan == NULL) {
+ goto err;
+ }
+ SLIST_INSERT_HEAD(&conn->bhc_channels, chan, blc_next);
+
+ /* XXX: Allocated entries always go into the list. Allocation and
+ * insertion may need to be split into separate operations.
+ */
+ SLIST_INSERT_HEAD(&ble_hs_conns, conn, bhc_next);
+
+ return conn;
+
+err:
+ ble_hs_conn_free(conn);
+ return NULL;
+}
+
+void
+ble_hs_conn_free(struct ble_hs_conn *conn)
+{
+ struct ble_l2cap_chan *chan;
+ int rc;
+
+ if (conn == NULL) {
+ return;
+ }
+
+ SLIST_REMOVE(&ble_hs_conns, conn, ble_hs_conn, bhc_next);
+
+ while ((chan = SLIST_FIRST(&conn->bhc_channels)) != NULL) {
+ SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, blc_next);
+ ble_l2cap_chan_free(chan);
+ }
+
+ rc = os_memblock_put(&ble_hs_conn_pool, conn);
+ assert(rc == 0);
+}
+
+struct ble_hs_conn *
+ble_hs_conn_find(uint16_t con_handle)
+{
+ struct ble_hs_conn *conn;
+
+ SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
+ if (conn->bhc_handle == con_handle) {
+ return conn;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Retrieves the first connection in the list.
+ * XXX: This is likely temporary.
+ */
+struct ble_hs_conn *
+ble_hs_conn_first(void)
+{
+ return SLIST_FIRST(&ble_hs_conns);
+}
+
+int
+ble_hs_conn_init(void)
+{
+ os_membuf_t *connection_mem;
+ int rc;
+
+ connection_mem = malloc(
+ OS_MEMPOOL_SIZE(BLE_HS_CONN_MAX,
+ sizeof (struct ble_hs_conn)));
+ if (connection_mem == NULL) {
+ return ENOMEM;
+ }
+
+ rc = os_mempool_init(&ble_hs_conn_pool, BLE_HS_CONN_MAX,
+ sizeof (struct ble_hs_conn),
+ connection_mem, "ble_hs_conn_pool");
+ if (rc != 0) {
+ return EINVAL; // XXX
+ }
+
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/net/nimble/host/src/ble_hs_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.h b/net/nimble/host/src/ble_hs_conn.h
new file mode 100644
index 0000000..35c752b
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_conn.h
@@ -0,0 +1,39 @@
+/**
+ * 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_HS_CONN_
+#define H_BLE_HS_CONN_
+
+#include "os/queue.h"
+#include "ble_l2cap.h"
+
+struct ble_hs_conn *ble_host_find_connection(uint16_t con_handle);
+
+struct ble_hs_conn {
+ SLIST_ENTRY(ble_hs_conn) bhc_next;
+ uint16_t bhc_handle;
+ int bhc_fd; // XXX Temporary.
+
+ struct ble_l2cap_chan_list bhc_channels;
+};
+
+struct ble_hs_conn *ble_hs_conn_alloc(void);
+void ble_hs_conn_free(struct ble_hs_conn *conn);
+struct ble_hs_conn *ble_hs_conn_find(uint16_t con_handle);
+struct ble_hs_conn *ble_hs_conn_first(void);
+int ble_hs_conn_init(void);
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/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
new file mode 100644
index 0000000..04e4f25
--- /dev/null
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -0,0 +1,155 @@
+/**
+ * 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 <string.h>
+#include <errno.h>
+#include <assert.h>
+#include "os/os.h"
+#include "nimble/ble.h"
+#include "nimble/hci_common.h"
+#include "ble_hs_conn.h"
+#include "ble_l2cap.h"
+
+#define BLE_L2CAP_CHAN_MAX 32
+
+static struct os_mempool ble_l2cap_chan_pool;
+
+struct ble_l2cap_chan *
+ble_l2cap_chan_alloc(void)
+{
+ struct ble_l2cap_chan *chan;
+
+ chan = os_memblock_get(&ble_l2cap_chan_pool);
+ if (chan == NULL) {
+ return NULL;
+ }
+
+ memset(chan, 0, sizeof *chan);
+
+ return chan;
+}
+
+void
+ble_l2cap_chan_free(struct ble_l2cap_chan *chan)
+{
+ int rc;
+
+ if (chan == NULL) {
+ return;
+ }
+
+ rc = os_memblock_put(&ble_l2cap_chan_pool, chan);
+ assert(rc == 0);
+}
+
+static int
+ble_l2cap_parse_hdr(void *pkt, uint16_t len, struct ble_l2cap_hdr *l2cap_hdr)
+{
+ uint8_t *u8ptr;
+ uint16_t off;
+
+ if (len < BLE_L2CAP_HDR_SZ) {
+ return EMSGSIZE;
+ }
+
+ off = 0;
+ u8ptr = pkt;
+
+ l2cap_hdr->blh_len = le16toh(u8ptr + off);
+ off += 2;
+
+ l2cap_hdr->blh_cid = le16toh(u8ptr + off);
+ off += 2;
+
+ if (len < BLE_L2CAP_HDR_SZ + l2cap_hdr->blh_len) {
+ return EMSGSIZE;
+ }
+
+ return 0;
+}
+
+static struct ble_l2cap_chan *
+ble_l2cap_chan_find(struct ble_hs_conn *conn, uint16_t cid)
+{
+ struct ble_l2cap_chan *chan;
+
+ SLIST_FOREACH(chan, &conn->bhc_channels, blc_next) {
+ if (chan->blc_cid == cid) {
+ return chan;
+ }
+ }
+
+ return NULL;
+}
+
+int
+ble_l2cap_rx(struct ble_hs_conn *conn,
+ struct hci_data_hdr *hci_hdr,
+ void *pkt)
+{
+ struct ble_l2cap_chan *chan;
+ struct ble_l2cap_hdr l2cap_hdr;
+ uint8_t *u8ptr;
+ int rc;
+
+ u8ptr = pkt;
+
+ rc = ble_l2cap_parse_hdr(u8ptr, hci_hdr->hdh_len, &l2cap_hdr);
+ if (rc != 0) {
+ return rc;
+ }
+
+ if (l2cap_hdr.blh_len != hci_hdr->hdh_len - BLE_L2CAP_HDR_SZ) {
+ return EMSGSIZE;
+ }
+
+ chan = ble_l2cap_chan_find(conn, l2cap_hdr.blh_cid);
+ if (chan == NULL) {
+ return ENOENT;
+ }
+
+ /* XXX: Append incoming data to channel buffer. */
+
+ rc = chan->blc_rx_fn(conn, chan);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
+}
+
+int
+ble_l2cap_init(void)
+{
+ os_membuf_t *chan_mem;
+ int rc;
+
+ chan_mem = malloc(
+ OS_MEMPOOL_SIZE(BLE_L2CAP_CHAN_MAX,
+ sizeof (struct ble_l2cap_chan)));
+ if (chan_mem == NULL) {
+ return ENOMEM;
+ }
+
+ rc = os_mempool_init(&ble_l2cap_chan_pool, BLE_L2CAP_CHAN_MAX,
+ sizeof (struct ble_l2cap_chan),
+ chan_mem, "ble_l2cap_chan_pool");
+ if (rc != 0) {
+ return EINVAL; // XXX
+ }
+
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/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
new file mode 100644
index 0000000..a1694ff
--- /dev/null
+++ b/net/nimble/host/src/ble_l2cap.h
@@ -0,0 +1,67 @@
+/**
+ * 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_L2CAP_
+#define H_L2CAP_
+
+#include <inttypes.h>
+struct ble_hs_conn;
+struct hci_data_hdr;
+
+#define BLE_L2CAP_CID_SIG 1
+#define BLE_L2CAP_CID_ATT 4
+
+#define BLE_L2CAP_HDR_SZ 4
+
+#define BLE_L2CAP_CHAN_BUF_CAP 256
+
+struct ble_l2cap_hdr
+{
+ uint16_t blh_len;
+ uint16_t blh_cid;
+};
+
+struct ble_l2cap_chan;
+typedef int ble_l2cap_rx_fn(struct ble_hs_conn *conn,
+ struct ble_l2cap_chan *chan);
+
+struct ble_l2cap_chan
+{
+ SLIST_ENTRY(ble_l2cap_chan) blc_next;
+ 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;
+
+ // tx mbuf
+ // tx callback
+};
+
+
+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);
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/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 4f736db..2148163 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -24,7 +24,8 @@
#include "nimble/hci_transport.h"
#include "host/host_task.h"
#include "host_dbg.h"
-#include "l2cap.h"
+#include "ble_hs_conn.h"
+#include "ble_l2cap.h"
#define HCI_CMD_BUFS (8)
#define HCI_CMD_BUF_SIZE (260) /* XXX: temporary, Fix later */
@@ -476,8 +477,7 @@ host_hci_data_parse_hdr(void *pkt, uint16_t len, struct hci_data_hdr *hdr)
int
host_hci_data_rx(void *pkt, uint16_t len)
{
- struct ble_host_connection *connection;
- struct ble_l2cap_hdr l2cap_hdr;
+ struct ble_hs_conn *connection;
struct hci_data_hdr hci_hdr;
uint16_t handle;
uint16_t off;
@@ -497,27 +497,12 @@ host_hci_data_rx(void *pkt, uint16_t len)
}
handle = BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc);
- connection = ble_host_find_connection(handle);
+ connection = ble_hs_conn_find(handle);
if (connection == NULL) {
return ENOTCONN;
}
- rc = ble_l2cap_parse_hdr(u8ptr + off, len - off, &l2cap_hdr);
- if (rc != 0) {
- return rc;
- }
- off += BLE_L2CAP_HDR_SZ;
- if (l2cap_hdr.blh_len != hci_hdr.hdh_len - BLE_L2CAP_HDR_SZ) {
- return EMSGSIZE;
- }
-
- printf("hci-handle-pb-bc=%d\n", hci_hdr.hdh_handle_pb_bc);
- printf("hci-len=%d\n", hci_hdr.hdh_len);
- printf("l2cap-len=%d\n", l2cap_hdr.blh_len);
- printf("l2cap-cid=%d\n", l2cap_hdr.blh_cid);
- printf("\n");
-
- ble_l2cap_rx(connection, &hci_hdr, &l2cap_hdr, u8ptr + off);
+ ble_l2cap_rx(connection, &hci_hdr, u8ptr + off);
return 0;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/net/nimble/host/src/host_task.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_task.c b/net/nimble/host/src/host_task.c
index a5148d2..196d011 100644
--- a/net/nimble/host/src/host_task.c
+++ b/net/nimble/host/src/host_task.c
@@ -18,6 +18,7 @@
#include "os/os.h"
#include "host/attr.h"
#include "host/host_task.h"
+#include "ble_hs_conn.h"
#ifdef ARCH_sim
#include "itf.h"
#endif
@@ -25,48 +26,10 @@
int ble_host_listen_enabled;
-struct ble_host_connection ble_host_connections[BLE_HOST_MAX_CONNECTIONS];
-int ble_host_num_connections;
-
static struct os_eventq host_task_evq;
//static struct ble_att_chan default_attr_chan;
static struct os_callout ble_host_task_timer;
-/**
- * Initialize the host portion of the BLE stack.
- */
-int
-host_init(void)
-{
- os_eventq_init(&host_task_evq);
- os_callout_init(&ble_host_task_timer, &host_task_evq, NULL);
-
-#ifdef ARCH_sim
- if (ble_host_listen_enabled) {
- int rc;
-
- rc = ble_sim_listen(1);
- assert(rc == 0);
- }
-#endif
-
- return 0;
-}
-
-struct ble_host_connection *
-ble_host_find_connection(uint16_t con_handle)
-{
- int i;
-
- for (i = 0; i < BLE_HOST_MAX_CONNECTIONS; i++) {
- if (ble_host_connections[i].bc_handle == con_handle) {
- return ble_host_connections + i;
- }
- }
-
- return NULL;
-}
-
int
ble_host_send_data_connectionless(uint16_t con_handle, uint16_t cid,
uint8_t *data, uint16_t len)
@@ -125,3 +88,36 @@ ble_host_task_handler(void *arg)
}
}
}
+
+/**
+ * Initialize the host portion of the BLE stack.
+ */
+int
+host_init(void)
+{
+ int rc;
+
+ os_eventq_init(&host_task_evq);
+ os_callout_init(&ble_host_task_timer, &host_task_evq, NULL);
+
+ rc = ble_hs_conn_init();
+ if (rc != 0) {
+ return rc;
+ }
+
+ rc = ble_l2cap_init();
+ if (rc != 0) {
+ return rc;
+ }
+
+#ifdef ARCH_sim
+ if (ble_host_listen_enabled) {
+ int rc;
+
+ rc = ble_sim_listen(1);
+ assert(rc == 0);
+ }
+#endif
+
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/net/nimble/host/src/l2cap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/l2cap.c b/net/nimble/host/src/l2cap.c
deleted file mode 100644
index 4f84123..0000000
--- a/net/nimble/host/src/l2cap.c
+++ /dev/null
@@ -1,59 +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 <errno.h>
-#include "nimble/ble.h"
-#include "nimble/hci_common.h"
-#include "l2cap.h"
-
-int
-ble_l2cap_parse_hdr(void *pkt, uint16_t len, struct ble_l2cap_hdr *l2cap_hdr)
-{
- uint8_t *u8ptr;
- uint16_t off;
-
- if (len < BLE_L2CAP_HDR_SZ) {
- return EMSGSIZE;
- }
-
- off = 0;
- u8ptr = pkt;
-
- l2cap_hdr->blh_len = le16toh(u8ptr + off);
- off += 2;
-
- l2cap_hdr->blh_cid = le16toh(u8ptr + off);
- off += 2;
-
- if (len < BLE_L2CAP_HDR_SZ + l2cap_hdr->blh_len) {
- return EMSGSIZE;
- }
-
- return 0;
-}
-
-int
-ble_l2cap_rx(struct ble_host_connection *connection,
- struct hci_data_hdr *hci_hdr,
- struct ble_l2cap_hdr *l2cap_hdr,
- void *pkt)
-{
- /* XXX: Look up L2CAP channel by connection-cid pair. */
- /* XXX: Append incoming data to channel buffer. */
- /* XXX: Call channel-specific rx callback. */
-
- return 0;
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6cc8f81/net/nimble/host/src/l2cap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/l2cap.h b/net/nimble/host/src/l2cap.h
deleted file mode 100644
index fddc85b..0000000
--- a/net/nimble/host/src/l2cap.h
+++ /dev/null
@@ -1,41 +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_L2CAP_
-#define H_L2CAP_
-
-struct ble_host_connection;
-struct hci_data_hdr;
-
-#define BLE_L2CAP_CID_SIG 1
-#define BLE_L2CAP_CID_ATT 4
-
-#define BLE_L2CAP_HDR_SZ 4
-
-struct ble_l2cap_hdr
-{
- uint16_t blh_len;
- uint16_t blh_cid;
-};
-
-int ble_l2cap_parse_hdr(void *pkt, uint16_t len,
- struct ble_l2cap_hdr *l2cap_hdr);
-int ble_l2cap_rx(struct ble_host_connection *connection,
- struct hci_data_hdr *hci_hdr,
- struct ble_l2cap_hdr *l2cap_hdr,
- void *pkt);
-
-#endif