Bluetooth: Shell: Make gatt notify more general

Make `gatt notify` take the source handle and the data to send.

Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
This commit is contained in:
Aleksander Wasaznik 2023-01-17 13:19:30 +01:00 committed by Carles Cufí
parent cc1c3ac58e
commit 6b6178be30
2 changed files with 78 additions and 33 deletions

View file

@ -12,9 +12,12 @@
#include <errno.h>
#include <zephyr/types.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <zephyr/shell/shell_string_conv.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
@ -561,7 +564,8 @@ static uint8_t notify_func(struct bt_conn *conn,
return BT_GATT_ITER_STOP;
}
shell_print(ctx_shell, "Notification: data %p length %u", data, length);
shell_print(ctx_shell, "Notification: length %u", length);
shell_hexdump(ctx_shell, data, length);
return BT_GATT_ITER_CONTINUE;
}
@ -946,43 +950,81 @@ static int cmd_unregister_test_svc(const struct shell *sh,
return 0;
}
static uint8_t found_attr(const struct bt_gatt_attr *attr, uint16_t handle,
void *user_data)
{
const struct bt_gatt_attr **found = user_data;
*found = attr;
return BT_GATT_ITER_STOP;
}
static const struct bt_gatt_attr *find_attr(uint16_t handle)
{
const struct bt_gatt_attr *attr = NULL;
bt_gatt_foreach_attr(handle, handle, found_attr, &attr);
return attr;
}
static int cmd_notify(const struct shell *sh, size_t argc, char *argv[])
{
const struct bt_gatt_attr *attr;
int err;
size_t data_len;
unsigned long handle;
static char data[CHAR_SIZE_MAX];
const char *arg_handle = argv[1];
const char *arg_data = argv[2];
size_t arg_data_len = strlen(arg_data);
err = 0;
handle = shell_strtoul(arg_handle, 16, &err);
if (err) {
shell_error(sh, "Handle '%s': Not a valid hex number.", arg_handle);
return -EINVAL;
}
if (!IN_RANGE(handle, BT_ATT_FIRST_ATTRIBUTE_HANDLE, BT_ATT_LAST_ATTRIBUTE_HANDLE)) {
shell_error(sh, "Handle 0x%lx: Impossible value.", handle);
return -EINVAL;
}
if ((arg_data_len / 2) > CHAR_SIZE_MAX) {
shell_error(sh, "Data: Size exceeds legal attribute size.");
return -EINVAL;
}
data_len = hex2bin(arg_data, arg_data_len, data, sizeof(data));
if (data_len == 0 && arg_data_len != 0) {
shell_error(sh, "Data: Bad hex.");
return -EINVAL;
}
attr = find_attr(handle);
if (!attr) {
shell_error(sh, "Handle 0x%lx: Local attribute not found.", handle);
return -EINVAL;
}
err = bt_gatt_notify(NULL, attr, data, data_len);
if (err) {
shell_error(sh, "bt_gatt_notify errno %d (%s)", -err, strerror(-err));
}
return err;
}
#if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
static void notify_cb(struct bt_conn *conn, void *user_data)
{
const struct shell *sh = user_data;
shell_print(sh, "Nofication sent to conn %p", conn);
}
static int cmd_notify(const struct shell *sh, size_t argc, char *argv[])
{
struct bt_gatt_notify_params params;
uint8_t data = 0;
if (!echo_enabled) {
shell_error(sh, "No clients have enabled notifications for the vnd1_echo CCC.");
return -ENOEXEC;
}
if (argc > 1) {
data = strtoul(argv[1], NULL, 16);
}
memset(&params, 0, sizeof(params));
params.uuid = &vnd1_echo_uuid.uuid;
params.attr = vnd1_attrs;
params.data = &data;
params.len = sizeof(data);
params.func = notify_cb;
params.user_data = (void *)sh;
SET_CHAN_OPT_ANY(params);
bt_gatt_notify_cb(NULL, &params);
return 0;
}
#if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
static int cmd_notify_mult(const struct shell *sh, size_t argc, char *argv[])
{
const size_t max_cnt = CONFIG_BT_L2CAP_TX_BUF_COUNT;
@ -1294,7 +1336,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(gatt_cmds,
SHELL_CMD_ARG(unregister, NULL,
"unregister pre-predefined test service",
cmd_unregister_test_svc, 1, 0),
SHELL_CMD_ARG(notify, NULL, "[data]", cmd_notify, 1, 1),
SHELL_CMD_ARG(notify, NULL, "<handle> <data>", cmd_notify, 3, 0),
#if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
SHELL_CMD_ARG(notify-mult, NULL, "count [data]", cmd_notify_mult, 2, 1),
#endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */

View file

@ -62,3 +62,6 @@ CONFIG_BT_ISO_PERIPHERAL=y
# kernel log-level bt_l2cap 2
# kernel log-level bt_att 4
CONFIG_LOG_RUNTIME_FILTERING=y
# Errno message table. Disable to save ROM.
CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE=y