Bluetooth: shell: Port commands to the news shell

Fixes #8873

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2018-09-24 10:59:23 +03:00 committed by Carles Cufí
commit 592dd2e964
9 changed files with 626 additions and 605 deletions

View file

@ -8,7 +8,8 @@
config BT_SHELL
bool "Enable Bluetooth shell"
select CONSOLE_SHELL
select SERIAL
select SHELL
help
Activate shell module that provides Bluetooth commands to the
console.

File diff suppressed because it is too large Load diff

View file

@ -13,6 +13,13 @@
#ifndef __BT_H
#define __BT_H
extern const struct shell *ctx_shell;
#define print(_sh, _ft, ...) \
shell_fprintf(_sh ? _sh : ctx_shell, SHELL_NORMAL, _ft, ##__VA_ARGS__)
#define error(_sh, _ft, ...) \
shell_fprintf(_sh ? _sh : ctx_shell, SHELL_ERROR, _ft, ##__VA_ARGS__)
extern struct bt_conn *default_conn;
#endif /* __BT_H */

View file

@ -14,7 +14,6 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <misc/printk.h>
#include <misc/byteorder.h>
#include <zephyr.h>
@ -22,6 +21,8 @@
#include <bluetooth/conn.h>
#include <bluetooth/gatt.h>
#include <shell/shell.h>
#include "bt.h"
#include "gatt.h"
@ -31,72 +32,70 @@
static void exchange_func(struct bt_conn *conn, u8_t err,
struct bt_gatt_exchange_params *params)
{
printk("Exchange %s\n", err == 0 ? "successful" : "failed");
print(NULL, "Exchange %s\n", err == 0 ? "successful" : "failed");
}
static struct bt_gatt_exchange_params exchange_params;
int cmd_gatt_exchange_mtu(int argc, char *argv[])
void cmd_gatt_exchange_mtu(const struct shell *shell, size_t argc, char *argv[])
{
int err;
if (!default_conn) {
printk("Not connected\n");
return 0;
print(shell, "Not connected\n");
return;
}
exchange_params.func = exchange_func;
err = bt_gatt_exchange_mtu(default_conn, &exchange_params);
if (err) {
printk("Exchange failed (err %d)\n", err);
print(shell, "Exchange failed (err %d)\n", err);
} else {
printk("Exchange pending\n");
print(shell, "Exchange pending\n");
}
return 0;
}
static struct bt_gatt_discover_params discover_params;
static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
static void print_chrc_props(u8_t properties)
static void print_chrc_props(const struct shell *shell, u8_t properties)
{
printk("Properties: ");
print(shell, "Properties: ");
if (properties & BT_GATT_CHRC_BROADCAST) {
printk("[bcast]");
print(shell, "[bcast]");
}
if (properties & BT_GATT_CHRC_READ) {
printk("[read]");
print(shell, "[read]");
}
if (properties & BT_GATT_CHRC_WRITE) {
printk("[write]");
print(shell, "[write]");
}
if (properties & BT_GATT_CHRC_WRITE_WITHOUT_RESP) {
printk("[write w/w rsp]");
print(shell, "[write w/w rsp]");
}
if (properties & BT_GATT_CHRC_NOTIFY) {
printk("[notify]");
print(shell, "[notify]");
}
if (properties & BT_GATT_CHRC_INDICATE) {
printk("[indicate]");
print(shell, "[indicate]");
}
if (properties & BT_GATT_CHRC_AUTH) {
printk("[auth]");
print(shell, "[auth]");
}
if (properties & BT_GATT_CHRC_EXT_PROP) {
printk("[ext prop]");
print(shell, "[ext prop]");
}
printk("\n");
print(shell, "\n");
}
static u8_t discover_func(struct bt_conn *conn,
@ -109,7 +108,7 @@ static u8_t discover_func(struct bt_conn *conn,
char str[37];
if (!attr) {
printk("Discover complete\n");
print(NULL, "Discover complete\n");
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
@ -119,39 +118,41 @@ static u8_t discover_func(struct bt_conn *conn,
case BT_GATT_DISCOVER_PRIMARY:
gatt_service = attr->user_data;
bt_uuid_to_str(gatt_service->uuid, str, sizeof(str));
printk("Service %s found: start handle %x, end_handle %x\n",
str, attr->handle, gatt_service->end_handle);
print(NULL, "Service %s found: start handle %x, "
"end_handle %x\n", str, attr->handle,
gatt_service->end_handle);
break;
case BT_GATT_DISCOVER_CHARACTERISTIC:
gatt_chrc = attr->user_data;
bt_uuid_to_str(gatt_chrc->uuid, str, sizeof(str));
printk("Characteristic %s found: handle %x\n", str,
print(NULL, "Characteristic %s found: handle %x\n", str,
attr->handle);
print_chrc_props(gatt_chrc->properties);
print_chrc_props(ctx_shell, gatt_chrc->properties);
break;
case BT_GATT_DISCOVER_INCLUDE:
gatt_include = attr->user_data;
bt_uuid_to_str(gatt_include->uuid, str, sizeof(str));
printk("Include %s found: handle %x, start %x, end %x\n",
str, attr->handle, gatt_include->start_handle,
print(NULL, "Include %s found: handle %x, start %x, "
"end %x\n", str, attr->handle, gatt_include->start_handle,
gatt_include->end_handle);
break;
default:
bt_uuid_to_str(attr->uuid, str, sizeof(str));
printk("Descriptor %s found: handle %x\n", str, attr->handle);
print(NULL, "Descriptor %s found: handle %x\n", str,
attr->handle);
break;
}
return BT_GATT_ITER_CONTINUE;
}
int cmd_gatt_discover(int argc, char *argv[])
void cmd_gatt_discover(const struct shell *shell, size_t argc, char *argv[])
{
int err;
if (!default_conn) {
printk("Not connected\n");
return 0;
error(shell, "Not connected\n");
return;
}
discover_params.func = discover_func;
@ -187,12 +188,10 @@ int cmd_gatt_discover(int argc, char *argv[])
err = bt_gatt_discover(default_conn, &discover_params);
if (err) {
printk("Discover failed (err %d)\n", err);
error(shell, "Discover failed (err %d)\n", err);
} else {
printk("Discover pending\n");
print(shell, "Discover pending\n");
}
return 0;
}
static struct bt_gatt_read_params read_params;
@ -201,7 +200,7 @@ static u8_t read_func(struct bt_conn *conn, u8_t err,
struct bt_gatt_read_params *params,
const void *data, u16_t length)
{
printk("Read complete: err %u length %u\n", err, length);
print(NULL, "Read complete: err %u length %u\n", err, length);
if (!data) {
(void)memset(params, 0, sizeof(*params));
@ -211,19 +210,19 @@ static u8_t read_func(struct bt_conn *conn, u8_t err,
return BT_GATT_ITER_CONTINUE;
}
int cmd_gatt_read(int argc, char *argv[])
void cmd_gatt_read(const struct shell *shell, size_t argc, char *argv[])
{
int err;
if (!default_conn) {
printk("Not connected\n");
return 0;
error(shell, "Not connected\n");
return;
}
read_params.func = read_func;
if (argc < 2) {
return -EINVAL;
if (!shell_cmd_precheck(shell, (argc >= 2), NULL, 0)) {
return;
}
read_params.handle_count = 1;
@ -236,31 +235,30 @@ int cmd_gatt_read(int argc, char *argv[])
err = bt_gatt_read(default_conn, &read_params);
if (err) {
printk("Read failed (err %d)\n", err);
error(shell, "Read failed (err %d)\n", err);
} else {
printk("Read pending\n");
print(shell, "Read pending\n");
}
return 0;
}
int cmd_gatt_mread(int argc, char *argv[])
void cmd_gatt_mread(const struct shell *shell, size_t argc, char *argv[])
{
u16_t h[8];
int i, err;
if (!default_conn) {
printk("Not connected\n");
return 0;
error(shell, "Not connected\n");
return;
}
if (argc < 3) {
return -EINVAL;
if (!shell_cmd_precheck(shell, (argc >= 3), NULL, 0)) {
return;
}
if (argc - 1 > ARRAY_SIZE(h)) {
printk("Enter max %lu handle items to read\n", ARRAY_SIZE(h));
return 0;
print(shell, "Enter max %lu handle items to read\n",
ARRAY_SIZE(h));
return;
}
for (i = 0; i < argc - 1; i++) {
@ -273,10 +271,9 @@ int cmd_gatt_mread(int argc, char *argv[])
err = bt_gatt_read(default_conn, &read_params);
if (err) {
printk("GATT multiple read request failed (err %d)\n", err);
error(shell, "GATT multiple read request failed (err %d)\n",
err);
}
return 0;
}
static struct bt_gatt_write_params write_params;
@ -285,28 +282,28 @@ static u8_t gatt_write_buf[CHAR_SIZE_MAX];
static void write_func(struct bt_conn *conn, u8_t err,
struct bt_gatt_write_params *params)
{
printk("Write complete: err %u\n", err);
print(NULL, "Write complete: err %u\n", err);
(void)memset(&write_params, 0, sizeof(write_params));
}
int cmd_gatt_write(int argc, char *argv[])
void cmd_gatt_write(const struct shell *shell, size_t argc, char *argv[])
{
int err;
u16_t handle, offset;
if (!default_conn) {
printk("Not connected\n");
return 0;
error(shell, "Not connected\n");
return;
}
if (write_params.func) {
printk("Write ongoing\n");
return 0;
error(shell, "Write ongoing\n");
return;
}
if (argc < 4) {
return -EINVAL;
if (!shell_cmd_precheck(shell, (argc >= 4), NULL, 0)) {
return;
}
handle = strtoul(argv[1], NULL, 16);
@ -334,15 +331,14 @@ int cmd_gatt_write(int argc, char *argv[])
err = bt_gatt_write(default_conn, &write_params);
if (err) {
printk("Write failed (err %d)\n", err);
error(shell, "Write failed (err %d)\n", err);
} else {
printk("Write pending\n");
print(shell, "Write pending\n");
}
return 0;
}
int cmd_gatt_write_without_rsp(int argc, char *argv[])
void cmd_gatt_write_without_rsp(const struct shell *shell,
size_t argc, char *argv[])
{
u16_t handle;
u16_t repeat;
@ -351,12 +347,12 @@ int cmd_gatt_write_without_rsp(int argc, char *argv[])
bool sign;
if (!default_conn) {
printk("Not connected\n");
return 0;
error(shell, "Not connected\n");
return;
}
if (argc < 3) {
return -EINVAL;
if (!shell_cmd_precheck(shell, (argc >= 3), NULL, 0)) {
return;
}
sign = !strcmp(argv[0], "gatt-write-signed");
@ -392,9 +388,7 @@ int cmd_gatt_write_without_rsp(int argc, char *argv[])
}
}
printk("Write Complete (err %d)\n", err);
return 0;
print(shell, "Write Complete (err %d)\n", err);
}
static struct bt_gatt_subscribe_params subscribe_params;
@ -404,33 +398,33 @@ static u8_t notify_func(struct bt_conn *conn,
const void *data, u16_t length)
{
if (!data) {
printk("Unsubscribed\n");
print(NULL, "Unsubscribed\n");
params->value_handle = 0;
return BT_GATT_ITER_STOP;
}
printk("Notification: data %p length %u\n", data, length);
print(NULL, "Notification: data %p length %u\n", data, length);
return BT_GATT_ITER_CONTINUE;
}
int cmd_gatt_subscribe(int argc, char *argv[])
void cmd_gatt_subscribe(const struct shell *shell, size_t argc, char *argv[])
{
int err;
if (subscribe_params.value_handle) {
printk("Cannot subscribe: subscription to %x already exists\n",
subscribe_params.value_handle);
return 0;
error(shell, "Cannot subscribe: subscription to %x already "
"exists\n", subscribe_params.value_handle);
return;
}
if (!default_conn) {
printk("Not connected\n");
return 0;
error(shell, "Not connected\n");
return;
}
if (argc < 3) {
return -EINVAL;
if (!shell_cmd_precheck(shell, (argc >= 3), NULL, 0)) {
return;
}
subscribe_params.ccc_handle = strtoul(argv[1], NULL, 16);
@ -444,52 +438,48 @@ int cmd_gatt_subscribe(int argc, char *argv[])
err = bt_gatt_subscribe(default_conn, &subscribe_params);
if (err) {
printk("Subscribe failed (err %d)\n", err);
error(shell, "Subscribe failed (err %d)\n", err);
} else {
printk("Subscribed\n");
print(shell, "Subscribed\n");
}
return 0;
}
int cmd_gatt_unsubscribe(int argc, char *argv[])
void cmd_gatt_unsubscribe(const struct shell *shell, size_t argc, char *argv[])
{
int err;
if (!default_conn) {
printk("Not connected\n");
return 0;
error(shell, "Not connected\n");
return;
}
if (!subscribe_params.value_handle) {
printk("No subscription found\n");
return 0;
error(shell, "No subscription found\n");
return;
}
err = bt_gatt_unsubscribe(default_conn, &subscribe_params);
if (err) {
printk("Unsubscribe failed (err %d)\n", err);
error(shell, "Unsubscribe failed (err %d)\n", err);
} else {
printk("Unsubscribe success\n");
print(shell, "Unsubscribe success\n");
}
return 0;
}
#endif /* CONFIG_BT_GATT_CLIENT */
static u8_t print_attr(const struct bt_gatt_attr *attr, void *user_data)
{
printk("attr %p handle 0x%04x uuid %s perm 0x%02x\n",
const struct shell *shell = user_data;
print(shell, "attr %p handle 0x%04x uuid %s perm 0x%02x\n",
attr, attr->handle, bt_uuid_str(attr->uuid), attr->perm);
return BT_GATT_ITER_CONTINUE;
}
int cmd_gatt_show_db(int argc, char *argv[])
void cmd_gatt_show_db(const struct shell *shell, size_t argc, char *argv[])
{
bt_gatt_foreach_attr(0x0001, 0xffff, print_attr, NULL);
return 0;
bt_gatt_foreach_attr(0x0001, 0xffff, print_attr, (void *)shell);
}
/* Custom Service Variables */
@ -529,7 +519,7 @@ static ssize_t write_vnd1(struct bt_conn *conn, const struct bt_gatt_attr *attr,
u8_t flags)
{
if (echo_enabled) {
printk("Echo attr len %u\n", len);
print(NULL, "Echo attr len %u\n", len);
bt_gatt_notify(conn, attr, buf, len);
}
@ -634,24 +624,22 @@ static struct bt_gatt_attr vnd1_attrs[] = {
static struct bt_gatt_service vnd1_svc = BT_GATT_SERVICE(vnd1_attrs);
int cmd_gatt_register_test_svc(int argc, char *argv[])
void cmd_gatt_register_test_svc(const struct shell *shell,
size_t argc, char *argv[])
{
bt_gatt_service_register(&vnd_svc);
bt_gatt_service_register(&vnd1_svc);
printk("Registering test vendor services\n");
return 0;
print(shell, "Registering test vendor services\n");
}
int cmd_gatt_unregister_test_svc(int argc, char *argv[])
void cmd_gatt_unregister_test_svc(const struct shell *shell,
size_t argc, char *argv[])
{
bt_gatt_service_unregister(&vnd_svc);
bt_gatt_service_unregister(&vnd1_svc);
printk("Unregistering test vendor services\n");
return 0;
print(shell, "Unregistering test vendor services\n");
}
static struct bt_uuid_128 met_svc_uuid = BT_UUID_INIT_128(
@ -726,36 +714,37 @@ static struct bt_gatt_attr met_attrs[] = {
static struct bt_gatt_service met_svc = BT_GATT_SERVICE(met_attrs);
int cmd_gatt_write_cmd_metrics(int argc, char *argv[])
void cmd_gatt_write_cmd_metrics(const struct shell *shell,
size_t argc, char *argv[])
{
int err = 0;
if (argc < 2) {
printk("Write: count= %u, len= %u, rate= %u bps.\n",
print(shell, "Write: count= %u, len= %u, rate= %u bps.\n",
write_count, write_len, write_rate);
return 0;
return;
}
if (!strcmp(argv[1], "on")) {
static bool registered;
if (!registered) {
printk("Registering GATT metrics test Service.\n");
print(shell, "Registering GATT metrics test "
"Service.\n");
err = bt_gatt_service_register(&met_svc);
registered = true;
}
} else if (!strcmp(argv[1], "off")) {
printk("Unregistering GATT metrics test Service.\n");
print(shell, "Unregistering GATT metrics test Service.\n");
err = bt_gatt_service_unregister(&met_svc);
} else {
printk("Incorrect value: %s\n", argv[1]);
return -EINVAL;
error(shell, "Incorrect value: %s\n", argv[1]);
shell_help_print(shell, NULL, 0);
return;
}
if (!err) {
printk("GATT write cmd metrics %s.\n", argv[1]);
print(shell, "GATT write cmd metrics %s.\n", argv[1]);
}
return err;
}

View file

@ -13,17 +13,22 @@
#ifndef __GATT_H
#define __GATT_H
int cmd_gatt_show_db(int argc, char *argv[]);
int cmd_gatt_exchange_mtu(int argc, char *argv[]);
int cmd_gatt_discover(int argc, char *argv[]);
int cmd_gatt_read(int argc, char *argv[]);
int cmd_gatt_mread(int argc, char *argv[]);
int cmd_gatt_write(int argc, char *argv[]);
int cmd_gatt_write_without_rsp(int argc, char *argv[]);
int cmd_gatt_subscribe(int argc, char *argv[]);
int cmd_gatt_unsubscribe(int argc, char *argv[]);
int cmd_gatt_register_test_svc(int argc, char *argv[]);
int cmd_gatt_unregister_test_svc(int argc, char *argv[]);
int cmd_gatt_write_cmd_metrics(int argc, char *argv[]);
void cmd_gatt_show_db(const struct shell *shell, size_t argc, char *argv[]);
void cmd_gatt_exchange_mtu(const struct shell *shell,
size_t argc, char *argv[]);
void cmd_gatt_discover(const struct shell *shell, size_t argc, char *argv[]);
void cmd_gatt_read(const struct shell *shell, size_t argc, char *argv[]);
void cmd_gatt_mread(const struct shell *shell, size_t argc, char *argv[]);
void cmd_gatt_write(const struct shell *shell, size_t argc, char *argv[]);
void cmd_gatt_write_without_rsp(const struct shell *shell,
size_t argc, char *argv[]);
void cmd_gatt_subscribe(const struct shell *shell, size_t argc, char *argv[]);
void cmd_gatt_unsubscribe(const struct shell *shell, size_t argc, char *argv[]);
void cmd_gatt_register_test_svc(const struct shell *shell,
size_t argc, char *argv[]);
void cmd_gatt_unregister_test_svc(const struct shell *shell,
size_t argc, char *argv[]);
void cmd_gatt_write_cmd_metrics(const struct shell *shell,
size_t argc, char *argv[]);
#endif /* __GATT_H */

View file

@ -15,7 +15,6 @@ CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_TINYCRYPT_ECC=y
CONFIG_CONSOLE_SHELL=y
CONFIG_BT_SHELL=y
CONFIG_BT_DEVICE_NAME="test shell"
CONFIG_BT_DEVICE_NAME_DYNAMIC=y

View file

@ -3,7 +3,6 @@ CONFIG_BT=y
CONFIG_BT_BREDR=y
CONFIG_BT_RFCOMM=y
CONFIG_CONSOLE_HANDLER=y
CONFIG_CONSOLE_SHELL=y
CONFIG_BT_SHELL=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_CENTRAL=y

View file

@ -21,21 +21,24 @@
#include <misc/byteorder.h>
#include <zephyr.h>
#include <shell/legacy_shell.h>
#include <shell/shell.h>
#include <shell/shell_uart.h>
#include <gatt/hrs.h>
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define MY_SHELL_MODULE "btshell"
SHELL_UART_DEFINE(shell_transport_uart);
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, '\r', 10);
#if defined(CONFIG_BT_CONN)
static bool hrs_simulate;
static int cmd_hrs_simulate(int argc, char *argv[])
static void cmd_hrs_simulate(const struct shell *shell,
size_t argc, char *argv[])
{
if (argc < 2) {
return -EINVAL;
if (!shell_cmd_precheck(shell, (argc == 2), NULL, 0)) {
return;
}
if (!strcmp(argv[1], "on")) {
@ -54,32 +57,49 @@ static int cmd_hrs_simulate(int argc, char *argv[])
hrs_simulate = false;
} else {
printk("Incorrect value: %s\n", argv[1]);
return -EINVAL;
shell_help_print(shell, NULL, 0);
return;
}
return 0;
}
#endif /* CONFIG_BT_CONN */
#define HELP_NONE "[none]"
#define HELP_ADDR_LE "<address: XX:XX:XX:XX:XX:XX> <type: (public|random)>"
static const struct shell_cmd commands[] = {
SHELL_CREATE_STATIC_SUBCMD_SET(hrs_cmds) {
#if defined(CONFIG_BT_CONN)
{ "hrs-simulate", cmd_hrs_simulate,
"register and simulate Heart Rate Service <value: on, off>" },
SHELL_CMD(hrs-simulate, NULL,
"register and simulate Heart Rate Service <value: on, off>",
cmd_hrs_simulate),
#endif /* CONFIG_BT_CONN */
{ NULL, NULL }
SHELL_SUBCMD_SET_END
};
static void cmd_hrs(const struct shell *shell, size_t argc, char **argv)
{
if (argc == 1) {
shell_help_print(shell, NULL, 0);
return;
}
if (!shell_cmd_precheck(shell, (argc == 2), NULL, 0)) {
return;
}
shell_fprintf(shell, SHELL_ERROR, "%s:%s%s\r\n", argv[0],
"unknown parameter: ", argv[1]);
}
SHELL_CMD_REGISTER(hrs, &hrs_cmds, "Heart Rate Service shell commands",
cmd_hrs);
void main(void)
{
printk("Type \"help\" for supported commands.\n");
printk("Before any Bluetooth commands you must \"select bt\" and then "
"run \"init\".\n");
printk("Before any Bluetooth commands you must \"bt init\" to "
"initialize the stack.\n");
SHELL_REGISTER(MY_SHELL_MODULE, commands);
shell_register_default_module(MY_SHELL_MODULE);
(void)shell_init(&uart_shell, NULL, true, true, LOG_LEVEL_INF);
while (1) {
k_sleep(MSEC_PER_SEC);

View file

@ -1,11 +1,15 @@
tests:
test:
extra_configs:
- CONFIG_NATIVE_UART_0_ON_STDINOUT=y
platform_whitelist: qemu_cortex_m3 qemu_x86 arduino_101 native_posix
platform_exclude: nrf52810_pca10040
tags: bluetooth
harness: keyboard
min_flash: 145
test_br:
extra_configs:
- CONFIG_NATIVE_UART_0_ON_STDINOUT=y
extra_args: CONF_FILE="prj_br.conf"
platform_whitelist: qemu_cortex_m3 qemu_x86 native_posix
platform_exclude: nrf52810_pca10040