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 2017/02/13 19:31:36 UTC

[01/10] incubator-mynewt-core git commit: bletiny: Add support to connect/disconnect L2CAP LE COC

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: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Authored: Tue Jan 31 01:28:20 2017 +0100
Committer: \u0141ukasz Rymanowski <lu...@codecoup.pl>
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;


[10/10] incubator-mynewt-core git commit: BLE Host - Update for CoC field name change.

Posted by cc...@apache.org.
BLE Host - Update for CoC field name change.


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

Branch: refs/heads/develop
Commit: 8b510e973cec21c776fdd2ab4801793a2339dd09
Parents: 0727c55
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Feb 13 11:25:04 2017 -0800
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon Feb 13 11:25:55 2017 -0800

----------------------------------------------------------------------
 net/nimble/host/src/ble_l2cap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8b510e97/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 bab2365..2fb48b6 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -77,7 +77,7 @@ ble_l2cap_chan_free(struct ble_l2cap_chan *chan)
         return;
     }
 
-    os_mbuf_free_chain(chan->blc_rx_buf);
+    os_mbuf_free_chain(chan->rx_buf);
 
     rc = os_memblock_put(&ble_l2cap_chan_pool, chan);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0);


[05/10] incubator-mynewt-core git commit: nimble/l2cap: Remove not needed checks

Posted by cc...@apache.org.
nimble/l2cap: Remove not needed checks

Minor change removing not needed check for return code.


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

Branch: refs/heads/develop
Commit: e9bb23e6176a55bd4897f6b8bd2213c87a04f0d6
Parents: 82c6878
Author: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Authored: Tue Jan 17 15:37:30 2017 +0100
Committer: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Committed: Thu Feb 2 12:59:59 2017 +0100

----------------------------------------------------------------------
 net/nimble/host/src/ble_l2cap_sig_cmd.c | 26 ++++----------------------
 1 file changed, 4 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e9bb23e6/net/nimble/host/src/ble_l2cap_sig_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_cmd.c b/net/nimble/host/src/ble_l2cap_sig_cmd.c
index 7458210..6b58f92 100644
--- a/net/nimble/host/src/ble_l2cap_sig_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sig_cmd.c
@@ -138,20 +138,13 @@ ble_l2cap_sig_reject_tx(uint16_t conn_handle, uint8_t id, uint16_t reason,
                                data, data_len);
 
     STATS_INC(ble_l2cap_stats, sig_rx);
-    rc = ble_l2cap_sig_tx(conn_handle, txom);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
+    return ble_l2cap_sig_tx(conn_handle, txom);
 }
 
 int
 ble_l2cap_sig_reject_invalid_cid_tx(uint16_t conn_handle, uint8_t id,
                                     uint16_t src_cid, uint16_t dst_cid)
 {
-    int rc;
-
     struct {
         uint16_t local_cid;
         uint16_t remote_cid;
@@ -160,10 +153,9 @@ ble_l2cap_sig_reject_invalid_cid_tx(uint16_t conn_handle, uint8_t id,
         .remote_cid = src_cid,
     };
 
-    rc = ble_l2cap_sig_reject_tx(conn_handle, id,
+    return ble_l2cap_sig_reject_tx(conn_handle, id,
                                  BLE_L2CAP_SIG_ERR_INVALID_CID,
                                  &data, sizeof data);
-    return rc;
 }
 
 static void
@@ -210,12 +202,7 @@ ble_l2cap_sig_update_req_tx(uint16_t conn_handle, uint8_t id,
     ble_l2cap_sig_update_req_write(payload_buf, BLE_L2CAP_SIG_UPDATE_REQ_SZ,
                                    req);
 
-    rc = ble_l2cap_sig_tx(conn_handle, txom);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
+    return ble_l2cap_sig_tx(conn_handle, txom);
 }
 
 static void
@@ -260,10 +247,5 @@ ble_l2cap_sig_update_rsp_tx(uint16_t conn_handle, uint8_t id, uint16_t result)
     ble_l2cap_sig_update_rsp_write(payload_buf, BLE_L2CAP_SIG_UPDATE_RSP_SZ,
                                    &rsp);
 
-    rc = ble_l2cap_sig_tx(conn_handle, txom);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
+    return ble_l2cap_sig_tx(conn_handle, txom);
 }


[02/10] incubator-mynewt-core git commit: nimble/l2cap: Add LE L2CAP COC API

Posted by cc...@apache.org.
nimble/l2cap: Add LE L2CAP COC API

This patch adds API for LE Connection Oriented Channels.
Note that implementation is hided behind BLE_L2CAP_COC_MAX_NUM flag
which defines maximum number of supported dynamic channels

Overview:
Idea is that credits are hidden from the user and controlled by the
stack. User creates its own memory pool for SDU taking into account
SDU size and number of L2CAP LE COC channels he expect to use.
User profiles SDU (os_mbuf) to the stack when creates or accepts
connection.

Flow overview.

Similar to GAP, L2CAP defines following events:

BLE_L2CAP_EVENT_COC_CONNECTED
BLE_L2CAP_EVENT_COC_DISCONNECT
BLE_L2CAP_EVENT_COC_ACCEPT
BLE_L2CAP_EVENT_COC_DATA_RECEIVED

which application should handle in ble_l2cap_event_fn() called cb in
 description below.

Outgoing connection:
1. *chan = ble_l2cap_connect(conn_handle, psm, mtu, struct os_mbuf *sdu_rx,
                             *cb, *cb_arg);

2. BLE_L2CAP_EVENT_COC_CONNECTED event is sent when channel has been
 established or rejected. If connection has been rejected, event contains
 reason for that.

3. BLE_L2CAP_EVENT_COC_DATA_RECEIVED event is sent  on incoming data.
 Note, it is sent when SDU is completed
3a. User needs to call ble_l2cap_recv_ready(*chan, sdu_rx) where
 sdu_rx is os_mbuf for next SDU.

4. To send data do remote device ble_l2cap_send(*chan, sdu_tx) shall
 be called

5. To drop channel ble_l2cap_disconnect(*chan) shall be called.
6. When disconnected BLE_L2CAP_EVENT_COC_DISCONNECTD event is sent

Incoming connection:
1. ble_l2cap_create_server(psm, mtu, *cb, *cb_arg)
2. BLE_L2CAP_COC_EVENT_ACCEPT event is sent on create connection request
 if there is server for given PSM in the stack.
2a. User might want to check required security and MTU requirements
 before accepts connection.
2b. User needs to call ble_l2cap_recv_ready(*chan, sdu_rx) where
 sdu_rx is os_mbuf for next SDU.
2c. If accept_cb returns 0, connection response is sent
2d. User gets BLE_L2CAP_EVENT_COC_CONNECTED event with a status


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

Branch: refs/heads/develop
Commit: 1afc08a637e0c9b94e78387ef4fe3aeffb1a37f1
Parents: 552adce
Author: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Authored: Tue Jan 17 14:13:24 2017 +0100
Committer: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Committed: Thu Feb 2 12:59:59 2017 +0100

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_l2cap.h | 114 ++++++++++++++++++++++++++
 net/nimble/host/src/ble_l2cap.c          |  47 ++++++++++-
 net/nimble/host/src/ble_l2cap_priv.h     |  18 ++++
 net/nimble/host/syscfg.yml               |   5 ++
 4 files changed, 181 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1afc08a6/net/nimble/host/include/host/ble_l2cap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_l2cap.h b/net/nimble/host/include/host/ble_l2cap.h
index 52849af..604d080 100644
--- a/net/nimble/host/include/host/ble_l2cap.h
+++ b/net/nimble/host/include/host/ble_l2cap.h
@@ -56,6 +56,22 @@ struct ble_hs_conn;
 #define BLE_L2CAP_SIG_ERR_MTU_EXCEEDED          0x0001
 #define BLE_L2CAP_SIG_ERR_INVALID_CID           0x0002
 
+#define BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS        0x0000
+#define BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM            0x0002
+#define BLE_L2CAP_COC_ERR_NO_RESOURCES              0x0004
+#define BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN       0x0005
+#define BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR       0x0006
+#define BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ       0x0007
+#define BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC          0x0008
+#define BLE_L2CAP_COC_ERR_INVALID_SOURCE_CID        0x0009
+#define BLE_L2CAP_COC_ERR_SOURCE_CID_ALREADY_USED   0x000A
+#define BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS   0x000B
+
+#define BLE_L2CAP_EVENT_COC_CONNECTED                 0
+#define BLE_L2CAP_EVENT_COC_DISCONNECTED              1
+#define BLE_L2CAP_EVENT_COC_ACCEPT                    2
+#define BLE_L2CAP_EVENT_COC_DATA_RECEIVED             3
+
 typedef void ble_l2cap_sig_update_fn(uint16_t conn_handle, int status,
                                      void *arg);
 
@@ -70,6 +86,104 @@ int ble_l2cap_sig_update(uint16_t conn_handle,
                          struct ble_l2cap_sig_update_params *params,
                          ble_l2cap_sig_update_fn *cb, void *cb_arg);
 
+struct ble_l2cap_chan;
+
+/**
+ * Represents a L2CAP-related event.
+ * When such an event occurs, the host notifies the application by passing an
+ * instance of this structure to an application-specified callback.
+ */
+struct ble_l2cap_event {
+    /**
+     * Indicates the type of L2CAP event that occurred.  This is one of the
+     * BLE_L2CAP_EVENT codes.
+     */
+    uint8_t type;
+
+    /**
+     * A discriminated union containing additional details concerning the L2CAP
+     * event.  The 'type' field indicates which member of the union is valid.
+     */
+    union {
+        /**
+         * Represents a connection attempt. Valid for the following event
+         * types:
+         *     o BLE_L2CAP_EVENT_COC_CONNECTED */
+        struct {
+            /**
+             * The status of the connection attempt;
+             *     o 0: the connection was successfully established.
+             *     o BLE host error code: the connection attempt failed for
+             *       the specified reason.
+             */
+            int status;
+
+            /** Connection handle of the relevant connection */
+            uint16_t conn_handle;
+
+            /** The L2CAP channel of the relevant L2CAP connection. */
+            struct ble_l2cap_chan *chan;
+        } connect;
+
+        /**
+         * Represents a terminated connection. Valid for the following event
+         * types:
+         *     o BLE_L2CAP_EVENT_COC_DISCONNECTED
+         */
+        struct {
+            /** Connection handle of the relevant connection */
+            uint16_t conn_handle;
+
+            /** Information about the L2CAP connection prior to termination. */
+            struct ble_l2cap_chan *chan;
+        } disconnect;
+
+        /**
+         * Represents connection accept. Valid for the following event
+         * types:
+         *     o BLE_L2CAP_EVENT_COC_ACCEPT
+         */
+        struct {
+            /** Connection handle of the relevant connection */
+            uint16_t conn_handle;
+
+            /** MTU supported by peer device on the channel */
+            uint16_t peer_sdu_size;
+
+            /** The L2CAP channel of the relevant L2CAP connection. */
+            struct ble_l2cap_chan *chan;
+        } accept;
+
+        /**
+         * Represents received data. Valid for the following event
+         * types:
+         *     o BLE_L2CAP_EVENT_COC_DATA_RECEIVED
+         */
+        struct {
+            /** Connection handle of the relevant connection */
+            uint16_t conn_handle;
+
+            /** The L2CAP channel of the relevant L2CAP connection. */
+            struct ble_l2cap_chan *chan;
+
+            /** The mbuf with received SDU. */
+            struct os_mbuf *sdu_rx;
+        } receive;
+    };
+};
+
+typedef int ble_l2cap_event_fn(struct ble_l2cap_event *event, void *arg);
+
+int ble_l2cap_create_server(uint16_t psm, uint16_t mtu,
+                            ble_l2cap_event_fn *cb, void *cb_arg);
+
+int ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
+                      struct os_mbuf *sdu_rx,
+                      ble_l2cap_event_fn *cb, void *cb_arg);
+int ble_l2cap_disconnect(struct ble_l2cap_chan *chan);
+int ble_l2cap_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx);
+void ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx);
+
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1afc08a6/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 a61ada7..bf279de 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -31,8 +31,9 @@ _Static_assert(sizeof (struct ble_l2cap_hdr) == BLE_L2CAP_HDR_SZ,
 struct os_mempool ble_l2cap_chan_pool;
 
 static os_membuf_t ble_l2cap_chan_mem[
-    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_MAX_CHANS),
-                     sizeof (struct ble_l2cap_chan))
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_MAX_CHANS) +
+                    MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
+                    sizeof (struct ble_l2cap_chan))
 ];
 
 STATS_SECT_DECL(ble_l2cap_stats) ble_l2cap_stats;
