Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 85638d22a -> 8b510e973


bletiny: Add support to connect/disconnect L2CAP LE COC

With this patch bletiny gets support to test LE COC.
In order to do this, new options to 'b l2cap' command has been added:
* create_srv psm=<psm>
* connect conn=<conn_handle> psm=<psm>
* disconnect idx=<idx>

In order to get 'idx' required to disconnect you should call

"b show coc"


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/8b73a4d8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/8b73a4d8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/8b73a4d8

Branch: refs/heads/develop
Commit: 8b73a4d81480d6753ff019cd26f89ef606b0b247
Parents: 2082dc6
Author: Łukasz Rymanowski <[email protected]>
Authored: Tue Jan 31 01:28:20 2017 +0100
Committer: Łukasz Rymanowski <[email protected]>
Committed: Thu Feb 2 12:59:59 2017 +0100

----------------------------------------------------------------------
 apps/bletiny/src/bletiny.h          |  12 +-
 apps/bletiny/src/cmd.c              | 145 ++++++++++++++++++++
 apps/bletiny/src/main.c             | 222 +++++++++++++++++++++++++++++++
 net/nimble/host/src/ble_l2cap_sig.c |   5 +-
 4 files changed, 381 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8b73a4d8/apps/bletiny/src/bletiny.h
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/bletiny.h b/apps/bletiny/src/bletiny.h
index 2ab696a..8d8ac64 100644
--- a/apps/bletiny/src/bletiny.h
+++ b/apps/bletiny/src/bletiny.h
@@ -78,9 +78,17 @@ struct bletiny_svc {
 
 SLIST_HEAD(bletiny_svc_list, bletiny_svc);
 
+struct bletiny_l2cap_coc {
+    SLIST_ENTRY(bletiny_l2cap_coc) next;
+    struct ble_l2cap_chan *chan;
+};
+
+SLIST_HEAD(bletiny_l2cap_coc_list, bletiny_l2cap_coc);
+
 struct bletiny_conn {
     uint16_t handle;
     struct bletiny_svc_list svcs;
+    struct bletiny_l2cap_coc_list coc_list;
 };
 
 extern struct bletiny_conn bletiny_conns[MYNEWT_VAL(BLE_MAX_CONNECTIONS)];
@@ -182,7 +190,9 @@ int bletiny_sec_restart(uint16_t conn_handle, uint8_t *ltk, 
uint16_t ediv,
 int bletiny_tx_start(uint16_t handle, uint16_t len, uint16_t rate,
                      uint16_t num);
 int bletiny_rssi(uint16_t conn_handle, int8_t *out_rssi);
-
+int bletiny_l2cap_create_srv(uint16_t psm);
+int bletiny_l2cap_connect(uint16_t conn, uint16_t psm);
+int bletiny_l2cap_disconnect(uint16_t conn, uint16_t idx);
 #define BLETINY_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
 #define BLETINY_LOG(lvl, ...) \
     LOG_ ## lvl(&bletiny_log, BLETINY_LOG_MODULE, __VA_ARGS__)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8b73a4d8/apps/bletiny/src/cmd.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/cmd.c b/apps/bletiny/src/cmd.c
index c5f4a55..8904ea2 100644
--- a/apps/bletiny/src/cmd.c
+++ b/apps/bletiny/src/cmd.c
@@ -1164,6 +1164,119 @@ cmd_l2cap_update(int argc, char **argv)
     return 0;
 }
 
+static void
+bletiny_l2cap_create_srv_help(void)
+{
+    console_printf("Available l2cap create_srv commands: \n");
+    console_printf("\thelp\n");
+    console_printf("Available l2cap create_srv params: \n");
+    help_cmd_uint16("psm");
+    help_cmd_uint16("mtu");
+}
+
+static int
+cmd_l2cap_create_srv(int argc, char **argv)
+{
+    uint16_t psm = 0;
+    int rc;
+
+    if (argc > 1 && strcmp(argv[1], "help") == 0) {
+            bletiny_l2cap_create_srv_help();
+        return 0;
+    }
+
+    psm = parse_arg_uint16("psm", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'psm' parameter\n");
+        help_cmd_uint16("psm");
+        return rc;
+    }
+
+    rc = bletiny_l2cap_create_srv(psm);
+    if (rc) {
+        console_printf("Server create error: 0x%02x", rc);
+    }
+
+    return 0;
+}
+
+static void
+bletiny_l2cap_connect_help(void)
+{
+    console_printf("Available l2cap connect commands: \n");
+    console_printf("\thelp\n");
+    console_printf("Available l2cap connect params: \n");
+    help_cmd_uint16("conn");
+    help_cmd_uint16("psm");
+}
+
+static int
+cmd_l2cap_connect(int argc, char **argv)
+{
+    uint16_t conn = 0;
+    uint16_t psm = 0;
+    int rc;
+
+    if (argc > 1 && strcmp(argv[1], "help") == 0) {
+            bletiny_l2cap_connect_help();
+        return 0;
+    }
+
+    conn = parse_arg_uint16("conn", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'conn' parameter\n");
+        help_cmd_uint16("conn");
+    }
+
+    psm = parse_arg_uint16("psm", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'psm' parameter\n");
+        help_cmd_uint16("psm");
+        return rc;
+    }
+
+    return bletiny_l2cap_connect(conn, psm);
+}
+
+static void
+bletiny_l2cap_disconnect_help(void)
+{
+    console_printf("Available l2cap disconnect commands: \n");
+    console_printf("\thelp\n");
+    console_printf("Available l2cap disconnect params: \n");
+    help_cmd_uint16("conn");
+    help_cmd_uint16("idx");
+    console_printf("\n Use 'b show coc' to get those parameters \n");
+}
+
+static int
+cmd_l2cap_disconnect(int argc, char **argv)
+{
+    uint16_t conn;
+    uint16_t idx;
+    int rc;
+
+    if (argc > 1 && strcmp(argv[1], "help") == 0) {
+        bletiny_l2cap_disconnect_help();
+        return 0;
+    }
+
+    conn = parse_arg_uint16("conn", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'conn' parameter\n");
+        help_cmd_uint16("conn");
+    }
+
+    idx = parse_arg_uint16("idx", &rc);
+    if (rc != 0) {
+        console_printf("invalid 'idx' parameter\n");
+        help_cmd_uint16("idx");
+        return 0;
+    }
+
+    return bletiny_l2cap_disconnect(conn, idx);
+}
+
 static const struct cmd_entry cmd_l2cap_entries[];
 
 static int
@@ -1180,6 +1293,9 @@ cmd_l2cap_help(int argc, char **argv)
 
 static const struct cmd_entry cmd_l2cap_entries[] = {
     { "update", cmd_l2cap_update },
+    { "create_srv", cmd_l2cap_create_srv },
+    { "connect", cmd_l2cap_connect },
+    { "disconnect", cmd_l2cap_disconnect },
     { "help", cmd_l2cap_help },
     { NULL, NULL }
 };
@@ -1608,6 +1724,34 @@ cmd_show_conn(int argc, char **argv)
     return 0;
 }
 
