mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-07-30 06:37:55 +00:00
btshell: Extend l2cap cli to support enhanced LE CoC
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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}
|
||||
};
|
||||
|
||||
@@ -3540,6 +3541,23 @@ static const struct shell_cmd_help l2cap_disconnect_help = {
|
||||
.params = l2cap_disconnect_params,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* $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 *
|
||||
*****************************************************************************/
|
||||
@@ -4387,6 +4405,13 @@ static const struct shell_cmd btshell_commands[] = {
|
||||
.sc_cmd_func = cmd_l2cap_connect,
|
||||
#if MYNEWT_VAL(SHELL_CMD_HELP)
|
||||
.help = &l2cap_connect_help,
|
||||
#endif
|
||||
},
|
||||
{
|
||||
.sc_cmd = "l2cap-reconfig",
|
||||
.sc_cmd_func = cmd_l2cap_reconfig,
|
||||
#if MYNEWT_VAL(SHELL_CMD_HELP)
|
||||
.help = &l2cap_reconfig_help,
|
||||
#endif
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+88
-11
@@ -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);
|
||||
@@ -2255,6 +2255,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",
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -2334,6 +2373,44 @@ btshell_l2cap_disconnect(uint16_t conn_handle, uint16_t idx)
|
||||
#endif
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -465,6 +465,20 @@ parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len)
|
||||
return parse_arg_byte_stream_delim(sval, ":-", max_len, dst, 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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user