@@ -122,6 +123,44 @@ ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len)
     return om;
 }
 
+int
+ble_l2cap_create_server(uint16_t psm, uint16_t mtu,
+                        ble_l2cap_event_fn *cb, void *cb_arg)
+{
+    /*TODO: Create server object and put it on the queue */
+    return BLE_HS_ENOTSUP;
+}
+
+int
+ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
+                  struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, void *cb_arg)
+{
+    /*
+     * TODO In here we are going to create l2cap channel and send
+     * BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ
+     */
+    return BLE_HS_ENOTSUP;
+}
+
+int ble_l2cap_disconnect(struct ble_l2cap_chan *chan)
+{
+    /*TODO Implement */
+    return BLE_HS_ENOTSUP;
+}
+
+int
+ble_l2cap_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu)
+{
+    /*TODO Implement */
+    return BLE_HS_ENOTSUP;
+}
+
+void
+ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx)
+{
+    /*TODO In here we going to update sdu_rx buffer */
+}
+
 static void
 ble_l2cap_forget_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -322,7 +361,9 @@ ble_l2cap_init(void)
 {
     int rc;
 
-    rc = os_mempool_init(&ble_l2cap_chan_pool, MYNEWT_VAL(BLE_L2CAP_MAX_CHANS),
+    rc = os_mempool_init(&ble_l2cap_chan_pool,
+                         MYNEWT_VAL(BLE_L2CAP_MAX_CHANS) +
+                         MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
                          sizeof (struct ble_l2cap_chan),
                          ble_l2cap_chan_mem, "ble_l2cap_chan_pool");
     if (rc != 0) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1afc08a6/net/nimble/host/src/ble_l2cap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_priv.h b/net/nimble/host/src/ble_l2cap_priv.h
index 7733c20..900d749 100644
--- a/net/nimble/host/src/ble_l2cap_priv.h
+++ b/net/nimble/host/src/ble_l2cap_priv.h
@@ -63,6 +63,14 @@ typedef uint8_t ble_l2cap_chan_flags;
 
 typedef int ble_l2cap_rx_fn(uint16_t conn_handle, struct os_mbuf **rxom);
 
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+struct ble_l2cap_coc_endpoint {
+    uint16_t mtu;
+    uint16_t credits;
+    struct os_mbuf *sdu;
+};
+#endif
+
 struct ble_l2cap_chan {
     SLIST_ENTRY(ble_l2cap_chan) next;
     uint16_t scid;
@@ -74,6 +82,16 @@ struct ble_l2cap_chan {
     uint16_t rx_len;        /* Length of current reassembled rx packet. */
 
     ble_l2cap_rx_fn *rx_fn;
+
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+    uint16_t conn_handle;
+    uint16_t dcid;
+    uint16_t psm;
+    struct ble_l2cap_coc_endpoint coc_rx;
+    struct ble_l2cap_coc_endpoint coc_tx;
+    ble_l2cap_event_fn *cb;
+    void *cb_arg;
+#endif
 };
 
 struct ble_l2cap_hdr {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1afc08a6/net/nimble/host/syscfg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/syscfg.yml b/net/nimble/host/syscfg.yml
index 9b3ba66..dd42ed8 100644
--- a/net/nimble/host/syscfg.yml
+++ b/net/nimble/host/syscfg.yml
@@ -52,6 +52,11 @@ syscfg.defs:
             passes since the previous fragment was received, the connection is
             terminated.  A value of 0 means no timeout.
         value: 30000
+    BLE_L2CAP_COC_MAX_NUM:
+        description: >
+            Defines maximum number of LE Connection Oriented Channels channels.
+            When set to (0), LE COC is not compiled in.
+        value: 0
 
     # Security manager settings.
     BLE_SM_LEGACY:


[07/10] incubator-mynewt-core git commit: nimble/l2cap: Add support to connect L2CAP LE COC

Posted by cc...@apache.org.
nimble/l2cap: Add support to connect L2CAP LE COC

With this patch nibmle is support to create L2CAP LE COC
and handle incoming connection request.

Note: New error codes (BLE_HS_EFOO) has been added in
order to translate L2CAP COC error codes to user


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

Branch: refs/heads/develop
Commit: 696e79d3455d4141b6a17e649219140db9f7e66f
Parents: 1afc08a
Author: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Authored: Tue Jan 31 00:08:13 2017 +0100
Committer: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Committed: Thu Feb 2 12:59:59 2017 +0100

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_hs.h    |   4 +
 net/nimble/host/src/ble_hs_priv.h        |   1 +
 net/nimble/host/src/ble_l2cap.c          |  15 +-
 net/nimble/host/src/ble_l2cap_coc.c      | 131 +++++++++
 net/nimble/host/src/ble_l2cap_coc_priv.h |  68 +++++
 net/nimble/host/src/ble_l2cap_priv.h     |   9 +-
 net/nimble/host/src/ble_l2cap_sig.c      | 365 +++++++++++++++++++++++++-
 net/nimble/host/src/ble_l2cap_sig_cmd.c  |  29 +-
 net/nimble/host/src/ble_l2cap_sig_priv.h |  31 ++-
 9 files changed, 633 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696e79d3/net/nimble/host/include/host/ble_hs.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs.h b/net/nimble/host/include/host/ble_hs.h
index 4ee6c79..8dd2296 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -66,6 +66,10 @@ struct os_event;
 #define BLE_HS_ENOMEM_EVT           20
 #define BLE_HS_ENOADDR              21
 #define BLE_HS_ENOTSYNCED           22
+#define BLE_HS_EAUTHEN              23
+#define BLE_HS_EAUTHOR              24
+#define BLE_HS_EENCRYPT             25
+#define BLE_HS_EENCRYPT_KEY_SZ      26
 
 #define BLE_HS_ERR_ATT_BASE         0x100   /* 256 */
 #define BLE_HS_ATT_ERR(x)           ((x) ? BLE_HS_ERR_ATT_BASE + (x) : 0)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696e79d3/net/nimble/host/src/ble_hs_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h
index 2cc8b40..4bdb22c 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -37,6 +37,7 @@
 #include "ble_hs_startup_priv.h"
 #include "ble_l2cap_priv.h"
 #include "ble_l2cap_sig_priv.h"
+#include "ble_l2cap_coc_priv.h"
 #include "ble_sm_priv.h"
 #include "ble_hs_adv_priv.h"
 #include "ble_hs_pvcy_priv.h"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696e79d3/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 bf279de..d881acb 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -24,6 +24,7 @@
 #include "nimble/ble.h"
 #include "nimble/hci_common.h"
 #include "ble_hs_priv.h"
+#include "ble_l2cap_coc_priv.h"
 
 _Static_assert(sizeof (struct ble_l2cap_hdr) == BLE_L2CAP_HDR_SZ,
                "struct ble_l2cap_hdr must be 4 bytes");
@@ -127,19 +128,14 @@ int
 ble_l2cap_create_server(uint16_t psm, uint16_t mtu,
                         ble_l2cap_event_fn *cb, void *cb_arg)
 {
-    /*TODO: Create server object and put it on the queue */
-    return BLE_HS_ENOTSUP;
+    return ble_l2cap_coc_create_server(psm, mtu, cb, cb_arg);
 }
 
 int
 ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
                   struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, void *cb_arg)
 {
-    /*
-     * TODO In here we are going to create l2cap channel and send
-     * BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ
-     */
-    return BLE_HS_ENOTSUP;
+    return ble_l2cap_sig_coc_connect(conn_handle, psm, mtu, sdu_rx, cb, cb_arg);
 }
 
 int ble_l2cap_disconnect(struct ble_l2cap_chan *chan)
@@ -375,6 +371,11 @@ ble_l2cap_init(void)
         return rc;
     }
 
+    rc = ble_l2cap_coc_init();
+    if (rc != 0) {
+        return rc;
+    }
+
     rc = ble_sm_init();
     if (rc != 0) {
         return rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696e79d3/net/nimble/host/src/ble_l2cap_coc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_coc.c b/net/nimble/host/src/ble_l2cap_coc.c
new file mode 100644
index 0000000..6286d43
--- /dev/null
+++ b/net/nimble/host/src/ble_l2cap_coc.c
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "console/console.h"
+#include "nimble/ble.h"
+#include "ble_hs_priv.h"
+#include "ble_l2cap_priv.h"
+#include "ble_l2cap_coc_priv.h"
+#include "ble_l2cap_sig_priv.h"
+
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+
+STAILQ_HEAD(ble_l2cap_coc_srv_list, ble_l2cap_coc_srv);
+
+static struct ble_l2cap_coc_srv_list ble_l2cap_coc_srvs;
+
+static os_membuf_t ble_l2cap_coc_srv_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
+                    sizeof (struct ble_l2cap_coc_srv))
+];
+
+static struct os_mempool ble_l2cap_coc_srv_pool;
+
+static void
+ble_l2cap_coc_dbg_assert_srv_not_inserted(struct ble_l2cap_coc_srv *srv)
+{
+#if MYNEWT_VAL(BLE_HS_DEBUG)
+    struct ble_l2cap_coc_srv *cur;
+
+    STAILQ_FOREACH(cur, &ble_l2cap_coc_srvs, next) {
+        BLE_HS_DBG_ASSERT(cur != srv);
+    }
+#endif
+}
+
+static struct ble_l2cap_coc_srv *
+ble_l2cap_coc_srv_alloc(void)
+{
+    struct ble_l2cap_coc_srv *srv;
+
+    srv = os_memblock_get(&ble_l2cap_coc_srv_pool);
+    if (srv != NULL) {
+        memset(srv, 0, sizeof(*srv));
+    }
+
+    return srv;
+}
+
+int
+ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu,
+                                        ble_l2cap_event_fn *cb, void *cb_arg)
+{
+    struct ble_l2cap_coc_srv * srv;
+
+    srv = ble_l2cap_coc_srv_alloc();
+    if (!srv) {
+            return BLE_HS_ENOMEM;
+    }
+
+    srv->psm = psm;
+    srv->mtu = mtu;
+    srv->cb = cb;
+    srv->cb_arg = cb_arg;
+
+    ble_l2cap_coc_dbg_assert_srv_not_inserted(srv);
+
+    STAILQ_INSERT_HEAD(&ble_l2cap_coc_srvs, srv, next);
+
+    return 0;
+}
+
+uint16_t
+ble_l2cap_coc_get_cid(void)
+{
+    static uint16_t next_cid = BLE_L2CAP_COC_CID_START;
+
+    if (next_cid > BLE_L2CAP_COC_CID_END) {
+            next_cid = BLE_L2CAP_COC_CID_START;
+    }
+
+    /*TODO: Make it smarter*/
+    return next_cid++;
+}
+
+struct ble_l2cap_coc_srv *
+ble_l2cap_coc_srv_find(uint16_t psm)
+{
+    struct ble_l2cap_coc_srv *cur, *srv;
+
+    srv = NULL;
+    STAILQ_FOREACH(cur, &ble_l2cap_coc_srvs, next) {
+        if (cur->psm == psm) {
+                srv = cur;
+                break;
+        }
+    }
+
+    return srv;
+}
+
+int
+ble_l2cap_coc_init(void)
+{
+    STAILQ_INIT(&ble_l2cap_coc_srvs);
+
+    return os_mempool_init(&ble_l2cap_coc_srv_pool,
+                         MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
+                         sizeof (struct ble_l2cap_coc_srv),
+                         ble_l2cap_coc_srv_mem,
+                         "ble_l2cap_coc_srv_pool");
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696e79d3/net/nimble/host/src/ble_l2cap_coc_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_coc_priv.h b/net/nimble/host/src/ble_l2cap_coc_priv.h
new file mode 100644
index 0000000..31e81e7
--- /dev/null
+++ b/net/nimble/host/src/ble_l2cap_coc_priv.h
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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_COC_PRIV_
+#define H_L2CAP_COC_PRIV_
+
+#include <inttypes.h>
+#include "syscfg/syscfg.h"
+#include "os/queue.h"
+#include "host/ble_l2cap.h"
+#include "ble_l2cap_sig_priv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_L2CAP_COC_MTU                       100
+#define BLE_L2CAP_COC_CID_START                 0x0040
+#define BLE_L2CAP_COC_CID_END                   0x007F
+
+struct ble_l2cap_chan;
+
+struct ble_l2cap_coc_endpoint {
+    uint16_t mtu;
+    uint16_t credits;
+    struct os_mbuf *sdu;
+};
+
+struct ble_l2cap_coc_srv {
+    STAILQ_ENTRY(ble_l2cap_coc_srv) next;
+    uint16_t psm;
+    uint16_t mtu;
+    ble_l2cap_event_fn *cb;
+    void *cb_arg;
+};
+
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+int ble_l2cap_coc_init(void);
+uint16_t ble_l2cap_coc_get_cid(void);
+int ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu,
+                                ble_l2cap_event_fn *cb, void *cb_arg);
+struct ble_l2cap_coc_srv * ble_l2cap_coc_srv_find(uint16_t psm);
+#else
+#define ble_l2cap_coc_init()                                    0
+#define ble_l2cap_coc_create_server(psm, mtu, cb, cb_arg)       BLE_HS_ENOTSUP
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_L2CAP_COC_PRIV_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696e79d3/net/nimble/host/src/ble_l2cap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_priv.h b/net/nimble/host/src/ble_l2cap_priv.h
index 900d749..cc4e0ed 100644
--- a/net/nimble/host/src/ble_l2cap_priv.h
+++ b/net/nimble/host/src/ble_l2cap_priv.h
@@ -20,6 +20,7 @@
 #ifndef H_L2CAP_PRIV_
 #define H_L2CAP_PRIV_
 
