btmgmt: advmon add rssi support
authorArchie Pusaka <apusaka@chromium.org>
Fri, 15 Jan 2021 11:50:41 +0000 (19:50 +0800)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:34 +0000 (19:08 +0530)
Using the new opcode MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI to
monitor advertisement according to some RSSI criteria.

Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
tools/btmgmt.c

index 3cbdd9c..3d1a604 100755 (executable)
@@ -4859,64 +4859,169 @@ static bool str2pattern(struct mgmt_adv_pattern *pattern, const char *str)
        return true;
 }
 
-static void advmon_add_usage(void)
+static struct option add_monitor_rssi_options[] = {
+       { "help",               0, 0, 'h' },
+       { "high-threshold",     1, 0, 'R' },
+       { "low-threshold",      1, 0, 'r' },
+       { "high-timeout",       1, 0, 'T' },
+       { "low-timeout",        1, 0, 't' },
+       { "sampling",           1, 0, 's' },
+       { 0, 0, 0, 0 }
+};
+
+static void advmon_add_pattern_usage(void)
+{
+       bt_shell_usage();
+       print("patterns format:\n"
+               "\t<ad_type:offset:pattern> [patterns]\n"
+               "e.g.:\n"
+               "\tadd-pattern 0:1:c504 ff:a:9a55beef");
+}
+
+static void advmon_add_pattern_rssi_usage(void)
 {
        bt_shell_usage();
-       print("Monitor Types:\n\t-p <ad_type:offset:pattern>..."
-               "\tPattern Monitor\ne.g.:\n\tadd -p 0:1:c504 1:a:9a55beef");
+       print("RSSI options:\n"
+               "\t -R, --high-threshold <dBm>  "
+                       "RSSI high threshold. Default: -70\n"
+               "\t -r, --low-threshold <dBm>   "
+                       "RSSI low threshold. Default: -50\n"
+               "\t -T, --high-timeout <s>      "
+                       "RSSI high threshold duration. Default: 0\n"
+               "\t -t, --low-timeout <s>       "
+                       "RSSI low threshold duration. Default: 5\n"
+               "\t -s, --sampling <N * 100ms>  "
+                       "RSSI sampling period. Default: 0\n"
+               "patterns format:\n"
+               "\t<ad_type:offset:pattern> [patterns]\n"
+               "e.g.:\n"
+               "\tadd-pattern-rssi -R 0xb2 -r -102 0:1:c504 ff:a:9a55beef");
 }
 
