@@ -4858,64 +4858,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,
@@ -5037,8 +5142,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" },
{ } },
};