+#include "ble_l2cap_coc_priv.h"
 #include "host/ble_l2cap.h"
 #include <inttypes.h>
 #include "stats/stats.h"
@@ -63,14 +64,6 @@ typedef uint8_t ble_l2cap_chan_flags;
 
 typedef int ble_l2cap_rx_fn(uint16_t conn_handle, struct os_mbuf **rxom);
 
-#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
-struct ble_l2cap_coc_endpoint {
-    uint16_t mtu;
-    uint16_t credits;
-    struct os_mbuf *sdu;
-};
-#endif
-
 struct ble_l2cap_chan {
     SLIST_ENTRY(ble_l2cap_chan) next;
     uint16_t scid;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696e79d3/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 09df2c3..fe9362f 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -55,7 +55,8 @@
 #define BLE_L2CAP_SIG_UNRESPONSIVE_TIMEOUT      30000   /* Milliseconds. */
 
 #define BLE_L2CAP_SIG_PROC_OP_UPDATE            0
-#define BLE_L2CAP_SIG_PROC_OP_MAX               1
+#define BLE_L2CAP_SIG_PROC_OP_CONNECT           1
+#define BLE_L2CAP_SIG_PROC_OP_MAX               2
 
 struct ble_l2cap_sig_proc {
     STAILQ_ENTRY(ble_l2cap_sig_proc) next;
@@ -70,6 +71,9 @@ struct ble_l2cap_sig_proc {
             ble_l2cap_sig_update_fn *cb;
             void *cb_arg;
         } update;
+        struct {
+            struct ble_l2cap_chan *chan;
+        } connect;
     };
 };
 
@@ -85,6 +89,14 @@ static ble_l2cap_sig_rx_fn ble_l2cap_sig_rx_noop;
 static ble_l2cap_sig_rx_fn ble_l2cap_sig_update_req_rx;
 static ble_l2cap_sig_rx_fn ble_l2cap_sig_update_rsp_rx;
 
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_coc_req_rx;
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_coc_rsp_rx;
+#else
+#define ble_l2cap_sig_coc_req_rx    ble_l2cap_sig_rx_noop
+#define ble_l2cap_sig_coc_rsp_rx    ble_l2cap_sig_rx_noop
+#endif
+
 static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = {
     [BLE_L2CAP_SIG_OP_REJECT]               = ble_l2cap_sig_rx_noop,
     [BLE_L2CAP_SIG_OP_CONNECT_RSP]          = ble_l2cap_sig_rx_noop,
@@ -97,7 +109,8 @@ static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = {
     [BLE_L2CAP_SIG_OP_MOVE_CHAN_CONF_RSP]   = ble_l2cap_sig_rx_noop,
     [BLE_L2CAP_SIG_OP_UPDATE_REQ]           = ble_l2cap_sig_update_req_rx,
     [BLE_L2CAP_SIG_OP_UPDATE_RSP]           = ble_l2cap_sig_update_rsp_rx,
-    [BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP]   = ble_l2cap_sig_rx_noop,
+    [BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ]   = ble_l2cap_sig_coc_req_rx,
+    [BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP]   = ble_l2cap_sig_coc_rsp_rx,
     [BLE_L2CAP_SIG_OP_FLOW_CTRL_CREDIT]     = ble_l2cap_sig_rx_noop,
 };
 
@@ -471,6 +484,343 @@ done:
     return rc;
 }
 
+/*****************************************************************************
+ * $connect                                                                  *
+ *****************************************************************************/
+
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+
+static int
+ble_l2cap_sig_coc_err2ble_hs_err(uint16_t l2cap_coc_err)
+{
+    switch (l2cap_coc_err) {
+    case BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS:
+        return 0;
+    case BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM:
+        return BLE_HS_ENOTSUP;
+    case BLE_L2CAP_COC_ERR_NO_RESOURCES:
+        return BLE_HS_ENOMEM;
+    case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN:
+        return BLE_HS_EAUTHEN;
+    case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR:
+        return BLE_HS_EAUTHOR;
+    case BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ:
+        return BLE_HS_EENCRYPT_KEY_SZ;
+    case BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC:
+        return BLE_HS_EENCRYPT;
+    case BLE_L2CAP_COC_ERR_INVALID_SOURCE_CID:
+        return BLE_HS_EREJECT;
+    case BLE_L2CAP_COC_ERR_SOURCE_CID_ALREADY_USED:
+        return BLE_HS_EALREADY;
+    case BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS:
+        return BLE_HS_EINVAL;
+    default:
+        return BLE_HS_EUNKNOWN;
+    }
+}
+
+static int
+ble_l2cap_sig_ble_hs_err2coc_err(uint16_t ble_hs_err)
+{
+    switch (ble_hs_err) {
+    case BLE_HS_ENOMEM:
+        return BLE_L2CAP_COC_ERR_NO_RESOURCES;
+    case BLE_HS_EAUTHEN:
+        return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN;
+    case BLE_HS_EAUTHOR:
+        return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR;
+    case BLE_HS_EENCRYPT:
+        return BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC;
+    case BLE_HS_EENCRYPT_KEY_SZ:
+        return BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ;
+    case BLE_HS_EINVAL:
+        return BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS;
+    default:
+        return BLE_L2CAP_COC_ERR_NO_RESOURCES;
+    }
+}
+
+static void
+ble_l2cap_event_coc_connected(struct ble_l2cap_chan *chan, uint16_t status)
+{
+    struct ble_l2cap_event event = { };
+
+    event.type = BLE_L2CAP_EVENT_COC_CONNECTED;
+    event.connect.conn_handle = chan->conn_handle;
+    event.connect.chan = chan;
+    event.connect.status = status;
+
+    chan->cb(&event, chan->cb_arg);
+}
+
+static int
+ble_l2cap_event_coc_accept(struct ble_l2cap_chan *chan, uint16_t peer_sdu_size)
+{
+    struct ble_l2cap_event event = { };
+
+    event.type = BLE_L2CAP_EVENT_COC_ACCEPT;
+    event.accept.chan = chan;
+    event.accept.conn_handle = chan->conn_handle;
+    event.accept.peer_sdu_size = peer_sdu_size;
+
+    return chan->cb(&event, chan->cb_arg);
+}
+
+static void
+ble_l2cap_sig_coc_connect_cb(struct ble_l2cap_sig_proc *proc, int status)
+{
+    struct ble_l2cap_chan *chan;
+
+    if (!proc) {
+            return;
+    }
+
+    chan = proc->connect.chan;
+    if (!chan || !chan->cb) {
+        return;
+    }
+
+    ble_l2cap_event_coc_connected(chan, status);
+}
+
+static int
+ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr,
+                         struct os_mbuf **om)
+{
+    int rc;
+    struct ble_l2cap_sig_le_con_req *req;
+    struct os_mbuf *txom;
+    struct ble_l2cap_sig_le_con_rsp *rsp;
+    struct ble_l2cap_coc_srv *srv;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    uint16_t scid;
+
+    rc = ble_hs_mbuf_pullup_base(om, sizeof(req));
+    if (rc != 0) {
+        return rc;
+    }
+
+    rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP,
+                                hdr->identifier, sizeof(*rsp), &txom);
+    if (!rsp) {
+        /* Well, nothing smart we can do if there is no memory for response.
+         * Remote will timeout.
+         */
+        return 0;
+    }
+
+    req = (struct ble_l2cap_sig_le_con_req *)(*om)->om_data;
+
+    ble_hs_lock();
+    conn = ble_hs_conn_find_assert(conn_handle);
+
+    /* Check if there is server registered on this PSM */
+    srv = ble_l2cap_coc_srv_find(le16toh(req->psm));
+    if (!srv) {
+        rsp->result = htole16(BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM);
+        goto failed;
+    }
+
+    /* Verify CID */
+    scid = le16toh(req->scid);
+    if (scid < BLE_L2CAP_COC_CID_START || scid > BLE_L2CAP_COC_CID_END) {
+        /*FIXME: Check if SCID is not already used */
+        rsp->result = htole16(BLE_L2CAP_COC_ERR_INVALID_SOURCE_CID);
+        goto failed;
+    }
+
+    chan = ble_l2cap_chan_alloc();
+    if (!chan) {
+        rsp->result = htole16(BLE_L2CAP_COC_ERR_NO_RESOURCES);
+        goto failed;
+    }
+
+    chan->cb = srv->cb;
+    chan->cb_arg = srv->cb_arg;
+    chan->conn_handle = conn_handle;
+    chan->dcid = scid;
+    chan->my_mtu = BLE_L2CAP_COC_MTU;
+
+    /* Fill up remote configuration. Note MPS is the L2CAP MTU*/
+    chan->peer_mtu = le16toh(req->mps);
+    chan->coc_tx.credits = le16toh(req->credits);
+    chan->coc_tx.mtu = le16toh(req->mtu);
+
+    rc = ble_l2cap_event_coc_accept(chan, le16toh(req->mtu));
+    if (rc != 0) {
+        uint16_t coc_err = ble_l2cap_sig_ble_hs_err2coc_err(rc);
+        ble_l2cap_chan_free(chan);
+        rsp->result = htole16(coc_err);
+        goto failed;
+    }
+
+    chan->scid = ble_l2cap_coc_get_cid();
+    chan->coc_rx.mtu = srv->mtu;
+    chan->coc_rx.credits = 10; //FIXME Calculate it
+
+    rsp->dcid = htole16(chan->scid);
+    rsp->credits = htole16(chan->coc_rx.credits);
+    rsp->mps = htole16(chan->my_mtu);
+    rsp->mtu = htole16(chan->coc_rx.mtu);
+    rsp->result = htole16(BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS);
+
+    rc = ble_l2cap_sig_tx(conn_handle, txom);
+    if (rc == 0) {
+        /* Response sent out with a success. We are connected now*/
+        ble_hs_lock();
+        ble_hs_conn_chan_insert(conn, chan);
+        ble_hs_unlock();
+    } else {
+        ble_l2cap_chan_free(chan);
+    }
+
+    /* Notify user about connection status */
+    ble_l2cap_event_coc_connected(chan, rc);
+    ble_hs_unlock();
+
+    return 0;
+
+failed:
+    ble_hs_unlock();
+    ble_l2cap_sig_tx(conn_handle, txom);
+    return 0;
+}
+
+static int
+ble_l2cap_sig_coc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr,
+                          struct os_mbuf **om)
+{
+    struct ble_l2cap_sig_proc *proc;
+    struct ble_l2cap_sig_le_con_rsp *rsp;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    BLE_HS_LOG(DEBUG, "L2CAP LE COC connection response received\n");
+
+    proc = ble_l2cap_sig_proc_extract(conn_handle,
+                                      BLE_L2CAP_SIG_PROC_OP_CONNECT,
+                                      hdr->identifier);
+    if (!proc) {
+        return 0;
+    }
+
+    rc = ble_hs_mbuf_pullup_base(om, sizeof(*rsp));
+    if (rc != 0) {
+        goto done;
+    }
+
+    rsp = (struct ble_l2cap_sig_le_con_rsp *)(*om)->om_data;
+
+    chan = proc->connect.chan;
+
+    if (rsp->result) {
+        rc = ble_l2cap_sig_coc_err2ble_hs_err(le16toh(rsp->result));
+        goto done;
+    }
+
+    /* Fill up remote configuration
+     * Note MPS is the L2CAP MTU
+     */
+    chan->peer_mtu = le16toh(rsp->mps);
+    chan->dcid = le16toh(rsp->dcid);
+    chan->coc_tx.mtu = le16toh(rsp->mtu);
+    chan->coc_tx.credits = le16toh(rsp->credits);
+
+    ble_hs_lock();
+    conn = ble_hs_conn_find(conn_handle);
+    assert(conn != NULL);
+    ble_hs_conn_chan_insert(conn, chan);
+    ble_hs_unlock();
+
+    rc = 0;
+
+done:
+    ble_l2cap_sig_coc_connect_cb(proc, rc);
+    ble_l2cap_sig_proc_free(proc);
+
+    /* Silently ignore errors as this is response signal */
+    return 0;
+}
+
+int
+ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
+                          struct os_mbuf *sdu_rx,
+                          ble_l2cap_event_fn *cb, void *cb_arg)
+{
+    struct ble_hs_conn *conn;
+    struct ble_l2cap_sig_proc *proc;
+    struct os_mbuf *txom;
+    struct ble_l2cap_sig_le_con_req *req;
+    struct ble_l2cap_chan *chan;
+    int rc;
+
+    if (!sdu_rx || !cb) {
+        return BLE_HS_EINVAL;
+    }
+
+    ble_hs_lock();
+    conn = ble_hs_conn_find(conn_handle);
+
+    if (!conn) {
+        ble_hs_unlock();
+        return BLE_HS_ENOTCONN;
+    }
+
+    chan = ble_l2cap_chan_alloc();
+    if (!chan) {
+        ble_hs_unlock();
+        return BLE_HS_ENOMEM;
+    }
+
+    proc = ble_l2cap_sig_proc_alloc();
+    if (!proc) {
+        ble_l2cap_chan_free(chan);
+        ble_hs_unlock();
+        return BLE_HS_ENOMEM;
+    }
+
+    chan->scid = ble_l2cap_coc_get_cid();
+    chan->my_mtu = BLE_L2CAP_COC_MTU;
+    chan->coc_rx.credits = 10;
+    chan->coc_rx.mtu = mtu;
+    chan->coc_rx.sdu = sdu_rx;
+    chan->cb = cb;
+    chan->cb_arg = cb_arg;
+    chan->conn_handle = conn_handle;
+
+    proc->op = BLE_L2CAP_SIG_PROC_OP_CONNECT;
+    proc->id = ble_l2cap_sig_next_id();
+    proc->conn_handle = conn_handle;
+    proc->connect.chan = chan;
+
+    req = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ, proc->id,
+                                sizeof(*req), &txom);
+    if (!req) {
+        ble_l2cap_chan_free(chan);
+        ble_hs_unlock();
+        return BLE_HS_ENOMEM;
+    }
+
+    req->psm = htole16(psm);
+    req->scid = htole16(chan->scid);
+    req->mtu = htole16(chan->coc_rx.mtu);
+    req->mps = htole16(chan->my_mtu);
+    req->credits = htole16(chan->coc_rx.credits);
+
+    rc = ble_l2cap_sig_tx(proc->conn_handle, txom);
+    if (rc != 0) {
+        ble_l2cap_chan_free(chan);
+    }
+
+    ble_l2cap_sig_process_status(proc, rc);
+    ble_hs_unlock();
+
+    return rc;
+}
+#endif
+
 static int
 ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -620,7 +970,16 @@ ble_l2cap_sig_timer(void)
     /* Report a failure for each timed out procedure. */
     while ((proc = STAILQ_FIRST(&temp_list)) != NULL) {
         STATS_INC(ble_l2cap_stats, proc_timeout);
-        ble_l2cap_sig_update_call_cb(proc, BLE_HS_ETIMEOUT);
+        switch(proc->op) {
+            case BLE_L2CAP_SIG_PROC_OP_UPDATE:
+                ble_l2cap_sig_update_call_cb(proc, BLE_HS_ETIMEOUT);
+                break;
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+            case BLE_L2CAP_SIG_PROC_OP_CONNECT:
+                ble_l2cap_sig_coc_connect_cb(proc, BLE_HS_ETIMEOUT);
+            break;
+#endif
+        }
 
         STAILQ_REMOVE_HEAD(&temp_list, next);
         ble_l2cap_sig_proc_free(proc);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696e79d3/net/nimble/host/src/ble_l2cap_sig_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_cmd.c b/net/nimble/host/src/ble_l2cap_sig_cmd.c
index 6b58f92..f7e68c8 100644
--- a/net/nimble/host/src/ble_l2cap_sig_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sig_cmd.c
@@ -54,7 +54,7 @@ ble_l2cap_sig_init_cmd(uint8_t op, uint8_t id, uint8_t payload_len,
     return 0;
 }
 
-static int
+int
 ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom)
 {
     struct ble_l2cap_chan *chan;
@@ -249,3 +249,30 @@ ble_l2cap_sig_update_rsp_tx(uint16_t conn_handle, uint8_t id, uint16_t result)
 
     return ble_l2cap_sig_tx(conn_handle, txom);
 }
