This is an automated email from the ASF dual-hosted git repository. kopyscinski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit 1f559ab80bd187db8e1e17e74bead3ea30df5865 Author: Krzysztof Kopyściński <[email protected]> AuthorDate: Fri Aug 18 07:38:29 2023 +0200 apps/btshell: add support for sending Multiple handle Notifications Added commands for queueing notifications to be sent using Multiple Handle Notification, sending them and clearing pending queue. --- apps/btshell/src/btshell.h | 6 +++ apps/btshell/src/cmd.c | 58 +++++++++++++++++++++++++++ apps/btshell/src/cmd_gatt.c | 72 ++++++++++++++++++++++++++++++++++ apps/btshell/src/cmd_gatt.h | 3 ++ apps/btshell/src/main.c | 78 +++++++++++++++++++++++++++++++++++++ nimble/host/include/host/ble_gatt.h | 4 +- nimble/host/src/ble_gattc.c | 4 +- 7 files changed, 221 insertions(+), 4 deletions(-) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index 17b07458a..d7beb1490 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -127,6 +127,12 @@ int btshell_write_long(uint16_t conn_handle, uint16_t attr_handle, uint16_t offset, struct os_mbuf *om); int btshell_write_reliable(uint16_t conn_handle, struct ble_gatt_attr *attrs, int num_attrs); +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) +int btshell_enqueue_notif(uint16_t handle, uint16_t len, uint8_t *value); +int btshell_send_pending_notif(uint16_t conn_handle); +int btshell_clear_pending_notif(void); +#endif + #if MYNEWT_VAL(BLE_EXT_ADV) int btshell_ext_adv_configure(uint8_t instance, const struct ble_gap_ext_adv_params *params, diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index bba5022df..f23c4b923 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -3498,6 +3498,43 @@ static const struct shell_cmd_help gatt_write_help = { .usage = NULL, .params = gatt_write_params, }; + +/***************************************************************************** + * $gatt-enqueue-notify * + *****************************************************************************/ + +static const struct shell_param gatt_enqueue_notif_params[] = { + {"handle", "characteristic handle, usage: =<UINT16>"}, + {"value", "usage: =<octets>"}, + {NULL, NULL} +}; + +static const struct shell_cmd_help gatt_enqueue_notif_help = { + .summary = "enqueue notification to be sent", + .usage = NULL, + .params = gatt_enqueue_notif_params, +}; + +/***************************************************************************** + * $gatt-send-pending-notify * + *****************************************************************************/ + +static const struct shell_param gatt_send_pending_notif_params[] = { + {"conn", "connection handle, usage: =<UINT16>"}, + {NULL, NULL} +}; + +static const struct shell_cmd_help gatt_send_pending_notif_help = { + .summary = "send pending notifications", + .usage = NULL, + .params = gatt_send_pending_notif_params, +}; + +static const struct shell_cmd_help gatt_clear_pending_notif_help = { + .summary = "clear pending notifications", + .usage = NULL, + .params = NULL, +}; #endif #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) @@ -4552,6 +4589,27 @@ static const struct shell_cmd btshell_commands[] = { .sc_cmd_func = cmd_gatt_write, #if MYNEWT_VAL(SHELL_CMD_HELP) .help = &gatt_write_help, +#endif + }, + { + .sc_cmd = "gatt-enqueue-notif", + .sc_cmd_func = cmd_gatt_enqueue_notif, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &gatt_enqueue_notif_help, +#endif + }, + { + .sc_cmd = "gatt-send-queued-notif", + .sc_cmd_func = cmd_gatt_send_pending_notif, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &gatt_send_pending_notif_help, +#endif + }, + { + .sc_cmd = "gatt-clear-queued-notif", + .sc_cmd_func = cmd_gatt_clear_pending_notif, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &gatt_clear_pending_notif_help, #endif }, #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) diff --git a/apps/btshell/src/cmd_gatt.c b/apps/btshell/src/cmd_gatt.c index 734b10047..3011dd9ca 100644 --- a/apps/btshell/src/cmd_gatt.c +++ b/apps/btshell/src/cmd_gatt.c @@ -592,3 +592,75 @@ done: return rc; } + +int +cmd_gatt_enqueue_notif(int argc, char **argv) +{ +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) + int rc; + uint16_t handle; + unsigned int len; + uint8_t value[BLE_ATT_ATTR_MAX_LEN]; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + handle = parse_arg_uint16("handle", &rc); + if (rc != 0) { + console_printf("invalid 'handle' parameter\n"); + return rc; + } + + if (argc > 1) { + rc = parse_arg_byte_stream("value", BLE_ATT_ATTR_MAX_LEN, value, &len); + if (rc != 0) { + console_printf("invalid 'value' parameter\n"); + return rc; + } + return btshell_enqueue_notif(handle, len, value); + } else { + return btshell_enqueue_notif(handle, 0, NULL); + } +#else + console_printf("To enable this features set BLE_GATT_NOTIFY_MULTIPLE\n"); + return ENOTSUP; +#endif +} + +int +cmd_gatt_send_pending_notif(int argc, char **argv) +{ +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) + uint16_t conn_handle; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + conn_handle = parse_arg_uint16("conn", &rc); + if (rc != 0) { + console_printf("invalid 'conn' parameter\n"); + return rc; + } + + return btshell_send_pending_notif(conn_handle); +#else + console_printf("To enable this features set BLE_GATT_NOTIFY_MULTIPLE\n"); + return ENOTSUP; +#endif +} + +int +cmd_gatt_clear_pending_notif(int argc, char **argv) +{ +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) + return btshell_clear_pending_notif(); +#else + console_printf("To enable this features set BLE_GATT_NOTIFY_MULTIPLE\n"); + return ENOTSUP; +#endif +} diff --git a/apps/btshell/src/cmd_gatt.h b/apps/btshell/src/cmd_gatt.h index 70536d03c..ae517f9a1 100644 --- a/apps/btshell/src/cmd_gatt.h +++ b/apps/btshell/src/cmd_gatt.h @@ -35,5 +35,8 @@ int cmd_gatt_service_visibility(int argc, char **argv); int cmd_gatt_show(int argc, char **argv); int cmd_gatt_show_local(int argc, char **argv); int cmd_gatt_write(int argc, char **argv); +int cmd_gatt_enqueue_notif(int argc, char **argv); +int cmd_gatt_send_pending_notif(int argc, char **argv); +int cmd_gatt_clear_pending_notif(int argc, char **argv); #endif diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 8224f42a5..f29b98f75 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -109,6 +109,11 @@ struct os_mbuf_pool sdu_os_mbuf_pool; static struct os_mempool sdu_coc_mbuf_mempool; #endif +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) +static struct ble_gatt_notif pending_notif[BTSHELL_MAX_CHRS]; +static size_t pending_notif_cnt; +#endif + static struct os_callout btshell_tx_timer; struct btshell_tx_data_s { @@ -1814,6 +1819,79 @@ btshell_write_reliable(uint16_t conn_handle, return rc; } +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) +int +btshell_enqueue_notif(uint16_t handle, uint16_t len, uint8_t *value) +{ + struct ble_gatt_notif *notify = NULL; + struct os_mbuf *val_ptr; + int i; + + for (i = 0; i < BTSHELL_MAX_CHRS; i++) { + if (pending_notif[i].handle == 0) { + notify = &pending_notif[i]; + break; + } + } + + if (notify == NULL) { + return ENOMEM; + } + + notify->handle = handle; + if (value != NULL) { + notify->value = os_msys_get(0, 0); + + val_ptr = os_mbuf_extend(notify->value, len); + if (val_ptr == NULL) { + return ENOMEM; + } + memcpy(val_ptr, value, len); + } + + pending_notif_cnt++; + + return 0; +} + +int +btshell_send_pending_notif(uint16_t conn_handle) +{ + int rc = 0; + int i; + + if (pending_notif_cnt == 0) { + return EALREADY; + } + + rc = ble_gatts_notify_multiple_custom(conn_handle, pending_notif_cnt, + pending_notif); + for (i = 0; i < pending_notif_cnt; i++) { + pending_notif[i].handle = 0; + pending_notif[i].value = NULL; + } + + pending_notif_cnt = 0; + + return rc; +} + +int +btshell_clear_pending_notif(void) +{ + int i; + + for (i = 0; i < pending_notif_cnt; i++) { + pending_notif[i].handle = 0; + pending_notif[i].value = NULL; + } + + pending_notif_cnt = 0; + + return 0; +} +#endif + #if MYNEWT_VAL(BLE_EXT_ADV) int btshell_ext_adv_configure(uint8_t instance, diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index a38d3c934..dbd6c94b5 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -668,7 +668,7 @@ int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle, * @return 0 on success; nonzero on failure. */ int ble_gatts_notify_multiple_custom(uint16_t conn_handle, - uint16_t chr_count, + size_t chr_count, struct ble_gatt_notif *tuples); /** @@ -719,7 +719,7 @@ int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle); * @return 0 on success; nonzero on failure. */ int ble_gatts_notify_multiple(uint16_t conn_handle, - uint8_t num_handles, + size_t num_handles, const uint16_t *chr_val_handles); /** diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index d40adfd3c..91f579c73 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -4415,7 +4415,7 @@ ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle) int ble_gatts_notify_multiple_custom(uint16_t conn_handle, - uint16_t chr_count, + size_t chr_count, struct ble_gatt_notif *tuples) { #if !MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) @@ -4507,7 +4507,7 @@ done: int ble_gatts_notify_multiple(uint16_t conn_handle, - uint8_t num_handles, + size_t num_handles, const uint16_t *chr_val_handles) { #if !MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE)
