summaryrefslogtreecommitdiff
path: root/src/libs/mynewt-nimble/apps/blestress/src/stress.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/mynewt-nimble/apps/blestress/src/stress.c')
-rw-r--r--src/libs/mynewt-nimble/apps/blestress/src/stress.c389
1 files changed, 389 insertions, 0 deletions
diff --git a/src/libs/mynewt-nimble/apps/blestress/src/stress.c b/src/libs/mynewt-nimble/apps/blestress/src/stress.c
new file mode 100644
index 00000000..6f5badf0
--- /dev/null
+++ b/src/libs/mynewt-nimble/apps/blestress/src/stress.c
@@ -0,0 +1,389 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "stress.h"
+
+void
+com_stress_print_report(const struct com_stress_test_ctx *test_ctxs)
+{
+ console_printf("\033[0;32mAll tests completed\033[0m\n");
+ console_printf("Tests results:\n");
+
+ console_printf(
+ "\033[0;33mUse case 1 - Stress Connect -> Connect Cancel: \n\033[0m");
+ console_printf("Con attempts = %d\n", test_ctxs->con_stat[1].attempts_num);
+ console_printf("Con success = %d\n", test_ctxs->con_stat[1].num);
+
+ console_printf(
+ "\033[0;33mUse case 2 - Stress Connect/Disconnect legacy: \n\033[0m");
+ console_printf("Con attempts = %d\n", test_ctxs->con_stat[2].attempts_num);
+ console_printf("Con success = %d\n", test_ctxs->con_stat[2].num);
+
+ console_printf(
+ "\033[0;33mUse case 3 - Stress Connect/Disconnect ext adv: \n\033[0m");
+ console_printf("Con attempts = %d\n", test_ctxs->con_stat[3].attempts_num);
+ console_printf("Con success = %d\n", test_ctxs->con_stat[3].num);
+
+ console_printf(
+ "\033[0;33mUse case 4 - Stress connection params update (TX): \n\033[0m");
+ console_printf("Params updates = %d\n",
+ test_ctxs->con_stat[4].prms_upd_num);
+
+ console_printf(
+ "\033[0;33mUse case 5 - Stress connection params update (RX): \n\033[0m");
+ console_printf("Params updates = %d\n",
+ test_ctxs->con_stat[5].prms_upd_num);
+
+ console_printf("\033[0;33mUse case 6 - Stress Scan: \n\033[0m");
+ console_printf("Received first packets = %d\n",
+ test_ctxs->s6_rcv_adv_first);
+ console_printf("Received all packets = %d\n", test_ctxs->s6_rcv_adv_suc);
+
+ console_printf("\033[0;33mUse case 7 - Stress PHY Update (TX): \n\033[0m");
+ console_printf("PHY updates = %d\n", test_ctxs->con_stat[7].phy_upd_num);
+
+ console_printf("\033[0;33mUse case 8 - Stress PHY Update (RX): \n\033[0m");
+ console_printf("PHY updates = %d\n", test_ctxs->con_stat[8].phy_upd_num);
+
+ console_printf(
+ "\033[0;33mUse case 9 - Stress multi connection: \n\033[0m");
+ console_printf("Max reached num of connections = %d\n",
+ test_ctxs->con_stat[9].max_num);
+
+ console_printf("\033[0;33mUse case 10 - Stress L2CAP send: \n\033[0m");
+ console_printf("Average bit rate = %d\n", test_ctxs->s10_bit_rate);
+ console_printf("Max received MTU = %lld\n", test_ctxs->s10_max_mtu);
+
+ console_printf("\033[0;33mUse case 11 - "
+ "Stress Advertise/Connect/Continue adv \n\033[0m");
+// console_printf(" = %d\n",);
+
+ console_printf("\033[0;33mUse case 12 - "
+ "Stress GATT indication: \n\033[0m");
+ console_printf("Average bit rate = %d\n", test_ctxs->s12_notif_time);
+
+ console_printf("\033[0;33mUse case 13 - "
+ "Stress GATT notification: \n\033[0m");
+ console_printf("Average time = %d\n", test_ctxs->s13_notif_time);
+
+ console_printf("\033[0;33mUse case 14 - "
+ "Stress GATT Subscribe/Notify/Unsubscribe: \n\033[0m");
+ console_printf("Average time = %d\n", test_ctxs->s14_notif_time);
+
+ console_printf("\033[0;33mUse case 15 - "
+ "Stress Connect/Send/Disconnect: \n\033[0m");
+ console_printf("Con num = %d\n", test_ctxs->con_stat[15].num);
+}
+
+void
+stress_clear_ctx_reusable_var(struct com_stress_test_ctx *ctx)
+{
+ ctx->cur_test_id = 0;
+ ctx->dev_addr.type = 0;
+ ctx->dev_addr.type = 0;
+ ctx->conn_handle = 0;
+ ctx->chan = 0;
+ ctx->rcv_data_bytes = 0;
+ ctx->rcv_num = 0;
+ ctx->send_num = 0;
+ ctx->begin_us = 0;
+ ctx->end_us = 0;
+ ctx->time_sum = 0;
+ ctx->bytes_sum = 0;
+ ctx->timeout_flag = 0;
+ ctx->rcv_data_flag = 0;
+}
+
+int
+stress_fill_mbuf_with_pattern(struct os_mbuf *om, uint16_t len)
+{
+ int rc, i, mul, rest;
+
+ mul = len / STRESS_PAT_LEN;
+ rest = len % STRESS_PAT_LEN;
+
+ for (i = 0; i < mul; ++i) {
+ rc = os_mbuf_append(om, &test_6_pattern[29], STRESS_PAT_LEN);
+
+ if (rc) {
+ os_mbuf_free_chain(om);
+ assert(0);
+ }
+ }
+
+ rc = os_mbuf_append(om, &test_6_pattern[29], rest);
+
+ if (rc) {
+ os_mbuf_free_chain(om);
+ assert(0);
+ }
+
+ return rc;
+}
+
+void
+stress_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu)
+{
+ int rc;
+ console_printf("LE CoC SDU received, chan: 0x%08lx, data len %d\n",
+ (uint32_t) chan, OS_MBUF_PKTLEN(sdu));
+
+ rc = os_mbuf_free_chain(sdu);
+ assert(rc == 0);
+
+ /* Get buffer for data chain */
+ sdu = os_msys_get_pkthdr(STRESS_COC_MTU, 0);
+ assert(sdu != NULL);
+
+ /* Receive data chain */
+ rc = ble_l2cap_recv_ready(chan, sdu);
+ assert(rc == 0);
+}
+
+void
+stress_l2cap_coc_accept(uint16_t peer_mtu, struct ble_l2cap_chan *chan)
+{
+ struct os_mbuf *sdu_rx;
+ int rc;
+
+ console_printf("LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n",
+ (uint32_t) chan, peer_mtu);
+
+ sdu_rx = os_msys_get_pkthdr(STRESS_COC_MTU, 0);
+ assert(sdu_rx != NULL);
+
+ rc = ble_l2cap_recv_ready(chan, sdu_rx);
+ assert(rc == 0);
+}
+
+void
+stress_start_timer(uint32_t timeout_ms, os_event_fn *ev_cb)
+{
+ int rc;
+ os_callout_stop(&stress_timer_callout);
+
+ os_callout_init(&stress_timer_callout, os_eventq_dflt_get(), ev_cb, NULL);
+
+ rc = os_callout_reset(&stress_timer_callout,
+ os_time_ms_to_ticks32(timeout_ms));
+
+ assert(rc == 0);
+}
+
+int64_t
+stress_calc_bit_rate(int64_t us, int64_t bytes_num)
+{
+ int bit_rate;
+
+ /* Multiply by 1000000 so you don't lose accuracy */
+ bit_rate = 1000000 * bytes_num / us;
+
+ return bit_rate;
+}
+
+static int
+stress_disc_dsc_fn(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ uint16_t chr_val_handle,
+ const struct ble_gatt_dsc *dsc,
+ void *arg)
+{
+ struct stress_gatt_search_ctx *search_ctx;
+ static bool found = false;
+
+ search_ctx = (struct stress_gatt_search_ctx *) arg;
+
+ if (error->status == 0) {
+ if (!ble_uuid_cmp(&dsc->uuid.u, &search_ctx->dsc_uuid.u) && !found) {
+ MODLOG_DFLT(INFO, "Found chr descriptor\n");
+ search_ctx->dsc_handle = dsc->handle;
+ MODLOG_DFLT(INFO, "uuid=%#06x; handle=%#06x", dsc->uuid.u16.value,
+ dsc->handle);
+ found = true;
+ }
+ return 0;
+ }
+
+ if (error->status == BLE_HS_EDONE) {
+ MODLOG_DFLT(INFO, "Done descriptor discovery\n");
+
+ if (found) {
+ found = false;
+ search_ctx->disc_end_fn(search_ctx);
+ return 0;
+ }
+
+ MODLOG_DFLT(ERROR, "\033[0;31mDid not find particular descriptor"
+ "\033[0m\n");
+ return 0;
+ }
+
+ MODLOG_DFLT(ERROR, "\033[0;31mError during descriptor discovery"
+ "\033[0m\n");
+ assert(0);
+ return 0;
+}
+
+static int
+stress_disc_chr_fn(uint16_t conn_handle,
+ const struct ble_gatt_error *error,
+ const struct ble_gatt_chr *chr, void *arg)
+{
+ int rc;
+ struct stress_gatt_search_ctx *search_ctx;
+ static bool found = false;
+
+ search_ctx = (struct stress_gatt_search_ctx *) arg;
+
+ if (error->status == 0) {
+ MODLOG_DFLT(INFO, "Found characteristic\n");
+ search_ctx->chr_start_handle = chr->val_handle;
+ found = true;
+ return 0;
+ }
+
+ if (error->status == BLE_HS_EDONE) {
+ MODLOG_DFLT(INFO, "Done characteristic discovery\n");
+
+ if (found) {
+ found = false;
+
+ if (search_ctx->search_goal == STRESS_FIND_CHR) {
+ search_ctx->disc_end_fn(search_ctx);
+ return 0;
+ }
+
+ rc = ble_gattc_disc_all_dscs(conn_handle,
+ search_ctx->chr_start_handle,
+ search_ctx->srv_end_handle,
+ &stress_disc_dsc_fn, search_ctx);
+ assert(rc == 0);
+ return 0;
+ }
+
+ MODLOG_DFLT(ERROR, "\033[0;31mDid not find particular "
+ "characteristic\033[0m\n");
+ return 0;
+ }
+
+ MODLOG_DFLT(ERROR,
+ "\033[0;31mError during characteristic discovery\033[0m\n");
+ assert(0);
+ return 0;
+}
+
+static int
+stress_disc_svc_fn(uint16_t conn_handle, const struct ble_gatt_error *error,
+ const struct ble_gatt_svc *service, void *arg)
+{
+ int rc;
+ struct stress_gatt_search_ctx *search_ctx = NULL;
+ static bool found = false;
+
+ search_ctx = (struct stress_gatt_search_ctx *) arg;
+
+ if (error->status == 0) {
+ MODLOG_DFLT(INFO, "Found service\n");
+ search_ctx->srv_start_handle = service->start_handle;
+ search_ctx->srv_end_handle = service->end_handle;
+ found = true;
+ return 0;
+ }
+
+ if (error->status == BLE_HS_EDONE) {
+ MODLOG_DFLT(INFO, "Done service discovery\n");
+
+ if (found) {
+ found = false;
+ if (search_ctx->search_goal == STRESS_FIND_SRV) {
+ search_ctx->disc_end_fn(search_ctx);
+ return 0;
+ }
+
+ rc = ble_gattc_disc_chrs_by_uuid(conn_handle,
+ search_ctx->srv_start_handle,
+ search_ctx->srv_end_handle,
+ &search_ctx->chr_uuid.u,
+ &stress_disc_chr_fn,
+ search_ctx);
+ MODLOG_DFLT(INFO, "rc=%d\n", rc);
+ assert(rc == 0);
+ return 0;
+ }
+
+ MODLOG_DFLT(ERROR,
+ "\033[0;31mDid not find particular service\033[0m\n");
+ return 0;
+ }
+
+ MODLOG_DFLT(ERROR, "\033[0;31mError during service discovery\033[0m\n");
+ assert(0);
+ return 0;
+}
+
+static void
+stress_gatt_find_handle(uint16_t conn_handle, const ble_uuid_t *srv_uuid,
+ const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid,
+ stress_gatt_disc_end_fn *disc_end_fn,
+ uint8_t search_goal)
+{
+ static struct stress_gatt_search_ctx search_ctx;
+ int rc;
+
+ search_ctx.conn_handle = conn_handle;
+ ble_uuid_copy((ble_uuid_any_t *) &search_ctx.srv_uuid, srv_uuid);
+ ble_uuid_copy((ble_uuid_any_t *) &search_ctx.chr_uuid, chr_uuid);
+ ble_uuid_copy((ble_uuid_any_t *) &search_ctx.dsc_uuid, dsc_uuid);
+ search_ctx.disc_end_fn = disc_end_fn;
+ search_ctx.search_goal = search_goal;
+ search_ctx.srv_start_handle = 0;
+ search_ctx.srv_end_handle = 0;
+ search_ctx.chr_start_handle = 0;
+ search_ctx.dsc_handle = 0;
+
+ rc = ble_gattc_disc_svc_by_uuid(conn_handle, srv_uuid, &stress_disc_svc_fn,
+ &search_ctx);
+ assert(rc == 0);
+}
+
+void
+stress_find_svc_handle(uint16_t conn_handle, const ble_uuid_t *srv_uuid,
+ stress_gatt_disc_end_fn *disc_end_fn)
+{
+ stress_gatt_find_handle(conn_handle, srv_uuid, NULL, NULL, disc_end_fn,
+ STRESS_FIND_SRV);
+}
+
+void
+stress_find_chr_handle(uint16_t conn_handle, const ble_uuid_t *srv_uuid,
+ const ble_uuid_t *chr_uuid,
+ stress_gatt_disc_end_fn *disc_end_fn)
+{
+ stress_gatt_find_handle(conn_handle, srv_uuid, chr_uuid, NULL, disc_end_fn,
+ STRESS_FIND_CHR);
+}
+
+void
+stress_find_dsc_handle(uint16_t conn_handle, const ble_uuid_t *srv_uuid,
+ const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid,
+ stress_gatt_disc_end_fn *disc_end_fn)
+{
+ stress_gatt_find_handle(conn_handle, srv_uuid, chr_uuid, dsc_uuid,
+ disc_end_fn, STRESS_FIND_DSC);
+}