+
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+void *
+ble_l2cap_sig_cmd_get(uint8_t opcode, uint8_t id, uint16_t len,
+                      struct os_mbuf **txom)
+{
+    struct ble_l2cap_sig_hdr *hdr;
+
+    *txom = ble_hs_mbuf_l2cap_pkt();
+    if (*txom == NULL) {
+        return NULL;
+    }
+
+    if (os_mbuf_extend(*txom, sizeof(*hdr) + len) == NULL) {
+        os_mbuf_free_chain(*txom);
+        return NULL;
+    }
+
+    hdr = (struct ble_l2cap_sig_hdr *)(*txom)->om_data;
+
+    hdr->op = opcode;
+    hdr->identifier = id;
+    hdr->length = htole16(len);
+
+    return hdr->data;
+}
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/696e79d3/net/nimble/host/src/ble_l2cap_sig_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_priv.h b/net/nimble/host/src/ble_l2cap_sig_priv.h
index 72819de..56f1af0 100644
--- a/net/nimble/host/src/ble_l2cap_sig_priv.h
+++ b/net/nimble/host/src/ble_l2cap_sig_priv.h
@@ -20,6 +20,8 @@
 #ifndef H_BLE_L2CAP_SIG_
 #define H_BLE_L2CAP_SIG_
 
+#include "syscfg/syscfg.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -31,6 +33,7 @@ struct ble_l2cap_sig_hdr {
     uint8_t op;
     uint8_t identifier;
     uint16_t length;
+    uint8_t data[0];
 } __attribute__((packed));
 
 #define BLE_L2CAP_SIG_REJECT_MIN_SZ         2
@@ -54,6 +57,22 @@ struct ble_l2cap_sig_update_rsp {
 #define BLE_L2CAP_SIG_UPDATE_RSP_RESULT_ACCEPT  0x0000
 #define BLE_L2CAP_SIG_UPDATE_RSP_RESULT_REJECT  0x0001
 
+struct ble_l2cap_sig_le_con_req {
+    uint16_t psm;
+    uint16_t scid;
+    uint16_t mtu;
+    uint16_t mps;
+    uint16_t credits;
+} __attribute__((packed));
+
+struct ble_l2cap_sig_le_con_rsp {
+    uint16_t dcid;
+    uint16_t mtu;
+    uint16_t mps;
+    uint16_t credits;
+    uint16_t result;
+} __attribute__((packed));
+
 int ble_l2cap_sig_init_cmd(uint8_t op, uint8_t id, uint8_t payload_len,
                            struct os_mbuf **out_om, void **out_payload_buf);
 void ble_l2cap_sig_hdr_parse(void *payload, uint16_t len,
@@ -75,9 +94,19 @@ void ble_l2cap_sig_update_rsp_write(void *payload, int len,
                                     struct ble_l2cap_sig_update_rsp *src);
 int ble_l2cap_sig_update_rsp_tx(uint16_t conn_handle, uint8_t id,
                                 uint16_t result);
-
 int ble_l2cap_sig_reject_invalid_cid_tx(uint16_t conn_handle, uint8_t id,
                                         uint16_t src_cid, uint16_t dst_cid);
+int ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom);
+#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
+int ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
+                              struct os_mbuf *sdu_rx,
+                              ble_l2cap_event_fn *cb, void *cb_arg);
+void *ble_l2cap_sig_cmd_get(uint8_t opcode, uint8_t id, uint16_t len,
+                            struct os_mbuf **txom);
+#else
+#define ble_l2cap_sig_coc_connect(conn_handle, psm, mtu, sdu_rx, cb, cb_arg) \
+                                                                BLE_HS_ENOTSUP
+#endif
 
 void ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason);
 int32_t ble_l2cap_sig_timer(void);


[08/10] incubator-mynewt-core git commit: nimble/l2cap: Remove prefix blc_ and blh_ from L2CAP structs

Posted by cc...@apache.org.
nimble/l2cap: Remove prefix blc_ and blh_ from L2CAP structs

Remove blc_ and blh_ prefix as it does not really gives us any value.
With this patch we make struct fields names shorter.


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

Branch: refs/heads/develop
Commit: 1c66c7902827ce2830fc1db21dfc0648f1e9ff68
Parents: e9bb23e
Author: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Authored: Fri Jan 20 12:39:00 2017 +0100
Committer: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Committed: Thu Feb 2 12:59:59 2017 +0100

----------------------------------------------------------------------
 net/nimble/host/src/ble_att.c               | 14 +++----
 net/nimble/host/src/ble_att_clt.c           |  4 +-
 net/nimble/host/src/ble_att_svr.c           |  4 +-
 net/nimble/host/src/ble_gattc.c             |  2 +-
 net/nimble/host/src/ble_hs_conn.c           | 20 ++++-----
 net/nimble/host/src/ble_l2cap.c             | 52 ++++++++++++------------
 net/nimble/host/src/ble_l2cap_priv.h        | 22 +++++-----
 net/nimble/host/src/ble_l2cap_sig.c         |  8 ++--
 net/nimble/host/src/ble_sm.c                |  8 ++--
 net/nimble/host/test/src/ble_att_svr_test.c | 10 ++---
 net/nimble/host/test/src/ble_hs_conn_test.c | 18 ++++----
 net/nimble/host/test/src/ble_hs_test_util.c |  6 +--
 net/nimble/host/test/src/ble_l2cap_test.c   | 16 ++++----
 13 files changed, 92 insertions(+), 92 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/src/ble_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att.c b/net/nimble/host/src/ble_att.c
index 0e3f00d..91bce94 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -436,7 +436,7 @@ ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu)
         peer_mtu = BLE_ATT_MTU_DFLT;
     }
 
-    chan->blc_peer_mtu = peer_mtu;
+    chan->peer_mtu = peer_mtu;
 }
 
 static int
@@ -517,8 +517,8 @@ ble_att_set_preferred_mtu(uint16_t mtu)
         chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
         BLE_HS_DBG_ASSERT(chan != NULL);
 
-        if (!(chan->blc_flags & BLE_L2CAP_CHAN_F_TXED_MTU)) {
-            chan->blc_my_mtu = mtu;
+        if (!(chan->flags & BLE_L2CAP_CHAN_F_TXED_MTU)) {
+            chan->my_mtu = mtu;
         }
 
         i++;
@@ -539,10 +539,10 @@ ble_att_create_chan(void)
         return NULL;
     }
 
-    chan->blc_cid = BLE_L2CAP_CID_ATT;
-    chan->blc_my_mtu = ble_att_preferred_mtu_val;
-    chan->blc_default_mtu = BLE_ATT_MTU_DFLT;
-    chan->blc_rx_fn = ble_att_rx;
+    chan->scid = BLE_L2CAP_CID_ATT;
+    chan->my_mtu = ble_att_preferred_mtu_val;
+    chan->default_mtu = BLE_ATT_MTU_DFLT;
+    chan->rx_fn = ble_att_rx;
 
     return chan;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/src/ble_att_clt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_clt.c b/net/nimble/host/src/ble_att_clt.c
index e167576..cdb4fa3 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -132,7 +132,7 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, const struct ble_att_mtu_cmd *req)
     ble_att_conn_chan_find(conn_handle, &conn, &chan);
     if (chan == NULL) {
         rc = BLE_HS_ENOTCONN;
-    } else if (chan->blc_flags & BLE_L2CAP_CHAN_F_TXED_MTU) {
+    } else if (chan->flags & BLE_L2CAP_CHAN_F_TXED_MTU) {
         rc = BLE_HS_EALREADY;
     } else {
         rc = 0;
@@ -159,7 +159,7 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, const struct ble_att_mtu_cmd *req)
     ble_hs_lock();
 
     ble_att_conn_chan_find(conn_handle, &conn, &chan);
-    chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
+    chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
 
     ble_hs_unlock();
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index df1a30d..8932f2f 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -702,7 +702,7 @@ ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct os_mbuf **rxom,
 
     ble_hs_lock();
     ble_att_conn_chan_find(conn_handle, NULL, &chan);