+static int
+cmd_show_coc(int argc, char **argv)
+{
+    struct bletiny_conn *conn = NULL;
+    struct bletiny_l2cap_coc *coc;
+    int i, j;
+
+    for (i = 0; i < bletiny_num_conns; i++) {
+        conn = bletiny_conns + i;
+        if (!conn) {
+            break;
+        }
+
+        if (SLIST_EMPTY(&conn->coc_list)) {
+            continue;
+        }
+
+        console_printf("conn_handle: 0x%04x\n", conn->handle);
+        j = 0;
+        SLIST_FOREACH(coc, &conn->coc_list, next) {
+            console_printf("    idx: %i, chan pointer = 0x%08lx\n", j++,
+                           (uint32_t)coc->chan);
+        }
+    }
+
+    return 0;
+}
+
 static struct cmd_entry cmd_show_entries[];
 
 static int
@@ -1626,6 +1770,7 @@ static struct cmd_entry cmd_show_entries[] = {
     { "addr", cmd_show_addr },
     { "chr", cmd_show_chr },
     { "conn", cmd_show_conn },
+    { "coc", cmd_show_coc },
     { "help", cmd_show_help },
     { NULL, NULL }
 };

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8b73a4d8/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index e958da6..c468666 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -71,6 +71,10 @@
 #define BLETINY_MAX_DSCS               1
 #endif
 
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
+#define BLETINY_COC_MTU               (256)
+#endif
+
 struct log bletiny_log;
 
 bssnz_t struct bletiny_conn bletiny_conns[MYNEWT_VAL(BLE_MAX_CONNECTIONS)];
