@@ -4567,6 +4567,83 @@ static void cmd_wbs(int argc, char **argv)
cmd_setting(MGMT_OP_SET_WIDEBAND_SPEECH, argc, argv);
}
+static const char * const advmon_features_str[] = {
+ "Pattern monitor with logic OR.",
+};
+
+static const char *advmon_features2str(uint32_t features)
+{
+ static char str[512];
+ unsigned int off, i;
+
+ off = 0;
+ snprintf(str, sizeof(str), "\n\tNone");
+
+ for (i = 0; i < NELEM(advmon_features_str); i++) {
+ if ((features & (1 << i)) != 0 && off < sizeof(str))
+ off += snprintf(str + off, sizeof(str) - off, "\n\t%s",
+ advmon_features_str[i]);
+ }
+
+ return str;
+}
+
+static void advmon_features_rsp(uint8_t status, uint16_t len, const void *param,
+ void *user_data)
+{
+ const struct mgmt_rp_read_adv_monitor_features *rp = param;
+ uint32_t supported_features, enabled_features;
+ uint16_t num_handles;
+ int i;
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Reading adv monitor features failed with status 0x%02x "
+ "(%s)", status, mgmt_errstr(status));
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ if (len < sizeof(*rp)) {
+ error("Too small adv monitor features reply (%u bytes)", len);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ supported_features = le32_to_cpu(rp->supported_features);
+ enabled_features = le32_to_cpu(rp->enabled_features);
+ num_handles = le16_to_cpu(rp->num_handles);
+
+ if (len < sizeof(*rp) + num_handles * sizeof(uint16_t)) {
+ error("Handles count (%u) doesn't match reply length (%u)",
+ num_handles, len);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ print("Supported features:%s", advmon_features2str(supported_features));
+ print("Enabled features:%s", advmon_features2str(enabled_features));
+ print("Max number of handles: %u", le16_to_cpu(rp->max_num_handles));
+ print("Max number of patterns: %u", rp->max_num_patterns);
+ print("Handles list with %u item%s", num_handles,
+ num_handles == 0 ? "" : num_handles == 1 ? ":" : "s:");
+ for (i = 0; i < num_handles; i++)
+ print("\t0x%04x ", le16_to_cpu(rp->handles[i]));
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_advmon_features(int argc, char **argv)
+{
+ uint16_t index;
+
+ index = mgmt_index;
+ if (index == MGMT_INDEX_NONE)
+ index = 0;
+
+ if (!mgmt_send(mgmt, MGMT_OP_READ_ADV_MONITOR_FEATURES, index, 0, NULL,
+ advmon_features_rsp, NULL, NULL)) {
+ error("Unable to send advertising monitor features command");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+}
+
static void register_mgmt_callbacks(struct mgmt *mgmt, uint16_t index)
{
mgmt_register(mgmt, MGMT_EV_CONTROLLER_ERROR, index, controller_error,
@@ -4635,6 +4712,16 @@ static void cmd_select(int argc, char **argv)
update_prompt(mgmt_index);
}
+static const struct bt_shell_menu monitor_menu = {
+ .name = "monitor",
+ .desc = "Advertisement Monitor Submenu",
+ .entries = {
+ { "features", NULL,
+ cmd_advmon_features, "Show advertisement monitor "
+ "features" },
+ { } },
+};
+
static const struct bt_shell_menu main_menu = {
.name = "main",
.entries = {
@@ -4815,6 +4902,7 @@ int main(int argc, char *argv[])
bt_shell_init(argc, argv, &opt);
bt_shell_set_menu(&main_menu);
+ bt_shell_add_submenu(&monitor_menu);
mgmt = mgmt_new_default();
if (!mgmt) {