-    mtu = chan->blc_my_mtu;
+    mtu = chan->my_mtu;
     ble_hs_unlock();
 
     /* Just reuse the request buffer for the response. */
@@ -765,7 +765,7 @@ done:
 
         ble_att_conn_chan_find(conn_handle, &conn, &chan);
         ble_att_set_peer_mtu(chan, cmd.bamc_mtu);
-        chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
+        chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
         mtu = ble_l2cap_chan_mtu(chan);
 
         ble_hs_unlock();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/src/ble_gattc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gattc.c b/net/nimble/host/src/ble_gattc.c
index d3a2270..fabb52d 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -1271,7 +1271,7 @@ ble_gattc_mtu_tx(struct ble_gattc_proc *proc)
 
     ble_hs_lock();
     ble_att_conn_chan_find(proc->conn_handle, &conn, &chan);
-    req.bamc_mtu = chan->blc_my_mtu;
+    req.bamc_mtu = chan->my_mtu;
     ble_hs_unlock();
 
     rc = ble_att_clt_tx_mtu(proc->conn_handle, &req);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/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
index d5dc17d..02676fa 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -58,11 +58,11 @@ ble_hs_conn_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) {
+    SLIST_FOREACH(chan, &conn->bhc_channels, next) {
+        if (chan->scid == cid) {
             return chan;
         }
-        if (chan->blc_cid > cid) {
+        if (chan->scid > cid) {
             return NULL;
         }
     }
@@ -81,11 +81,11 @@ ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     struct ble_l2cap_chan *cur;
 
     prev = NULL;
-    SLIST_FOREACH(cur, &conn->bhc_channels, blc_next) {
-        if (cur->blc_cid == chan->blc_cid) {
+    SLIST_FOREACH(cur, &conn->bhc_channels, next) {
+        if (cur->scid == chan->scid) {
             return BLE_HS_EALREADY;
         }
-        if (cur->blc_cid > chan->blc_cid) {
+        if (cur->scid > chan->scid) {
             break;
         }
 
@@ -93,9 +93,9 @@ ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     }
 
     if (prev == NULL) {
-        SLIST_INSERT_HEAD(&conn->bhc_channels, chan, blc_next);
+        SLIST_INSERT_HEAD(&conn->bhc_channels, chan, next);
     } else {
-        SLIST_INSERT_AFTER(prev, chan, blc_next);
+        SLIST_INSERT_AFTER(prev, chan, next);
     }
 
     return 0;
@@ -164,14 +164,14 @@ err:
     return NULL;
 }
 
-static void
+void
 ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
     if (conn->bhc_rx_chan == chan) {
         conn->bhc_rx_chan = NULL;
     }
 
-    SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, blc_next);
+    SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, next);
     ble_l2cap_chan_free(chan);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/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 fc8ecb9..6b857f2 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -89,15 +89,15 @@ ble_l2cap_chan_mtu(const struct ble_l2cap_chan *chan)
     /* If either side has not exchanged MTU size, use the default.  Otherwise,
      * use the lesser of the two exchanged values.
      */
-    if (!(chan->blc_flags & BLE_L2CAP_CHAN_F_TXED_MTU) ||
-        chan->blc_peer_mtu == 0) {
+    if (!(chan->flags & BLE_L2CAP_CHAN_F_TXED_MTU) ||
+        chan->peer_mtu == 0) {
 
-        mtu = chan->blc_default_mtu;
+        mtu = chan->default_mtu;
     } else {
-        mtu = min(chan->blc_my_mtu, chan->blc_peer_mtu);
+        mtu = min(chan->my_mtu, chan->peer_mtu);
     }
 
-    BLE_HS_DBG_ASSERT(mtu >= chan->blc_default_mtu);
+    BLE_HS_DBG_ASSERT(mtu >= chan->default_mtu);
 
     return mtu;
 }
@@ -113,8 +113,8 @@ ble_l2cap_parse_hdr(struct os_mbuf *om, int off,
         return BLE_HS_EMSGSIZE;
     }
 
-    l2cap_hdr->blh_len = get_le16(&l2cap_hdr->blh_len);
-    l2cap_hdr->blh_cid = get_le16(&l2cap_hdr->blh_cid);
+    l2cap_hdr->len = get_le16(&l2cap_hdr->len);
+    l2cap_hdr->cid = get_le16(&l2cap_hdr->cid);
 
     return 0;
 }
@@ -124,8 +124,8 @@ ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len)
 {
     struct ble_l2cap_hdr hdr;
 
-    put_le16(&hdr.blh_len, len);
-    put_le16(&hdr.blh_cid, cid);
+    put_le16(&hdr.len, len);
+    put_le16(&hdr.cid, cid);
 
     om = os_mbuf_prepend_pullup(om, sizeof hdr);
     if (om == NULL) {
@@ -141,14 +141,14 @@ static void
 ble_l2cap_forget_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
     conn->bhc_rx_chan = NULL;
-    chan->blc_rx_buf = NULL;
-    chan->blc_rx_len = 0;
+    chan->rx_buf = NULL;
+    chan->rx_len = 0;
 }
 
 static void
 ble_l2cap_discard_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
-    os_mbuf_free_chain(chan->blc_rx_buf);
+    os_mbuf_free_chain(chan->rx_buf);
     ble_l2cap_forget_rx(conn, chan);
 }
 
@@ -160,22 +160,22 @@ ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     int len_diff;
     int rc;
 