@@ -85,6 +89,14 @@ static struct os_mempool bletiny_chr_pool;
 static void *bletiny_dsc_mem;
 static struct os_mempool bletiny_dsc_pool;
 
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
+static void *bletiny_coc_conn_mem;
+static struct os_mempool bletiny_coc_conn_pool;
+
+static void *bletiny_sdu_coc_mem;
+static struct os_mempool bletiny_sdu_coc_pool;
+#endif
+
 static struct os_callout bletiny_tx_timer;
 struct bletiny_tx_data_s
 {
@@ -599,6 +611,7 @@ bletiny_conn_add(struct ble_gap_conn_desc *desc)
 
     conn->handle = desc->conn_handle;
     SLIST_INIT(&conn->svcs);
+    SLIST_INIT(&conn->coc_list);
 
     return conn;
 }
@@ -1549,6 +1562,190 @@ bletiny_on_reset(int reason)
     console_printf("Error: Resetting state; reason=%d\n", reason);
 }
 
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+
+static int
+bletiny_l2cap_coc_add(uint16_t conn_handle, struct ble_l2cap_chan *chan)
+{
+    struct bletiny_conn *conn;
+    struct bletiny_l2cap_coc *coc;
+    struct bletiny_l2cap_coc *prev, *cur;
+
+    conn = bletiny_conn_find(conn_handle);
+    assert(conn != NULL);
+
+    coc = os_memblock_get(&bletiny_coc_conn_pool);
+    if (!coc) {
+        return ENOMEM;
+    }
+
+    coc->chan = chan;
+
+    prev = NULL;
+    SLIST_FOREACH(cur, &conn->coc_list, next) {
+        prev = cur;
+    }
+
+    if (prev == NULL) {
+        SLIST_INSERT_HEAD(&conn->coc_list, coc, next);
+    } else {
+        SLIST_INSERT_AFTER(prev, coc, next);
+    }
+
+    return 0;
+}
+
+static void
+bletiny_l2cap_coc_remove(uint16_t conn_handle, struct ble_l2cap_chan *chan)
+{
+    struct bletiny_conn *conn;
+    struct bletiny_l2cap_coc *coc;
+    struct bletiny_l2cap_coc *cur;
+
+    conn = bletiny_conn_find(conn_handle);
+    assert(conn != NULL);
+
+    coc = NULL;
+    SLIST_FOREACH(cur, &conn->coc_list, next) {
+        if (cur->chan == chan) {
+            coc = cur;
+            break;
+        }
+    }
+
+    if (!coc) {
+        return;
+    }
+
+    SLIST_REMOVE(&conn->coc_list, coc, bletiny_l2cap_coc, next);
+    os_memblock_put(&bletiny_coc_conn_pool, coc);
+}
+
+static void
+bletiny_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu)
+{
+    console_printf("LE CoC SDU received, chan: 0x%08lx\n", (uint32_t) chan);
+}
+
+static int
+bletiny_l2cap_coc_accept(uint16_t conn_handle, uint16_t peer_mtu,
+                           struct ble_l2cap_chan *chan)
+{
+    struct os_mbuf *sdu_rx;
+
+    sdu_rx = os_memblock_get(&bletiny_sdu_coc_pool);
+    if (!sdu_rx) {
+            return BLE_HS_ENOMEM;
+    }
+
+    ble_l2cap_recv_ready(chan, sdu_rx);
+
+    return 0;
+}
+
+static int
+bletiny_l2cap_event(struct ble_l2cap_event *event, void *arg)
+{
+    switch(event->type) {
+        case BLE_L2CAP_EVENT_COC_CONNECTED:
+            if (event->connect.status) {
+                console_printf("LE COC error: %d\n", event->connect.status);
+                return 0;
+            }
+
+            console_printf("LE COC connected, conn: %d, chan: 0x%08lx\n",
+                           event->connect.conn_handle,
+                           (uint32_t) event->connect.chan);
+
+            bletiny_l2cap_coc_add(event->connect.conn_handle,
+                                  event->connect.chan);
+
+            return 0;
+        case BLE_L2CAP_EVENT_COC_DISCONNECTED:
+            console_printf("LE CoC disconnected, chan: 0x%08lx\n",
+                           (uint32_t) event->disconnect.chan);
+
+            bletiny_l2cap_coc_remove(event->disconnect.conn_handle,
+                                     event->disconnect.chan);
+            return 0;
+        case BLE_L2CAP_EVENT_COC_ACCEPT:
+            return bletiny_l2cap_coc_accept(event->accept.conn_handle,
+                                            event->accept.peer_sdu_size,
+                                            event->accept.chan);
+
+        case BLE_L2CAP_EVENT_COC_DATA_RECEIVED:
+            bletiny_l2cap_coc_recv(event->receive.chan, event->receive.sdu_rx);
+            return 0;
+        default:
+            return 0;
+    }
+}
+#endif
+
+int
+bletiny_l2cap_create_srv(uint16_t psm)
+{
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) == 0
+    console_printf("BLE L2CAP LE COC not supported.");
+    console_printf(" Configure nimble host to enable it\n");
+    return 0;
+#else
+
+    return ble_l2cap_create_server(psm, BLETINY_COC_MTU, bletiny_l2cap_event,
+                                                                       NULL);
+#endif
+}
+
+int
+bletiny_l2cap_connect(uint16_t conn_handle, uint16_t psm)
+{
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) == 0
+    console_printf("BLE L2CAP LE COC not supported.");
+    console_printf(" Configure nimble host to enable it\n");
+    return 0;
+#else
+
+    struct os_mbuf *sdu_rx;
+
+    sdu_rx = os_memblock_get(&bletiny_sdu_coc_pool);
+    assert(sdu_rx != NULL);
+
+    return ble_l2cap_connect(conn_handle, psm, BLETINY_COC_MTU, sdu_rx,
+                             bletiny_l2cap_event, NULL);
+#endif
+}
+
+int
+bletiny_l2cap_disconnect(uint16_t conn_handle, uint16_t idx)
+{
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) == 0
+    console_printf("BLE L2CAP LE COC not supported.");
+    console_printf(" Configure nimble host to enable it\n");
+    return 0;
+#else
+
+    struct bletiny_conn *conn;
+    struct bletiny_l2cap_coc *coc;
+    int i;
+
+    conn = bletiny_conn_find(conn_handle);
+    assert(conn != NULL);
+
+    i = 0;
+    SLIST_FOREACH(coc, &conn->coc_list, next) {
+        if (i == idx) {
+                break;
+        }
+        i++;
+    }
+    assert(coc != NULL);
+
+    ble_l2cap_disconnect(coc->chan);
+
+    return 0;
+#endif
+}
+
 /**
  * main
  *
@@ -1593,6 +1790,31 @@ main(void)
                          "bletiny_dsc_pool");
     assert(rc == 0);
 
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+    /* For testing we want to support all the available channels */
+    bletiny_sdu_coc_mem = malloc(
+        OS_MEMPOOL_BYTES(BLETINY_COC_MTU * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
+                         sizeof (struct os_mbuf)));
+    assert(bletiny_sdu_coc_mem != NULL);
+
+    rc = os_mempool_init(&bletiny_sdu_coc_pool,
+                         BLETINY_COC_MTU * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
+                         sizeof (struct os_mbuf), bletiny_sdu_coc_mem,
+                         "bletiny_coc_sdu_pool");
+    assert(rc == 0);
+
+    bletiny_coc_conn_mem = malloc(
+        OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
+                         sizeof (struct bletiny_l2cap_coc)));
+    assert(bletiny_coc_conn_mem != NULL);
+
+    rc = os_mempool_init(&bletiny_coc_conn_pool,
+                         MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
+                         sizeof (struct bletiny_l2cap_coc), 
bletiny_coc_conn_mem,
+                         "bletiny_coc_conn_pool");
+    assert(rc == 0);
+#endif
+
     /* Initialize the logging system. */
     log_register("bletiny", &bletiny_log, &log_console_handler, NULL,
                  LOG_SYSLEVEL);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8b73a4d8/net/nimble/host/src/ble_l2cap_sig.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig.c 
b/net/nimble/host/src/ble_l2cap_sig.c
index fdaa408..40cda11 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -890,7 +890,8 @@ ble_l2cap_sig_disc_req_rx(uint16_t conn_handle, struct 
ble_l2cap_sig_hdr *hdr,
     ble_hs_conn_delete_chan(conn, chan);
     ble_hs_unlock();
 
-    return ble_l2cap_sig_tx(conn_handle, txom);
+    ble_l2cap_sig_tx(conn_handle, txom);
+    return 0;
 }
 
 static void
@@ -929,7 +930,7 @@ done:
 }
 
 static int
-ble_l2cap_sig_disc_rsp_rx (uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr,
+ble_l2cap_sig_disc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr,
                            struct os_mbuf **om)
 {
     struct ble_l2cap_sig_disc_rsp *rsp;

Reply via email to