This is an automated email from the ASF dual-hosted git repository. rymek pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit b7849bbbab81b3434fbd02dc01ae8dbde6c997b6 Author: Ćukasz Rymanowski <[email protected]> AuthorDate: Mon Jan 13 15:50:29 2020 +0100 btshell: Extend l2cap cli to support enhanced LE CoC --- apps/btshell/src/btshell.h | 4 +- apps/btshell/src/cmd.c | 25 +++++++++++ apps/btshell/src/cmd.h | 2 + apps/btshell/src/cmd_l2cap.c | 50 +++++++++++++++++++++- apps/btshell/src/cmd_l2cap.h | 1 + apps/btshell/src/main.c | 99 +++++++++++++++++++++++++++++++++++++++----- apps/btshell/src/parse.c | 14 +++++++ 7 files changed, 182 insertions(+), 13 deletions(-) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index 838ee83..650888d 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -171,9 +171,11 @@ int btshell_tx_start(uint16_t conn_handle, uint16_t len, uint16_t rate, void btshell_tx_stop(void); int btshell_rssi(uint16_t conn_handle, int8_t *out_rssi); int btshell_l2cap_create_srv(uint16_t psm, int accept_response); -int btshell_l2cap_connect(uint16_t conn, uint16_t psm); +int btshell_l2cap_connect(uint16_t conn, uint16_t psm, uint8_t num); int btshell_l2cap_disconnect(uint16_t conn, uint16_t idx); int btshell_l2cap_send(uint16_t conn, uint16_t idx, uint16_t bytes); +int btshell_l2cap_reconfig(uint16_t conn_handle, uint16_t mtu, + uint8_t num, uint8_t idxs[]); int btshell_gap_event(struct ble_gap_event *event, void *arg); void btshell_sync_stats(uint16_t handle); diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 3bf60af..b91bd82 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -3515,6 +3515,7 @@ static const struct shell_cmd_help l2cap_create_server_help = { static const struct shell_param l2cap_connect_params[] = { {"conn", "connection handle, usage: =<UINT16>"}, {"psm", "usage: =<UINT16>"}, + {"num", "usage: number of connection created in a row: [1-5]"}, {NULL, NULL} }; @@ -3541,6 +3542,23 @@ static const struct shell_cmd_help l2cap_disconnect_help = { }; /***************************************************************************** + * $l2cap-reconfig * + *****************************************************************************/ + +static const struct shell_param l2cap_reconfig_params[] = { + {"conn", "connection handle, usage: =<UINT16>"}, + {"mtu", "new mtu, usage: =<UINT16>, default: 0 (no change)"}, + {"idxs", "list of channel indexes, usage: idxs=1,3"}, + {NULL, NULL} +}; + +static const struct shell_cmd_help l2cap_reconfig_help = { + .summary = "perform l2cap reconfigure procedure", + .usage = "use gatt-show-coc to get the parameters", + .params = l2cap_reconfig_params, +}; + +/***************************************************************************** * $l2cap-send * *****************************************************************************/ @@ -4390,6 +4408,13 @@ static const struct shell_cmd btshell_commands[] = { #endif }, { + .sc_cmd = "l2cap-reconfig", + .sc_cmd_func = cmd_l2cap_reconfig, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &l2cap_reconfig_help, +#endif + }, + { .sc_cmd = "l2cap-disconnect", .sc_cmd_func = cmd_l2cap_disconnect, #if MYNEWT_VAL(SHELL_CMD_HELP) diff --git a/apps/btshell/src/cmd.h b/apps/btshell/src/cmd.h index 96b9e9b..63bd50d 100644 --- a/apps/btshell/src/cmd.h +++ b/apps/btshell/src/cmd.h @@ -51,6 +51,8 @@ int parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status); int parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val, int *out_status); int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len); +int parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, + uint8_t *dst, int *out_len); int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len); int parse_arg_mac(char *name, uint8_t *dst); int parse_arg_addr(char *name, ble_addr_t *addr); diff --git a/apps/btshell/src/cmd_l2cap.c b/apps/btshell/src/cmd_l2cap.c index 6558455..8f26dc9 100644 --- a/apps/btshell/src/cmd_l2cap.c +++ b/apps/btshell/src/cmd_l2cap.c @@ -20,6 +20,7 @@ #include <inttypes.h> #include <errno.h> +#include "syscfg/syscfg.h" #include "host/ble_gap.h" #include "host/ble_l2cap.h" #include "console/console.h" @@ -147,6 +148,7 @@ cmd_l2cap_connect(int argc, char **argv) { uint16_t conn = 0; uint16_t psm = 0; + uint8_t num; int rc; rc = parse_arg_all(argc - 1, argv + 1); @@ -166,7 +168,13 @@ cmd_l2cap_connect(int argc, char **argv) return rc; } - return btshell_l2cap_connect(conn, psm); + num = parse_arg_uint8_dflt("num", 1, &rc); + if (rc != 0) { + console_printf("invalid 'num' parameter\n"); + return rc; + } + + return btshell_l2cap_connect(conn, psm, num); } /***************************************************************************** @@ -261,3 +269,43 @@ cmd_l2cap_show_coc(int argc, char **argv) return 0; } + +int +cmd_l2cap_reconfig(int argc, char **argv) +{ +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) + uint16_t conn; + uint16_t mtu; + uint8_t idxs[5]; + int num; + int rc; + + rc = parse_arg_all(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + conn = parse_arg_uint16("conn", &rc); + if (rc != 0) { + console_printf("invalid 'conn' parameter\n"); + return rc; + } + + mtu = parse_arg_uint16_dflt("mtu", 0,&rc); + if (rc != 0) { + console_printf("invalid 'mtu' parameter\n"); + return rc; + } + + rc = parse_arg_uint8_list_with_separator("idxs", ",", 5, idxs, &num); + if (rc != 0) { + console_printf("invalid 'idxs' parameter\n"); + return rc; + } + + return btshell_l2cap_reconfig(conn, mtu, num, idxs); +#else + console_printf("To enable this features set BLE_L2CAP_ENHANCED_COC\n"); + return ENOTSUP; +#endif +} diff --git a/apps/btshell/src/cmd_l2cap.h b/apps/btshell/src/cmd_l2cap.h index 164b02d..d366fe2 100644 --- a/apps/btshell/src/cmd_l2cap.h +++ b/apps/btshell/src/cmd_l2cap.h @@ -28,5 +28,6 @@ int cmd_l2cap_connect(int argc, char **argv); int cmd_l2cap_disconnect(int argc, char **argv); int cmd_l2cap_send(int argc, char **argv); int cmd_l2cap_show_coc(int argc, char **argv); +int cmd_l2cap_reconfig(int argc, char **argv); #endif diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 56a17f1..714ce21 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -2226,9 +2226,9 @@ btshell_l2cap_event(struct ble_l2cap_event *event, void *arg) assert(0); } - console_printf("LE COC connected, conn: %d, chan: 0x%08lx, psm: 0x%02x, scid: 0x%04x, " - "dcid: 0x%04x, our_mps: %d, our_mtu: %d, peer_mps: 0x%d, peer_mtu: %d\n", - event->connect.conn_handle, (uint32_t) event->connect.chan, + console_printf("LE COC connected, conn: %d, chan: %p, psm: 0x%02x, scid: 0x%04x, " + "dcid: 0x%04x, our_mps: %d, our_mtu: %d, peer_mps: %d, peer_mtu: %d\n", + event->connect.conn_handle, event->connect.chan, chan_info.psm, chan_info.scid, chan_info.dcid, chan_info.our_l2cap_mtu, chan_info.our_coc_mtu, chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu); @@ -2237,8 +2237,8 @@ btshell_l2cap_event(struct ble_l2cap_event *event, void *arg) return 0; case BLE_L2CAP_EVENT_COC_DISCONNECTED: - console_printf("LE CoC disconnected, chan: 0x%08lx\n", - (uint32_t) event->disconnect.chan); + console_printf("LE CoC disconnected, chan: %p\n", + event->disconnect.chan); btshell_l2cap_coc_remove(event->disconnect.conn_handle, event->disconnect.chan); @@ -2256,6 +2256,37 @@ btshell_l2cap_event(struct ble_l2cap_event *event, void *arg) case BLE_L2CAP_EVENT_COC_DATA_RECEIVED: btshell_l2cap_coc_recv(event->receive.chan, event->receive.sdu_rx); return 0; + case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED: + + if (ble_l2cap_get_chan_info(event->reconfigured.chan, &chan_info)) { + assert(0); + } + + console_printf("LE CoC reconfigure completed status 0x%02x," \ + "chan: %p\n", + event->reconfigured.status, + event->reconfigured.chan); + + if (event->reconfigured.status == 0) { + console_printf("\t our_mps: %d our_mtu %d\n", chan_info.our_l2cap_mtu, chan_info.our_coc_mtu); + } + return 0; + case BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED: + + if (ble_l2cap_get_chan_info(event->reconfigured.chan, &chan_info)) { + assert(0); + } + + console_printf("LE CoC peer reconfigured status 0x%02x," \ + "chan: %p\n", + event->reconfigured.status, + event->reconfigured.chan); + + if (event->reconfigured.status == 0) { + console_printf("\t peer_mps: %d peer_mtu %d\n", chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu); + } + + return 0; case BLE_L2CAP_EVENT_COC_TX_UNSTALLED: console_printf("L2CAP CoC channel %p unstalled, last sdu sent with err=0x%02x\n", event->tx_unstalled.chan, event->tx_unstalled.status); @@ -2281,7 +2312,7 @@ btshell_l2cap_create_srv(uint16_t psm, int accept_response) } int -btshell_l2cap_connect(uint16_t conn_handle, uint16_t psm) +btshell_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint8_t num) { #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) == 0 console_printf("BLE L2CAP LE COC not supported."); @@ -2289,13 +2320,21 @@ btshell_l2cap_connect(uint16_t conn_handle, uint16_t psm) return 0; #else - struct os_mbuf *sdu_rx; + struct os_mbuf *sdu_rx[num]; + int i; - sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - assert(sdu_rx != NULL); + for (i = 0; i < num; i++) { + sdu_rx[i] = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); + assert(sdu_rx != NULL); + } - return ble_l2cap_connect(conn_handle, psm, BTSHELL_COC_MTU, sdu_rx, - btshell_l2cap_event, NULL); + if (num == 1) { + return ble_l2cap_connect(conn_handle, psm, BTSHELL_COC_MTU, sdu_rx[0], + btshell_l2cap_event, NULL); + } + + return ble_l2cap_enhanced_connect(conn_handle, psm, BTSHELL_COC_MTU, + num, sdu_rx,btshell_l2cap_event, NULL); #endif } @@ -2335,6 +2374,44 @@ btshell_l2cap_disconnect(uint16_t conn_handle, uint16_t idx) } int +btshell_l2cap_reconfig(uint16_t conn_handle, uint16_t mtu, + uint8_t num, uint8_t idxs[]) +{ + struct btshell_conn *conn; + struct btshell_l2cap_coc *coc; + struct ble_l2cap_chan * chans[5] = {0}; + int i, j; + int cnt; + + conn = btshell_conn_find(conn_handle); + if (conn == NULL) { + console_printf("conn=%d does not exist\n", conn_handle); + return 0; + } + + i = 0; + j = 0; + cnt = 0; + SLIST_FOREACH(coc, &conn->coc_list, next) { + for (i = 0; i < num; i++) { + if (idxs[i] == j) { + chans[cnt] = coc->chan; + cnt++; + break; + } + } + j++; + } + + if (cnt != num) { + console_printf("Missing coc? (%d!=%d)\n", num, cnt); + return BLE_HS_EINVAL; + } + + return ble_l2cap_reconfig(chans, cnt, mtu); +} + +int btshell_l2cap_send(uint16_t conn_handle, uint16_t idx, uint16_t bytes) { #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) == 0 diff --git a/apps/btshell/src/parse.c b/apps/btshell/src/parse.c index db79b45..d8018c5 100644 --- a/apps/btshell/src/parse.c +++ b/apps/btshell/src/parse.c @@ -466,6 +466,20 @@ parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len) } int +parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, + uint8_t *dst, int *out_len) +{ + char *sval; + + sval = parse_arg_extract(name); + if (sval == NULL) { + return ENOENT; + } + + return parse_arg_byte_stream_delim(sval, separator, max_len, dst, out_len); +} + +int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len) { int actual_len;