-    if (chan->blc_rx_buf == NULL) {
-        chan->blc_rx_buf = om;
+    if (chan->rx_buf == NULL) {
+        chan->rx_buf = om;
     } else {
-        os_mbuf_concat(chan->blc_rx_buf, om);
+        os_mbuf_concat(chan->rx_buf, om);
     }
 
     /* Determine if packet is fully reassembled. */
-    len_diff = OS_MBUF_PKTLEN(chan->blc_rx_buf) - chan->blc_rx_len;
+    len_diff = OS_MBUF_PKTLEN(chan->rx_buf) - chan->rx_len;
     if (len_diff > 0) {
         /* More data than expected; data corruption. */
         ble_l2cap_discard_rx(conn, chan);
         rc = BLE_HS_EBADDATA;
     } else if (len_diff == 0) {
         /* All fragments received. */
-        *out_rx_cb = chan->blc_rx_fn;
-        *out_rx_buf = chan->blc_rx_buf;
+        *out_rx_cb = chan->rx_fn;
+        *out_rx_buf = chan->rx_buf;
         ble_l2cap_forget_rx(conn, chan);
         rc = 0;
     } else {
@@ -251,7 +251,7 @@ ble_l2cap_rx(struct ble_hs_conn *conn,
         /* Strip L2CAP header from the front of the mbuf. */
         os_mbuf_adj(om, BLE_L2CAP_HDR_SZ);
 
-        chan = ble_hs_conn_chan_find(conn, l2cap_hdr.blh_cid);
+        chan = ble_hs_conn_chan_find(conn, l2cap_hdr.cid);
         if (chan == NULL) {
             rc = BLE_HS_ENOENT;
 
@@ -259,27 +259,27 @@ ble_l2cap_rx(struct ble_hs_conn *conn,
              * channel, quietly drop the packet.  Otherwise, send an invalid
              * CID response.
              */
-            if (l2cap_hdr.blh_cid != BLE_L2CAP_CID_BLACK_HOLE) {
+            if (l2cap_hdr.cid != BLE_L2CAP_CID_BLACK_HOLE) {
                 BLE_HS_LOG(DEBUG, "rx on unknown L2CAP channel: %d\n",
-                           l2cap_hdr.blh_cid);
-                *out_reject_cid = l2cap_hdr.blh_cid;
+                           l2cap_hdr.cid);
+                *out_reject_cid = l2cap_hdr.cid;
             }
             goto err;
         }
 
-        if (chan->blc_rx_buf != NULL) {
+        if (chan->rx_buf != NULL) {
             /* Previous data packet never completed.  Discard old packet. */
             ble_l2cap_discard_rx(conn, chan);
         }
 
         /* Remember channel and length of L2CAP data for reassembly. */
         conn->bhc_rx_chan = chan;
-        chan->blc_rx_len = l2cap_hdr.blh_len;
+        chan->rx_len = l2cap_hdr.len;
         break;
 
     case BLE_HCI_PB_MIDDLE:
         chan = conn->bhc_rx_chan;
-        if (chan == NULL || chan->blc_rx_buf == NULL) {
+        if (chan == NULL || chan->rx_buf == NULL) {
             /* Middle fragment without the start.  Discard new packet. */
             rc = BLE_HS_EBADDATA;
             goto err;
@@ -319,7 +319,7 @@ ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
 {
     int rc;
 
-    txom = ble_l2cap_prepend_hdr(txom, chan->blc_cid, OS_MBUF_PKTLEN(txom));
+    txom = ble_l2cap_prepend_hdr(txom, chan->scid, OS_MBUF_PKTLEN(txom));
     if (txom == NULL) {
         return BLE_HS_ENOMEM;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/src/ble_l2cap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_priv.h b/net/nimble/host/src/ble_l2cap_priv.h
index 79d58a7..ecdcf78 100644
--- a/net/nimble/host/src/ble_l2cap_priv.h
+++ b/net/nimble/host/src/ble_l2cap_priv.h
@@ -64,22 +64,22 @@ typedef uint8_t ble_l2cap_chan_flags;
 typedef int ble_l2cap_rx_fn(uint16_t conn_handle, struct os_mbuf **rxom);
 
 struct ble_l2cap_chan {
-    SLIST_ENTRY(ble_l2cap_chan) blc_next;
-    uint16_t blc_cid;
-    uint16_t blc_my_mtu;
-    uint16_t blc_peer_mtu;      /* 0 if not exchanged. */
-    uint16_t blc_default_mtu;
-    ble_l2cap_chan_flags blc_flags;
+    SLIST_ENTRY(ble_l2cap_chan) next;
+    uint16_t scid;
+    uint16_t my_mtu;
+    uint16_t peer_mtu;      /* 0 if not exchanged. */
+    uint16_t default_mtu;
+    ble_l2cap_chan_flags flags;
 
-    struct os_mbuf *blc_rx_buf;
-    uint16_t blc_rx_len;        /* Length of current reassembled rx packet. */
+    struct os_mbuf *rx_buf;
+    uint16_t rx_len;        /* Length of current reassembled rx packet. */
 
-    ble_l2cap_rx_fn *blc_rx_fn;
+    ble_l2cap_rx_fn *rx_fn;
 };
 
 struct ble_l2cap_hdr {
-    uint16_t blh_len;
-    uint16_t blh_cid;
+    uint16_t len;
+    uint16_t cid;
 };
 
 typedef int ble_l2cap_tx_fn(struct ble_hs_conn *conn,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/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 33cde78..e7c7704 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -523,10 +523,10 @@ ble_l2cap_sig_create_chan(void)
         return NULL;
     }
 
-    chan->blc_cid = BLE_L2CAP_CID_SIG;
-    chan->blc_my_mtu = BLE_L2CAP_SIG_MTU;
-    chan->blc_default_mtu = BLE_L2CAP_SIG_MTU;
-    chan->blc_rx_fn = ble_l2cap_sig_rx;
+    chan->scid = BLE_L2CAP_CID_SIG;
+    chan->my_mtu = BLE_L2CAP_SIG_MTU;
+    chan->default_mtu = BLE_L2CAP_SIG_MTU;
+    chan->rx_fn = ble_l2cap_sig_rx;
 
     return chan;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/src/ble_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm.c b/net/nimble/host/src/ble_sm.c
index a4e189d..0227f1a 100644
--- a/net/nimble/host/src/ble_sm.c
+++ b/net/nimble/host/src/ble_sm.c
@@ -2508,10 +2508,10 @@ ble_sm_create_chan(void)
         return NULL;
     }
 
-    chan->blc_cid = BLE_L2CAP_CID_SM;
-    chan->blc_my_mtu = BLE_SM_MTU;
-    chan->blc_default_mtu = BLE_SM_MTU;
-    chan->blc_rx_fn = ble_sm_rx;
+    chan->scid = BLE_L2CAP_CID_SM;
+    chan->my_mtu = BLE_SM_MTU;
+    chan->default_mtu = BLE_SM_MTU;
+    chan->rx_fn = ble_sm_rx;
 
     return chan;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/test/src/ble_att_svr_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_att_svr_test.c b/net/nimble/host/test/src/ble_att_svr_test.c
index 8ee9bc6..fa60abc 100644
--- a/net/nimble/host/test/src/ble_att_svr_test.c
+++ b/net/nimble/host/test/src/ble_att_svr_test.c
@@ -83,9 +83,9 @@ ble_att_svr_test_misc_init(uint16_t mtu)
     TEST_ASSERT_FATAL(rc == 0);
 
     if (mtu != 0) {
-        chan->blc_my_mtu = mtu;
-        chan->blc_peer_mtu = mtu;
-        chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
+        chan->my_mtu = mtu;
+        chan->peer_mtu = mtu;
+        chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
     }
 
     ble_hs_unlock();
@@ -443,7 +443,7 @@ ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle)
 
     ble_hs_lock();
     ble_att_conn_chan_find(conn_handle, &conn, &chan);
-    my_mtu = chan->blc_my_mtu;
+    my_mtu = chan->my_mtu;
     ble_hs_unlock();
 
     ble_hs_test_util_verify_tx_mtu_cmd(0, my_mtu);
@@ -608,7 +608,7 @@ ble_att_svr_test_misc_mtu_exchange(uint16_t my_mtu, uint16_t peer_sent,
     rc = ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT,
                                     &conn, &chan);
     TEST_ASSERT_FATAL(rc == 0);
-    TEST_ASSERT(chan->blc_peer_mtu == peer_actual);
+    TEST_ASSERT(chan->peer_mtu == peer_actual);
     TEST_ASSERT(ble_l2cap_chan_mtu(chan) == chan_mtu);
     ble_hs_unlock();
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/test/src/ble_hs_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_hs_conn_test.c b/net/nimble/host/test/src/ble_hs_conn_test.c
index 93e2f14..eb6da38 100644
--- a/net/nimble/host/test/src/ble_hs_conn_test.c
+++ b/net/nimble/host/test/src/ble_hs_conn_test.c
@@ -79,9 +79,9 @@ TEST_CASE(ble_hs_conn_test_direct_connect_success)
 
     chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
     TEST_ASSERT_FATAL(chan != NULL);
-    TEST_ASSERT(chan->blc_my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
-    TEST_ASSERT(chan->blc_peer_mtu == 0);
-    TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
+    TEST_ASSERT(chan->my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
+    TEST_ASSERT(chan->peer_mtu == 0);
+    TEST_ASSERT(chan->default_mtu == BLE_ATT_MTU_DFLT);
 
     ble_hs_unlock();
 }
@@ -134,9 +134,9 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_success)
 
     chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
     TEST_ASSERT_FATAL(chan != NULL);
-    TEST_ASSERT(chan->blc_my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
-    TEST_ASSERT(chan->blc_peer_mtu == 0);
-    TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
+    TEST_ASSERT(chan->my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
+    TEST_ASSERT(chan->peer_mtu == 0);
+    TEST_ASSERT(chan->default_mtu == BLE_ATT_MTU_DFLT);
 
     ble_hs_unlock();
 }
@@ -196,9 +196,9 @@ TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
 
     chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
     TEST_ASSERT_FATAL(chan != NULL);
-    TEST_ASSERT(chan->blc_my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
-    TEST_ASSERT(chan->blc_peer_mtu == 0);
-    TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
+    TEST_ASSERT(chan->my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
+    TEST_ASSERT(chan->peer_mtu == 0);
+    TEST_ASSERT(chan->default_mtu == BLE_ATT_MTU_DFLT);
 
     ble_hs_unlock();
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/test/src/ble_hs_test_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_hs_test_util.c b/net/nimble/host/test/src/ble_hs_test_util.c
index 687920e..5b0902c 100644
--- a/net/nimble/host/test/src/ble_hs_test_util.c
+++ b/net/nimble/host/test/src/ble_hs_test_util.c
@@ -125,7 +125,7 @@ ble_hs_test_util_prev_tx_dequeue(void)
 
         ble_hs_test_util_prev_tx_cur = om;
         while (OS_MBUF_PKTLEN(ble_hs_test_util_prev_tx_cur) <
-               l2cap_hdr.blh_len) {
+               l2cap_hdr.len) {
 
             om = ble_hs_test_util_prev_tx_dequeue_once(&hci_hdr);
             TEST_ASSERT_FATAL(om != NULL);
@@ -2039,8 +2039,8 @@ ble_hs_test_util_mbuf_count(const struct ble_hs_test_util_mbuf_params *params)
         }
 
         if (params->rx_queue) {
-            SLIST_FOREACH(chan, &conn->bhc_channels, blc_next) {
-                count += ble_hs_test_util_mbuf_chain_len(chan->blc_rx_buf);
+            SLIST_FOREACH(chan, &conn->bhc_channels, next) {
+                count += ble_hs_test_util_mbuf_chain_len(chan->rx_buf);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1c66c790/net/nimble/host/test/src/ble_l2cap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_l2cap_test.c b/net/nimble/host/test/src/ble_l2cap_test.c
index 526436c..021ebb7 100644
--- a/net/nimble/host/test/src/ble_l2cap_test.c
+++ b/net/nimble/host/test/src/ble_l2cap_test.c
@@ -118,10 +118,10 @@ ble_l2cap_test_util_create_conn(uint16_t conn_handle, uint8_t *addr,
     chan = ble_l2cap_chan_alloc();
     TEST_ASSERT_FATAL(chan != NULL);
 
-    chan->blc_cid = BLE_L2CAP_TEST_CID;
-    chan->blc_my_mtu = 240;
-    chan->blc_default_mtu = 240;
-    chan->blc_rx_fn = ble_l2cap_test_util_dummy_rx;
+    chan->scid = BLE_L2CAP_TEST_CID;
+    chan->my_mtu = 240;
+    chan->default_mtu = 240;
+    chan->rx_fn = ble_l2cap_test_util_dummy_rx;
 
     ble_hs_conn_chan_insert(conn, chan);
 
@@ -194,7 +194,7 @@ ble_l2cap_test_util_verify_first_frag(uint16_t conn_handle,
     conn = ble_hs_conn_find(conn_handle);
     TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_rx_chan != NULL &&
-                conn->bhc_rx_chan->blc_cid == BLE_L2CAP_TEST_CID);
+                conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID);
 
     ble_hs_unlock();
 }
@@ -214,7 +214,7 @@ ble_l2cap_test_util_verify_middle_frag(uint16_t conn_handle,
     conn = ble_hs_conn_find(conn_handle);
     TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_rx_chan != NULL &&
-                conn->bhc_rx_chan->blc_cid == BLE_L2CAP_TEST_CID);
+                conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID);
 
     ble_hs_unlock();
 }
@@ -352,7 +352,7 @@ TEST_CASE(ble_l2cap_test_case_frag_channels)
     conn = ble_hs_conn_find(2);
     TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_rx_chan != NULL &&
-                conn->bhc_rx_chan->blc_cid == BLE_L2CAP_TEST_CID);
+                conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID);
     ble_hs_unlock();
 
     /* Receive a starting fragment on a different channel.  The first fragment
@@ -365,7 +365,7 @@ TEST_CASE(ble_l2cap_test_case_frag_channels)
     conn = ble_hs_conn_find(2);
     TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_rx_chan != NULL &&
-                conn->bhc_rx_chan->blc_cid == BLE_L2CAP_CID_ATT);
+                conn->bhc_rx_chan->scid == BLE_L2CAP_CID_ATT);
     ble_hs_unlock();
 }
 


[03/10] incubator-mynewt-core git commit: nimble/l2cap: Move ble_l2cap_chan_mtu() to ble_att

Posted by cc...@apache.org.
nimble/l2cap: Move ble_l2cap_chan_mtu() to ble_att

MTU Exchange procedure belongs to ATT. Also concept of default MTU
belongs to ATT. This patch removes default_mtu from ble_l2cap_chan and
moves function choosing MTU for ATT channel to ble_att


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

Branch: refs/heads/develop
Commit: 552adce6ed25a46eb40266342c719da478c89a6f
Parents: 1c66c79
Author: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Authored: Fri Jan 20 13:06:13 2017 +0100
Committer: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Committed: Thu Feb 2 12:59:59 2017 +0100

----------------------------------------------------------------------
 net/nimble/host/src/ble_att.c               | 26 +++++++++++++++++++++---
 net/nimble/host/src/ble_att_clt.c           |  2 +-
 net/nimble/host/src/ble_att_priv.h          |  1 +
 net/nimble/host/src/ble_att_svr.c           |  2 +-
 net/nimble/host/src/ble_l2cap.c             | 21 +++----------------
 net/nimble/host/src/ble_l2cap_priv.h        |  4 +---
 net/nimble/host/src/ble_l2cap_sig.c         |  1 -
 net/nimble/host/src/ble_sm.c                |  1 -
 net/nimble/host/test/src/ble_att_svr_test.c |  4 ++--
 net/nimble/host/test/src/ble_hs_conn_test.c |  3 ---
 net/nimble/host/test/src/ble_l2cap_test.c   |  1 -
 11 files changed, 32 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/net/nimble/host/src/ble_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att.c b/net/nimble/host/src/ble_att.c
index 91bce94..ff1eebf 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -392,7 +392,7 @@ ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan,
     int32_t extra_len;
     uint16_t mtu;
 
-    mtu = ble_l2cap_chan_mtu(att_chan);
+    mtu = ble_att_chan_mtu(att_chan);
     extra_len = OS_MBUF_PKTLEN(txom) - mtu;
     if (extra_len > 0) {
         os_mbuf_adj(txom, -extra_len);
@@ -419,7 +419,7 @@ ble_att_mtu(uint16_t conn_handle)
 
     ble_att_conn_chan_find(conn_handle, &conn, &chan);
     if (chan != NULL) {
-        mtu = ble_l2cap_chan_mtu(chan);
+        mtu = ble_att_chan_mtu(chan);
     } else {
         mtu = 0;
     }
@@ -439,6 +439,27 @@ ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu)
     chan->peer_mtu = peer_mtu;
 }
 
+uint16_t
+ble_att_chan_mtu(const struct ble_l2cap_chan *chan)
+{
+    uint16_t mtu;
+
+    /* If either side has not exchanged MTU size, use the default.  Otherwise,
+     * use the lesser of the two exchanged values.
+     */
+    if (!(ble_l2cap_is_mtu_req_sent(chan)) ||
+        chan->peer_mtu == 0) {
+
+        mtu = BLE_ATT_MTU_DFLT;
+    } else {
+        mtu = min(chan->my_mtu, chan->peer_mtu);
+    }
+
+    BLE_HS_DBG_ASSERT(mtu >= BLE_ATT_MTU_DFLT);
+
+    return mtu;
+}
+
 static int
 ble_att_rx(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -541,7 +562,6 @@ ble_att_create_chan(void)
 
     chan->scid = BLE_L2CAP_CID_ATT;
     chan->my_mtu = ble_att_preferred_mtu_val;
-    chan->default_mtu = BLE_ATT_MTU_DFLT;
     chan->rx_fn = ble_att_rx;
 
     return chan;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/net/nimble/host/src/ble_att_clt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_clt.c b/net/nimble/host/src/ble_att_clt.c
index cdb4fa3..4a93171 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -185,7 +185,7 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom)
 
         ble_att_conn_chan_find(conn_handle, NULL, &chan);
         ble_att_set_peer_mtu(chan, cmd.bamc_mtu);
-        mtu = ble_l2cap_chan_mtu(chan);
+        mtu = ble_att_chan_mtu(chan);
 
         ble_hs_unlock();
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/net/nimble/host/src/ble_att_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_priv.h b/net/nimble/host/src/ble_att_priv.h
index ed696df..22ed62e 100644
--- a/net/nimble/host/src/ble_att_priv.h
+++ b/net/nimble/host/src/ble_att_priv.h
@@ -166,6 +166,7 @@ void ble_att_inc_tx_stat(uint8_t att_op);
 void ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan,
                              struct os_mbuf *txom);
 void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu);
+uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan);
 int ble_att_init(void);
 
 #define BLE_ATT_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index 8932f2f..1c2d4a2 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -766,7 +766,7 @@ done:
         ble_att_conn_chan_find(conn_handle, &conn, &chan);
         ble_att_set_peer_mtu(chan, cmd.bamc_mtu);
         chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
-        mtu = ble_l2cap_chan_mtu(chan);
+        mtu = ble_att_chan_mtu(chan);
 
         ble_hs_unlock();
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/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 6b857f2..a61ada7 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -81,25 +81,10 @@ ble_l2cap_chan_free(struct ble_l2cap_chan *chan)
     STATS_INC(ble_l2cap_stats, chan_delete);
 }
 
-uint16_t
-ble_l2cap_chan_mtu(const struct ble_l2cap_chan *chan)
+bool
+ble_l2cap_is_mtu_req_sent(const struct ble_l2cap_chan *chan)
 {
-    uint16_t mtu;
-
-    /* If either side has not exchanged MTU size, use the default.  Otherwise,
-     * use the lesser of the two exchanged values.
-     */
-    if (!(chan->flags & BLE_L2CAP_CHAN_F_TXED_MTU) ||
-        chan->peer_mtu == 0) {
-
-        mtu = chan->default_mtu;
-    } else {
-        mtu = min(chan->my_mtu, chan->peer_mtu);
-    }
-
-    BLE_HS_DBG_ASSERT(mtu >= chan->default_mtu);
-
-    return mtu;
+    return (chan->flags & BLE_L2CAP_CHAN_F_TXED_MTU);
 }
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/net/nimble/host/src/ble_l2cap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_priv.h b/net/nimble/host/src/ble_l2cap_priv.h
index ecdcf78..7733c20 100644
--- a/net/nimble/host/src/ble_l2cap_priv.h
+++ b/net/nimble/host/src/ble_l2cap_priv.h
@@ -68,7 +68,6 @@ struct ble_l2cap_chan {
     uint16_t scid;
     uint16_t my_mtu;
     uint16_t peer_mtu;      /* 0 if not exchanged. */
-    uint16_t default_mtu;
     ble_l2cap_chan_flags flags;
 
     struct os_mbuf *rx_buf;
@@ -97,8 +96,7 @@ struct os_mbuf *ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid,
 struct ble_l2cap_chan *ble_l2cap_chan_alloc(void);
 void ble_l2cap_chan_free(struct ble_l2cap_chan *chan);
 
-uint16_t ble_l2cap_chan_mtu(const struct ble_l2cap_chan *chan);
-
+bool ble_l2cap_is_mtu_req_sent(const struct ble_l2cap_chan *chan);
 
 int ble_l2cap_rx(struct ble_hs_conn *conn,
                  struct hci_data_hdr *hci_hdr,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/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 e7c7704..09df2c3 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -525,7 +525,6 @@ ble_l2cap_sig_create_chan(void)
 
     chan->scid = BLE_L2CAP_CID_SIG;
     chan->my_mtu = BLE_L2CAP_SIG_MTU;
-    chan->default_mtu = BLE_L2CAP_SIG_MTU;
     chan->rx_fn = ble_l2cap_sig_rx;
 
     return chan;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/net/nimble/host/src/ble_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm.c b/net/nimble/host/src/ble_sm.c
index 0227f1a..6f88830 100644
--- a/net/nimble/host/src/ble_sm.c
+++ b/net/nimble/host/src/ble_sm.c
@@ -2510,7 +2510,6 @@ ble_sm_create_chan(void)
 
     chan->scid = BLE_L2CAP_CID_SM;
     chan->my_mtu = BLE_SM_MTU;
-    chan->default_mtu = BLE_SM_MTU;
     chan->rx_fn = ble_sm_rx;
 
     return chan;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/net/nimble/host/test/src/ble_att_svr_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_att_svr_test.c b/net/nimble/host/test/src/ble_att_svr_test.c
index fa60abc..c2bc64a 100644
--- a/net/nimble/host/test/src/ble_att_svr_test.c
+++ b/net/nimble/host/test/src/ble_att_svr_test.c
@@ -398,7 +398,7 @@ ble_att_svr_test_misc_verify_tx_read_mult_rsp(
     rc = ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT,
                                     NULL, &chan);
     TEST_ASSERT_FATAL(rc == 0);
-    mtu = ble_l2cap_chan_mtu(chan);
+    mtu = ble_att_chan_mtu(chan);
 
     ble_hs_unlock();
 
@@ -609,7 +609,7 @@ ble_att_svr_test_misc_mtu_exchange(uint16_t my_mtu, uint16_t peer_sent,
                                     &conn, &chan);
     TEST_ASSERT_FATAL(rc == 0);
     TEST_ASSERT(chan->peer_mtu == peer_actual);
-    TEST_ASSERT(ble_l2cap_chan_mtu(chan) == chan_mtu);
+    TEST_ASSERT(ble_att_chan_mtu(chan) == chan_mtu);
     ble_hs_unlock();
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/net/nimble/host/test/src/ble_hs_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_hs_conn_test.c b/net/nimble/host/test/src/ble_hs_conn_test.c
index eb6da38..8ae4971 100644
--- a/net/nimble/host/test/src/ble_hs_conn_test.c
+++ b/net/nimble/host/test/src/ble_hs_conn_test.c
@@ -81,7 +81,6 @@ TEST_CASE(ble_hs_conn_test_direct_connect_success)
     TEST_ASSERT_FATAL(chan != NULL);
     TEST_ASSERT(chan->my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
     TEST_ASSERT(chan->peer_mtu == 0);
-    TEST_ASSERT(chan->default_mtu == BLE_ATT_MTU_DFLT);
 
     ble_hs_unlock();
 }
@@ -136,7 +135,6 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_success)
     TEST_ASSERT_FATAL(chan != NULL);
     TEST_ASSERT(chan->my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
     TEST_ASSERT(chan->peer_mtu == 0);
-    TEST_ASSERT(chan->default_mtu == BLE_ATT_MTU_DFLT);
 
     ble_hs_unlock();
 }
@@ -198,7 +196,6 @@ TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
     TEST_ASSERT_FATAL(chan != NULL);
     TEST_ASSERT(chan->my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
     TEST_ASSERT(chan->peer_mtu == 0);
-    TEST_ASSERT(chan->default_mtu == BLE_ATT_MTU_DFLT);
 
     ble_hs_unlock();
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/552adce6/net/nimble/host/test/src/ble_l2cap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_l2cap_test.c b/net/nimble/host/test/src/ble_l2cap_test.c
index 021ebb7..e8dbfa8 100644
--- a/net/nimble/host/test/src/ble_l2cap_test.c
+++ b/net/nimble/host/test/src/ble_l2cap_test.c
@@ -120,7 +120,6 @@ ble_l2cap_test_util_create_conn(uint16_t conn_handle, uint8_t *addr,
 
     chan->scid = BLE_L2CAP_TEST_CID;
     chan->my_mtu = 240;
-    chan->default_mtu = 240;
     chan->rx_fn = ble_l2cap_test_util_dummy_rx;
 
     ble_hs_conn_chan_insert(conn, chan);


[04/10] incubator-mynewt-core git commit: kernel/queue: Fix SLIST_REMOVE macro

Posted by cc...@apache.org.
kernel/queue: Fix SLIST_REMOVE macro

This patch adds a missing NULL check of list element.
Without that patch, if somebody wants to remove element which is
not on the list, crash occurs


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

Branch: refs/heads/develop
Commit: 82c6878e75b257f4a1735c2ab68de72e2dc983c8
Parents: e9ff7ac
Author: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Authored: Sun Jan 29 23:44:17 2017 +0100
Committer: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Committed: Thu Feb 2 12:59:59 2017 +0100

----------------------------------------------------------------------
 kernel/os/include/os/queue.h | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/82c6878e/kernel/os/include/os/queue.h
----------------------------------------------------------------------
diff --git a/kernel/os/include/os/queue.h b/kernel/os/include/os/queue.h
index faffd85..a3a0790 100755
--- a/kernel/os/include/os/queue.h
+++ b/kernel/os/include/os/queue.h
@@ -158,10 +158,11 @@ struct {                                                \
     }                                                       \
     else {                                                  \
         struct type *curelm = SLIST_FIRST((head));          \
-        while (SLIST_NEXT(curelm, field) != (elm))          \
-            curelm = SLIST_NEXT(curelm, field);             \
-        SLIST_NEXT(curelm, field) =                         \
-            SLIST_NEXT(SLIST_NEXT(curelm, field), field);   \
+        while (SLIST_NEXT(curelm, field) &&                 \
+               SLIST_NEXT(curelm, field) != (elm)) {        \
+              curelm = SLIST_NEXT(curelm, field);           \
+        }                                                   \
+        SLIST_NEXT(curelm, field) = SLIST_NEXT(elm, field); \
     }                                                       \
 } while (0)
 


[09/10] incubator-mynewt-core git commit: This closes #171.

Posted by cc...@apache.org.
This closes #171.

Merge remote-tracking branch 'rymanluk/l2cap_coc_sig' into develop

* rymanluk/l2cap_coc_sig:
  bletiny: Add support to connect/disconnect L2CAP LE COC
  nimble/l2cap: Add support to disconnect L2CAP LE COC
  nimble/l2cap: Add support to connect L2CAP LE COC
  nimble/l2cap: Add LE L2CAP COC API
  nimble/l2cap: Move ble_l2cap_chan_mtu() to ble_att
  nimble/l2cap: Remove prefix blc_ and blh_ from L2CAP structs
  nimble/l2cap: Remove not needed checks
  kernel/queue: Fix SLIST_REMOVE macro


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

Branch: refs/heads/develop
Commit: 0727c55dcfb6a7718b38bcfec4068f652ca314fa
Parents: 85638d2 8b73a4d
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Feb 13 11:23:27 2017 -0800
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon Feb 13 11:23:27 2017 -0800

----------------------------------------------------------------------
 apps/bletiny/src/bletiny.h                  |  12 +-
 apps/bletiny/src/cmd.c                      | 145 ++++++
 apps/bletiny/src/main.c                     | 222 +++++++++
 kernel/os/include/os/queue.h                |   9 +-
 net/nimble/host/include/host/ble_hs.h       |   4 +
 net/nimble/host/include/host/ble_l2cap.h    | 114 +++++
 net/nimble/host/src/ble_att.c               |  38 +-
 net/nimble/host/src/ble_att_clt.c           |   6 +-
 net/nimble/host/src/ble_att_priv.h          |   1 +
 net/nimble/host/src/ble_att_svr.c           |   6 +-
 net/nimble/host/src/ble_gattc.c             |   2 +-
 net/nimble/host/src/ble_hs_conn.c           |  20 +-
 net/nimble/host/src/ble_hs_conn_priv.h      |   3 +
 net/nimble/host/src/ble_hs_priv.h           |   1 +
 net/nimble/host/src/ble_l2cap.c             | 110 +++--
 net/nimble/host/src/ble_l2cap_coc.c         | 131 ++++++
 net/nimble/host/src/ble_l2cap_coc_priv.h    |  68 +++
 net/nimble/host/src/ble_l2cap_priv.h        |  39 +-
 net/nimble/host/src/ble_l2cap_sig.c         | 563 ++++++++++++++++++++++-
 net/nimble/host/src/ble_l2cap_sig_cmd.c     |  51 +-
 net/nimble/host/src/ble_l2cap_sig_priv.h    |  44 +-
 net/nimble/host/src/ble_sm.c                |   7 +-
 net/nimble/host/syscfg.yml                  |   5 +
 net/nimble/host/test/src/ble_att_svr_test.c |  14 +-
 net/nimble/host/test/src/ble_hs_conn_test.c |  15 +-
 net/nimble/host/test/src/ble_hs_test_util.c |   6 +-
 net/nimble/host/test/src/ble_l2cap_test.c   |  15 +-
 27 files changed, 1502 insertions(+), 149 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0727c55d/net/nimble/host/src/ble_l2cap.c
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0727c55d/net/nimble/host/test/src/ble_att_svr_test.c
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0727c55d/net/nimble/host/test/src/ble_l2cap_test.c
----------------------------------------------------------------------
diff --cc net/nimble/host/test/src/ble_l2cap_test.c
index 2681b26,e8dbfa8..dc1c373
--- a/net/nimble/host/test/src/ble_l2cap_test.c
+++ b/net/nimble/host/test/src/ble_l2cap_test.c
@@@ -365,13 -364,8 +364,13 @@@ TEST_CASE(ble_l2cap_test_case_frag_chan
      conn = ble_hs_conn_find(2);
      TEST_ASSERT_FATAL(conn != NULL);
      TEST_ASSERT(conn->bhc_rx_chan != NULL &&
-                 conn->bhc_rx_chan->blc_cid == BLE_L2CAP_CID_ATT);
+                 conn->bhc_rx_chan->scid == BLE_L2CAP_CID_ATT);
      ble_hs_unlock();
 +
 +    /* Terminate the connection.  The received fragments should get freed.
 +     * Mbuf leaks are tested in the post-test-case callback.
 +     */
 +    ble_hs_test_util_conn_disconnect(2);
  }
  
  TEST_CASE(ble_l2cap_test_case_frag_timeout)


[06/10] incubator-mynewt-core git commit: nimble/l2cap: Add support to disconnect L2CAP LE COC

Posted by cc...@apache.org.
nimble/l2cap: Add support to disconnect L2CAP LE COC

With this patch nibmle is able to initiate LE COC disconnect
and handle incoming disconnection request


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

Branch: refs/heads/develop
Commit: 2082dc6919f461e05cdf23b5e27e95adc01792ca
Parents: 696e79d
Author: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Authored: Tue Jan 31 01:13:09 2017 +0100
Committer: \u0141ukasz Rymanowski <lu...@codecoup.pl>
Committed: Thu Feb 2 12:59:59 2017 +0100

----------------------------------------------------------------------
 net/nimble/host/src/ble_hs_conn_priv.h   |   3 +
 net/nimble/host/src/ble_l2cap.c          |   3 +-
 net/nimble/host/src/ble_l2cap_sig.c      | 192 +++++++++++++++++++++++++-
 net/nimble/host/src/ble_l2cap_sig_priv.h |  13 ++
 4 files changed, 207 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2082dc69/net/nimble/host/src/ble_hs_conn_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn_priv.h b/net/nimble/host/src/ble_hs_conn_priv.h
index 904aa3c..b58a0df 100644
--- a/net/nimble/host/src/ble_hs_conn_priv.h
+++ b/net/nimble/host/src/ble_hs_conn_priv.h
@@ -88,6 +88,9 @@ struct ble_l2cap_chan *ble_hs_conn_chan_find(struct ble_hs_conn *conn,
                                              uint16_t cid);
 int ble_hs_conn_chan_insert(struct ble_hs_conn *conn,
                             struct ble_l2cap_chan *chan);
+void
+ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan);
+
 void ble_hs_conn_addrs(const struct ble_hs_conn *conn,
                        struct ble_hs_conn_addrs *addrs);
 int32_t ble_hs_conn_timer(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2082dc69/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 d881acb..8367509 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -140,8 +140,7 @@ ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
 
 int ble_l2cap_disconnect(struct ble_l2cap_chan *chan)
 {
-    /*TODO Implement */
-    return BLE_HS_ENOTSUP;
+    return ble_l2cap_sig_disconnect(chan);
 }
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2082dc69/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 fe9362f..fdaa408 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -56,7 +56,8 @@
 
 #define BLE_L2CAP_SIG_PROC_OP_UPDATE            0
 #define BLE_L2CAP_SIG_PROC_OP_CONNECT           1
-#define BLE_L2CAP_SIG_PROC_OP_MAX               2
+#define BLE_L2CAP_SIG_PROC_OP_DISCONNECT        2
+#define BLE_L2CAP_SIG_PROC_OP_MAX               3
 
 struct ble_l2cap_sig_proc {
     STAILQ_ENTRY(ble_l2cap_sig_proc) next;
@@ -74,6 +75,9 @@ struct ble_l2cap_sig_proc {
         struct {
             struct ble_l2cap_chan *chan;
         } connect;
+        struct {
+            struct ble_l2cap_chan *chan;
+        } disconnect;
     };
 };
 
@@ -92,16 +96,21 @@ static ble_l2cap_sig_rx_fn ble_l2cap_sig_update_rsp_rx;
 #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
 static ble_l2cap_sig_rx_fn ble_l2cap_sig_coc_req_rx;
 static ble_l2cap_sig_rx_fn ble_l2cap_sig_coc_rsp_rx;
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_disc_rsp_rx;
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_disc_req_rx;
 #else
 #define ble_l2cap_sig_coc_req_rx    ble_l2cap_sig_rx_noop
 #define ble_l2cap_sig_coc_rsp_rx    ble_l2cap_sig_rx_noop
+#define ble_l2cap_sig_disc_rsp_rx   ble_l2cap_sig_rx_noop
+#define ble_l2cap_sig_disc_req_rx   ble_l2cap_sig_rx_noop
 #endif
 
 static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = {
     [BLE_L2CAP_SIG_OP_REJECT]               = ble_l2cap_sig_rx_noop,
     [BLE_L2CAP_SIG_OP_CONNECT_RSP]          = ble_l2cap_sig_rx_noop,
     [BLE_L2CAP_SIG_OP_CONFIG_RSP]           = ble_l2cap_sig_rx_noop,
-    [BLE_L2CAP_SIG_OP_DISCONN_RSP]          = ble_l2cap_sig_rx_noop,
+    [BLE_L2CAP_SIG_OP_DISCONN_REQ]          = ble_l2cap_sig_disc_req_rx,
+    [BLE_L2CAP_SIG_OP_DISCONN_RSP]          = ble_l2cap_sig_disc_rsp_rx,
     [BLE_L2CAP_SIG_OP_ECHO_RSP]             = ble_l2cap_sig_rx_noop,
     [BLE_L2CAP_SIG_OP_INFO_RSP]             = ble_l2cap_sig_rx_noop,
     [BLE_L2CAP_SIG_OP_CREATE_CHAN_RSP]      = ble_l2cap_sig_rx_noop,
@@ -553,6 +562,18 @@ ble_l2cap_event_coc_connected(struct ble_l2cap_chan *chan, uint16_t status)
     chan->cb(&event, chan->cb_arg);
 }
 
+static void
+ble_l2cap_event_coc_disconnected(struct ble_l2cap_chan *chan)
+{
+    struct ble_l2cap_event event = { };
+
+    event.type = BLE_L2CAP_EVENT_COC_DISCONNECTED;
+    event.disconnect.conn_handle = chan->conn_handle;
+    event.disconnect.chan = chan;
+
+    chan->cb(&event, chan->cb_arg);
+}
+
 static int
 ble_l2cap_event_coc_accept(struct ble_l2cap_chan *chan, uint16_t peer_sdu_size)
 {
@@ -819,7 +840,171 @@ ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
 
     return rc;
 }
+
+/*****************************************************************************
+ * $disconnect                                                               *
+ *****************************************************************************/
+
+static int
+ble_l2cap_sig_disc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr,
+                          struct os_mbuf **om)
+{
+    struct ble_l2cap_sig_disc_req *req;
+    struct os_mbuf *txom;
+    struct ble_l2cap_sig_disc_rsp *rsp;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    rc = ble_hs_mbuf_pullup_base(om, sizeof(*req));
+    if (rc != 0) {
+        return rc;
+    }
+
+    rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_DISCONN_RSP, hdr->identifier,
+                                sizeof(*rsp), &txom);
+    if (!rsp) {
+        /* Well, nothing smart we can do if there is no memory for response.
+         * Remote will timeout.
+         */
+        return 0;
+    }
+
+    ble_hs_lock();
+    conn = ble_hs_conn_find_assert(conn_handle);
+
+    req = (struct ble_l2cap_sig_disc_req *) (*om)->om_data;
+
+    chan = ble_hs_conn_chan_find(conn, le16toh(req->dcid));
+    if (!chan || (le16toh(req->scid) != chan->scid)) {
+        os_mbuf_free_chain(txom);
+        ble_hs_unlock();
+        return 0;
+    }
+
+    rsp->dcid = htole16(chan->dcid);
+    rsp->scid = htole16(chan->scid);
+
+    ble_l2cap_event_coc_disconnected(chan);
+
+    ble_hs_conn_delete_chan(conn, chan);
+    ble_hs_unlock();
+
+    return ble_l2cap_sig_tx(conn_handle, txom);
+}
+
+static void
+ble_l2cap_sig_coc_disconnect_cb(struct ble_l2cap_sig_proc *proc, int status)
+{
+    struct ble_l2cap_chan *chan;
+    struct ble_l2cap_event event;
+    struct ble_hs_conn *conn;
+
+    if (!proc) {
+        return;
+    }
+
+    memset(&event, 0, sizeof(event));
+    chan = proc->disconnect.chan;
+
+    if (!chan) {
+        return;
+    }
+
+    if (!chan->cb) {
+        goto done;
+    }
+
+    ble_l2cap_event_coc_disconnected(chan);
+
+done:
+    ble_hs_lock();
+    conn = ble_hs_conn_find(chan->conn_handle);
+    if (conn) {
+        ble_hs_conn_delete_chan(conn, chan);
+    } else {
+        ble_l2cap_chan_free(chan);
+    }
+    ble_hs_unlock();
+}
+
+static int
+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;
+    struct ble_l2cap_sig_proc *proc;
+    struct ble_l2cap_chan *chan;
+    int rc;
+
+    proc = ble_l2cap_sig_proc_extract(conn_handle,
+                                      BLE_L2CAP_SIG_PROC_OP_DISCONNECT,
+                                      hdr->identifier);
+    if (!proc) {
+        return 0;
+    }
+
+    rc = ble_hs_mbuf_pullup_base(om, sizeof(*rsp));
+    if (rc != 0) {
+        goto done;
+    }
+
+    chan = proc->disconnect.chan;
+    if (!chan) {
+        goto done;
+    }
+
+    rsp = (struct ble_l2cap_sig_disc_rsp *)(*om)->om_data;
+    if (chan->dcid != le16toh(rsp->dcid) || chan->scid != le16toh(rsp->scid)) {
+        /* This response is incorrect, lets wait for timeout */
+        ble_l2cap_sig_process_status(proc, 0);
+        return 0;
+    }
+
+    ble_l2cap_sig_coc_disconnect_cb(proc, rc);
+
+done:
+    ble_l2cap_sig_proc_free(proc);
+    return 0;
+}
+
+int
+ble_l2cap_sig_disconnect(struct ble_l2cap_chan *chan)
+{
+    struct os_mbuf *txom;
+    struct ble_l2cap_sig_disc_req *req;
+    struct ble_l2cap_sig_proc *proc;
+    int rc;
+
+    proc = ble_l2cap_sig_proc_alloc();
+    if (proc == NULL) {
+        return BLE_HS_ENOMEM;
+    }
+
+    proc->op = BLE_L2CAP_SIG_PROC_OP_DISCONNECT;
+    proc->id = ble_l2cap_sig_next_id();
+    proc->conn_handle = chan->conn_handle;
+    proc->disconnect.chan = chan;
+
+    req = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_DISCONN_REQ, proc->id,
+                                sizeof(*req), &txom);
+    if (!req) {
+        return BLE_HS_ENOMEM;
+    }
+
+    req->dcid = htole16(chan->dcid);
+    req->scid = htole16(chan->scid);
+
+    rc = ble_l2cap_sig_tx(proc->conn_handle, txom);
+
+    ble_l2cap_sig_process_status(proc, rc);
+
+    return rc;
+}
 #endif
