From 0742a45ac9f51d45f7b1fe148ac7d9bbfecb2f83 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 17 Jun 2020 21:16:12 -0700 Subject: [PATCH] Bluetooth: shell: Add support for printing the write rate This makes the gatt metrics also available for gatt write-without-rsp-cb so it now prints the rate of each write: uart:~$ gatt write-without-response-cb 1e ff 10 10 Write #1: 16 bytes (0 bps) Write #2: 32 bytes (3445948416 bps) Write #3: 48 bytes (2596929536 bps) Write #4: 64 bytes (6400 bps) Write #5: 80 bytes (8533 bps) Write #6: 96 bytes (10666 bps) Write #7: 112 bytes (8533 bps) Write #8: 128 bytes (9955 bps) Write #9: 144 bytes (11377 bps) Write #10: 160 bytes (7680 bps) Write #11: 176 bytes (8533 bps) Write #12: 192 bytes (9386 bps) Write Complete (err 0) Write #13: 208 bytes (8533 bps) Write #14: 224 bytes (9244 bps) Write #15: 240 bytes (9955 bps) Write #16: 256 bytes (8000 bps) Signed-off-by: Luiz Augusto von Dentz --- subsys/bluetooth/shell/gatt.c | 93 +++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/subsys/bluetooth/shell/gatt.c b/subsys/bluetooth/shell/gatt.c index 1f6640f10412f2..0bcaec4fc9ae61 100644 --- a/subsys/bluetooth/shell/gatt.c +++ b/subsys/bluetooth/shell/gatt.c @@ -404,9 +404,60 @@ static int cmd_write(const struct shell *shell, size_t argc, char *argv[]) return err; } +static struct write_stats { + uint32_t count; + uint32_t len; + uint32_t total; + uint32_t rate; +} write_stats; + +static void update_write_stats(uint16_t len) +{ + static uint32_t cycle_stamp; + uint32_t delta; + + delta = k_cycle_get_32() - cycle_stamp; + delta = (uint32_t)k_cyc_to_ns_floor64(delta); + + if (!delta) { + delta = 1; + } + + write_stats.count++; + write_stats.total += len; + + /* if last data rx-ed was greater than 1 second in the past, + * reset the metrics. + */ + if (delta > 1000000000) { + write_stats.len = 0U; + write_stats.rate = 0U; + cycle_stamp = k_cycle_get_32(); + } else { + write_stats.len += len; + write_stats.rate = ((uint64_t)write_stats.len << 3) * + 1000000000U / delta; + } +} + +static void reset_write_stats(void) +{ + memset(&write_stats, 0, sizeof(write_stats)); +} + +static void print_write_stats(void) +{ + shell_print(ctx_shell, "Write #%u: %u bytes (%u bps)", + write_stats.count, write_stats.total, write_stats.rate); +} + static void write_without_rsp_cb(struct bt_conn *conn, void *user_data) { - shell_print(ctx_shell, "Write transmission complete"); + uint16_t len = POINTER_TO_UINT(user_data); + + update_write_stats(len); + + print_write_stats(); } static int cmd_write_without_rsp(const struct shell *shell, @@ -428,6 +479,7 @@ static int cmd_write_without_rsp(const struct shell *shell, if (!sign) { if (!strcmp(argv[0], "write-without-response-cb")) { func = write_without_rsp_cb; + reset_write_stats(); } } @@ -458,10 +510,14 @@ static int cmd_write_without_rsp(const struct shell *shell, while (repeat--) { err = bt_gatt_write_without_response_cb(default_conn, handle, gatt_write_buf, len, - sign, func, NULL); + sign, func, + UINT_TO_POINTER(len)); if (err) { break; } + + k_yield(); + } shell_print(shell, "Write Complete (err %d)", err); @@ -844,17 +900,11 @@ static ssize_t read_met(struct bt_conn *conn, const struct bt_gatt_attr *attr, value_len); } -static uint32_t write_count; -static uint32_t write_len; -static uint32_t write_rate; - static ssize_t write_met(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { uint8_t *value = attr->user_data; - static uint32_t cycle_stamp; - uint32_t delta; if (offset + len > sizeof(met_char_value)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); @@ -862,22 +912,7 @@ static ssize_t write_met(struct bt_conn *conn, const struct bt_gatt_attr *attr, memcpy(value + offset, buf, len); - delta = k_cycle_get_32() - cycle_stamp; - delta = (uint32_t)k_cyc_to_ns_floor64(delta); - - /* if last data rx-ed was greater than 1 second in the past, - * reset the metrics. - */ - if (delta > 1000000000) { - write_count = 0U; - write_len = 0U; - write_rate = 0U; - cycle_stamp = k_cycle_get_32(); - } else { - write_count++; - write_len += len; - write_rate = ((uint64_t)write_len << 3) * 1000000000U / delta; - } + update_write_stats(len); return len; } @@ -898,10 +933,8 @@ static int cmd_metrics(const struct shell *shell, size_t argc, char *argv[]) int err = 0; if (argc < 2) { - shell_print(shell, "Write: count= %u, len= %u, rate= %u bps.", - write_count, write_len, write_rate); - - return -ENOEXEC; + print_write_stats(); + return 0; } if (!strcmp(argv[1], "on")) { @@ -1063,9 +1096,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(gatt_cmds, SHELL_CMD_ARG(set, NULL, " [data...]", cmd_set, 2, 255), SHELL_CMD_ARG(show-db, NULL, "[uuid] [num_matches]", cmd_show_db, 1, 2), #if defined(CONFIG_BT_GATT_DYNAMIC_DB) - SHELL_CMD_ARG(metrics, NULL, - "register vendr char and measure rx ", - cmd_metrics, 2, 0), + SHELL_CMD_ARG(metrics, NULL, "[value: on, off]", cmd_metrics, 1, 1), SHELL_CMD_ARG(register, NULL, "register pre-predefined test service", cmd_register_test_svc, 1, 0),