-static bool advmon_add_pattern(int argc, char **argv)
+static void cmd_advmon_add_pattern(int argc, char **argv)
 {
+       bool success = true;
        uint16_t index;
        int i, cp_len;
        struct mgmt_cp_add_adv_monitor *cp = NULL;
-       bool success = false;
 
-       index = mgmt_index;
-       if (index == MGMT_INDEX_NONE)
-               index = 0;
+       if (!strcmp(argv[1], "-h"))
+               goto done;
 
-       cp_len = sizeof(struct mgmt_cp_add_adv_monitor) +
-                       argc * sizeof(struct mgmt_adv_pattern);
+       argc -= 1;
+       argv += 1;
 
+       cp_len = sizeof(*cp) + argc * sizeof(struct mgmt_adv_pattern);
        cp = malloc0(cp_len);
        cp->pattern_count = argc;
 
        for (i = 0; i < argc; i++) {
                if (!str2pattern(&cp->patterns[i], argv[i])) {
                        error("Failed to parse monitor patterns.");
+                       success = false;
                        goto done;
                }
        }
 
-       if (!mgmt_send(mgmt, MGMT_OP_ADD_ADV_PATTERNS_MONITOR, index, cp_len,
-                                       cp, advmon_add_rsp, NULL, NULL)) {
-               error("Unable to send \"Add Advertising Monitor\" command");
+       index = mgmt_index;
+       if (index == MGMT_INDEX_NONE)
+               index = 0;
+
+       if (!mgmt_send(mgmt, MGMT_OP_ADD_ADV_PATTERNS_MONITOR, index,
+                               cp_len, cp, advmon_add_rsp, NULL, NULL)) {
+               error("Unable to send Add Advertising Monitor command");
+               success = false;
                goto done;
        }
 
-       success = true;
+       free(cp);
+       return;
 
 done:
        free(cp);
-       return success;
+       advmon_add_pattern_usage();
+       bt_shell_noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
-static void cmd_advmon_add(int argc, char **argv)
+static void cmd_advmon_add_pattern_rssi(int argc, char **argv)
 {
-       bool success = false;
+       bool success = true;
+       int opt;
+       int8_t rssi_low = -70;
+       int8_t rssi_high = -50;
+       uint16_t rssi_low_timeout = 5;
+       uint16_t rssi_high_timeout = 0;
+       uint8_t rssi_sampling_period = 0;
+       uint16_t index;
+       int i, cp_len;
+       struct mgmt_cp_add_adv_patterns_monitor_rssi *cp = NULL;
 
-       if (strcasecmp(argv[1], "-p") == 0 && argc > 2) {
-               argc -= 2;
-               argv += 2;
-               success = advmon_add_pattern(argc, argv);
+       while ((opt = getopt_long(argc, argv, "+hr:R:t:T:s:",
+                               add_monitor_rssi_options, NULL)) != -1) {
+               switch (opt) {
+               case 'h':
+                       goto done;
+               case 'r':
+                       rssi_low = strtol(optarg, NULL, 0);
+                       break;
+               case 'R':
+                       rssi_high = strtol(optarg, NULL, 0);
+                       break;
+               case 't':
+                       rssi_low_timeout = strtol(optarg, NULL, 0);
+                       break;
+               case 'T':
+                       rssi_high_timeout = strtol(optarg, NULL, 0);
+                       break;
+               case 's':
+                       rssi_sampling_period = strtol(optarg, NULL, 0);
+                       break;
+               default:
+                       success = false;
+                       goto done;
+               }
        }
 
-       if (!success) {
-               advmon_add_usage();
-               bt_shell_noninteractive_quit(EXIT_FAILURE);
+       argc -= optind;
+       argv += optind;
+       optind = 0;
+
+       cp_len = sizeof(*cp) + argc * sizeof(struct mgmt_adv_pattern);
+       cp = malloc0(cp_len);
+       cp->pattern_count = argc;
+       cp->rssi.high_threshold = rssi_high;
+       cp->rssi.low_threshold = rssi_low;
+       cp->rssi.high_threshold_timeout = htobs(rssi_high_timeout);
+       cp->rssi.low_threshold_timeout = htobs(rssi_low_timeout);
+       cp->rssi.sampling_period = rssi_sampling_period;
+
+       for (i = 0; i < argc; i++) {
+               if (!str2pattern(&cp->patterns[i], argv[i])) {
+                       error("Failed to parse monitor patterns.");
+                       success = false;
+                       goto done;
+               }
+       }
+
+       index = mgmt_index;
+       if (index == MGMT_INDEX_NONE)
+               index = 0;
+
+       if (!mgmt_send(mgmt, MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, index,
+                               cp_len, cp, advmon_add_rsp, NULL, NULL)) {
+               error("Unable to send Add Advertising Monitor RSSI command");
+               success = false;
+               goto done;
        }
+
+       free(cp);
+       return;
+
+done:
+       free(cp);
+       optind = 0;
+       advmon_add_pattern_rssi_usage();
+       bt_shell_noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
 static void advmon_remove_rsp(uint8_t status, uint16_t len, const void *param,
@@ -5038,8 +5143,11 @@ static const struct bt_shell_menu monitor_menu = {
                                        "features"                      },
        { "remove",             "<handle>",
                cmd_advmon_remove,      "Remove advertisement monitor " },
-       { "add",                "<-p|-h> [options...]",
-               cmd_advmon_add,         "Add advertisement monitor"     },
+       { "add-pattern",        "[-h] <patterns>",
+               cmd_advmon_add_pattern, "Add advertisement monitor pattern" },
+       { "add-pattern-rssi",   "[options] <patterns>",
+               cmd_advmon_add_pattern_rssi,
+               "Add advertisement monitor pattern with RSSI options"    },
        { } },
 };