+/*****************************************************************************
+ * $misc                                                                     *
+ *****************************************************************************/
 
 static int
 ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
@@ -978,6 +1163,9 @@ ble_l2cap_sig_timer(void)
             case BLE_L2CAP_SIG_PROC_OP_CONNECT:
                 ble_l2cap_sig_coc_connect_cb(proc, BLE_HS_ETIMEOUT);
             break;
+            case BLE_L2CAP_SIG_PROC_OP_DISCONNECT:
+                ble_l2cap_sig_coc_disconnect_cb(proc, BLE_HS_ETIMEOUT);
+            break;
 #endif
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2082dc69/net/nimble/host/src/ble_l2cap_sig_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_priv.h b/net/nimble/host/src/ble_l2cap_sig_priv.h
index 56f1af0..48bff7e 100644
--- a/net/nimble/host/src/ble_l2cap_sig_priv.h
+++ b/net/nimble/host/src/ble_l2cap_sig_priv.h
@@ -73,6 +73,16 @@ struct ble_l2cap_sig_le_con_rsp {
     uint16_t result;
 } __attribute__((packed));
 
+struct ble_l2cap_sig_disc_req {
+    uint16_t dcid;
+    uint16_t scid;
+} __attribute__((packed));
+
+struct ble_l2cap_sig_disc_rsp {
+    uint16_t dcid;
+    uint16_t scid;
+} __attribute__((packed));
+
 int ble_l2cap_sig_init_cmd(uint8_t op, uint8_t id, uint8_t payload_len,
                            struct os_mbuf **out_om, void **out_payload_buf);
 void ble_l2cap_sig_hdr_parse(void *payload, uint16_t len,
@@ -103,9 +113,12 @@ int ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu,
                               ble_l2cap_event_fn *cb, void *cb_arg);
 void *ble_l2cap_sig_cmd_get(uint8_t opcode, uint8_t id, uint16_t len,
                             struct os_mbuf **txom);
+
+int ble_l2cap_sig_disconnect(struct ble_l2cap_chan *chan);
 #else
 #define ble_l2cap_sig_coc_connect(conn_handle, psm, mtu, sdu_rx, cb, cb_arg) \
                                                                 BLE_HS_ENOTSUP
+#define ble_l2cap_sig_disconnect(chan)                          BLE_HS_ENOTSUP
 #endif
 
 void ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason);