| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2020 Google LLC
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <string.h>
- #include "gdbus/gdbus.h"
- #include "src/shared/ad.h"
- #include "src/shared/util.h"
- #include "src/shared/shell.h"
- #include "adv_monitor.h"
- #define ADV_MONITOR_APP_PATH "/org/bluez/adv_monitor_app"
- #define ADV_MONITOR_INTERFACE "org.bluez.AdvertisementMonitor1"
- #define RSSI_UNSET_THRESHOLD 127
- #define RSSI_UNSET_TIMEOUT 0
- #define RSSI_UNSET_SAMPLING_PERIOD 256
- struct rssi_setting {
- int16_t high_threshold;
- uint16_t high_timeout;
- int16_t low_threshold;
- uint16_t low_timeout;
- uint16_t sampling_period;
- };
- struct pattern {
- uint8_t start_pos;
- uint8_t ad_data_type;
- uint8_t content_len;
- uint8_t content[BT_AD_MAX_DATA_LEN];
- };
- struct adv_monitor {
- uint8_t idx;
- char *path;
- char *type;
- struct rssi_setting *rssi;
- GSList *patterns;
- };
- static struct adv_monitor_manager {
- GSList *supported_types;
- GSList *supported_features;
- GDBusProxy *proxy;
- gboolean app_registered;
- } manager = { NULL, NULL, NULL, FALSE };
- static uint8_t adv_mon_idx;
- static GSList *adv_mons;
- static struct rssi_setting *current_rssi;
- static void remove_adv_monitor(void *data, void *user_data);
- static DBusMessage *release_adv_monitor(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- bt_shell_printf("Advertisement monitor %d released\n",
- adv_monitor->idx);
- remove_adv_monitor(adv_monitor, conn);
- return dbus_message_new_method_return(msg);
- }
- static DBusMessage *activate_adv_monitor(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- bt_shell_printf("Advertisement monitor %d activated\n",
- adv_monitor->idx);
- return dbus_message_new_method_return(msg);
- }
- static DBusMessage *device_found_adv_monitor(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- const char *device;
- dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
- DBUS_TYPE_INVALID);
- bt_shell_printf("Advertisement monitor %d found device %s\n",
- adv_monitor->idx, device);
- return dbus_message_new_method_return(msg);
- }
- static DBusMessage *device_lost_adv_monitor(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- const char *device;
- dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
- DBUS_TYPE_INVALID);
- bt_shell_printf("Advertisement monitor %d lost device %s\n",
- adv_monitor->idx, device);
- return dbus_message_new_method_return(msg);
- }
- static const GDBusMethodTable adv_monitor_methods[] = {
- { GDBUS_ASYNC_METHOD("Release", NULL, NULL, release_adv_monitor) },
- { GDBUS_ASYNC_METHOD("Activate", NULL, NULL, activate_adv_monitor) },
- { GDBUS_ASYNC_METHOD("DeviceFound", GDBUS_ARGS({ "device", "o" }),
- NULL, device_found_adv_monitor) },
- { GDBUS_ASYNC_METHOD("DeviceLost", GDBUS_ARGS({ "device", "o" }),
- NULL, device_lost_adv_monitor) },
- { }
- };
- static gboolean get_type(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
- &adv_monitor->type);
- return TRUE;
- }
- static gboolean get_low_threshold(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- struct rssi_setting *rssi = adv_monitor->rssi;
- dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16,
- &rssi->low_threshold);
- return TRUE;
- }
- static gboolean get_high_threshold(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- struct rssi_setting *rssi = adv_monitor->rssi;
- dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16,
- &rssi->high_threshold);
- return TRUE;
- }
- static gboolean get_low_timeout(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- struct rssi_setting *rssi = adv_monitor->rssi;
- dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
- &rssi->low_timeout);
- return TRUE;
- }
- static gboolean get_high_timeout(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- struct rssi_setting *rssi = adv_monitor->rssi;
- dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
- &rssi->high_timeout);
- return TRUE;
- }
- static gboolean get_sampling_period(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- struct rssi_setting *rssi = adv_monitor->rssi;
- dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
- &rssi->sampling_period);
- return TRUE;
- }
- static gboolean low_threshold_exists(const GDBusPropertyTable *property,
- void *data)
- {
- struct adv_monitor *adv_monitor = data;
- return adv_monitor->rssi != NULL &&
- adv_monitor->rssi->low_threshold != RSSI_UNSET_THRESHOLD;
- }
- static gboolean high_threshold_exists(const GDBusPropertyTable *property,
- void *data)
- {
- struct adv_monitor *adv_monitor = data;
- return adv_monitor->rssi != NULL &&
- adv_monitor->rssi->high_threshold != RSSI_UNSET_THRESHOLD;
- }
- static gboolean low_timeout_exists(const GDBusPropertyTable *property,
- void *data)
- {
- struct adv_monitor *adv_monitor = data;
- return adv_monitor->rssi != NULL &&
- adv_monitor->rssi->low_timeout != RSSI_UNSET_TIMEOUT;
- }
- static gboolean high_timeout_exists(const GDBusPropertyTable *property,
- void *data)
- {
- struct adv_monitor *adv_monitor = data;
- return adv_monitor->rssi != NULL &&
- adv_monitor->rssi->high_timeout != RSSI_UNSET_TIMEOUT;
- }
- static gboolean sampling_period_exists(const GDBusPropertyTable *property,
- void *data)
- {
- struct adv_monitor *adv_monitor = data;
- return adv_monitor->rssi != NULL &&
- adv_monitor->rssi->sampling_period !=
- RSSI_UNSET_SAMPLING_PERIOD;
- }
- static void append_pattern_content_to_dbus(DBusMessageIter *iter,
- struct pattern *pattern)
- {
- DBusMessageIter data_iter;
- int idx;
- dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING, &data_iter);
- for (idx = 0; idx < pattern->content_len; idx++)
- dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_BYTE,
- &pattern->content[idx]);
- dbus_message_iter_close_container(iter, &data_iter);
- }
- static void append_pattern_to_dbus(void *data, void *user_data)
- {
- struct pattern *pattern = data;
- DBusMessageIter *array_iter = user_data;
- DBusMessageIter data_iter;
- dbus_message_iter_open_container(array_iter, DBUS_TYPE_STRUCT,
- NULL, &data_iter);
- dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_BYTE,
- &pattern->start_pos);
- dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_BYTE,
- &pattern->ad_data_type);
- append_pattern_content_to_dbus(&data_iter, pattern);
- dbus_message_iter_close_container(array_iter, &data_iter);
- }
- static gboolean get_patterns(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- DBusMessageIter array_iter;
- dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "(yyay)",
- &array_iter);
- g_slist_foreach(adv_monitor->patterns, append_pattern_to_dbus,
- &array_iter);
- dbus_message_iter_close_container(iter, &array_iter);
- return TRUE;
- }
- static gboolean pattern_exists(const GDBusPropertyTable *property, void *data)
- {
- struct adv_monitor *adv_monitor = data;
- return adv_monitor->patterns != NULL;
- }
- static const GDBusPropertyTable adv_monitor_props[] = {
- { "Type", "s", get_type },
- { "RSSILowThreshold", "n", get_low_threshold, NULL,
- low_threshold_exists },
- { "RSSIHighThreshold", "n", get_high_threshold, NULL,
- high_threshold_exists },
- { "RSSILowTimeout", "q", get_low_timeout, NULL, low_timeout_exists },
- { "RSSIHighTimeout", "q", get_high_timeout, NULL, high_timeout_exists },
- { "RSSISamplingPeriod", "q", get_sampling_period, NULL,
- sampling_period_exists },
- { "Patterns", "a(yyay)", get_patterns, NULL, pattern_exists },
- { }
- };
- static void set_supported_list(GSList **list, DBusMessageIter *iter)
- {
- char *str;
- DBusMessageIter subiter;
- dbus_message_iter_recurse(iter, &subiter);
- while (dbus_message_iter_get_arg_type(&subiter) ==
- DBUS_TYPE_STRING) {
- dbus_message_iter_get_basic(&subiter, &str);
- *list = g_slist_append(*list, str);
- dbus_message_iter_next(&subiter);
- }
- }
- void adv_monitor_add_manager(DBusConnection *conn, GDBusProxy *proxy)
- {
- DBusMessageIter iter;
- if (manager.proxy != NULL || manager.supported_types != NULL ||
- manager.supported_features != NULL) {
- bt_shell_printf("advertisement monitor manager already "
- "added\n");
- return;
- }
- manager.proxy = proxy;
- if (g_dbus_proxy_get_property(proxy, "SupportedMonitorTypes", &iter))
- set_supported_list(&(manager.supported_types), &iter);
- if (g_dbus_proxy_get_property(proxy, "SupportedFeatures", &iter))
- set_supported_list(&(manager.supported_features), &iter);
- }
- void adv_monitor_remove_manager(DBusConnection *conn)
- {
- if (manager.supported_types != NULL) {
- g_slist_free(manager.supported_types);
- manager.supported_types = NULL;
- }
- if (manager.supported_features != NULL) {
- g_slist_free(manager.supported_features);
- manager.supported_features = NULL;
- }
- manager.proxy = NULL;
- manager.app_registered = FALSE;
- g_free(current_rssi);
- current_rssi = NULL;
- }
- static void register_setup(DBusMessageIter *iter, void *user_data)
- {
- const char *path = "/";
- dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
- }
- static void register_reply(DBusMessage *message, void *user_data)
- {
- DBusError error;
- dbus_error_init(&error);
- if (!dbus_set_error_from_message(&error, message)) {
- bt_shell_printf("AdvertisementMonitor path registered\n");
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- bt_shell_printf("Failed to register path: %s\n", error.name);
- dbus_error_free(&error);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- static void unregister_setup(DBusMessageIter *iter, void *user_data)
- {
- const char *path = "/";
- dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
- }
- static void unregister_reply(DBusMessage *message, void *user_data)
- {
- DBusError error;
- dbus_error_init(&error);
- if (!dbus_set_error_from_message(&error, message)) {
- bt_shell_printf("AdvertisementMonitor path unregistered\n");
- return bt_shell_noninteractive_quit(EXIT_SUCCESS);
- }
- bt_shell_printf("Failed to unregister Advertisement Monitor:"
- " %s\n", error.name);
- dbus_error_free(&error);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- void adv_monitor_register_app(DBusConnection *conn)
- {
- if (manager.app_registered) {
- bt_shell_printf("Advertisement Monitor already registered\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- } else if (manager.supported_types == NULL ||
- !g_dbus_proxy_method_call(manager.proxy, "RegisterMonitor",
- register_setup, register_reply,
- NULL, NULL)) {
- bt_shell_printf("Failed to register Advertisement Monitor\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- manager.app_registered = TRUE;
- }
- void adv_monitor_unregister_app(DBusConnection *conn)
- {
- if (!manager.app_registered) {
- bt_shell_printf("Advertisement Monitor not registered\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- } else if (!g_dbus_proxy_method_call(manager.proxy, "UnregisterMonitor",
- unregister_setup, unregister_reply,
- NULL, NULL)) {
- bt_shell_printf("Failed to unregister Advertisement Monitor\n");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- manager.app_registered = FALSE;
- }
- static void free_pattern(void *user_data)
- {
- struct pattern *p = user_data;
- g_free(p);
- }
- static void free_adv_monitor(void *user_data)
- {
- struct adv_monitor *adv_monitor = user_data;
- g_free(adv_monitor->path);
- g_free(adv_monitor->type);
- g_free(adv_monitor->rssi);
- g_slist_free_full(adv_monitor->patterns, free_pattern);
- g_free(adv_monitor);
- }
- static uint8_t str2bytearray(char *str, uint8_t *arr)
- {
- int idx, len = strlen(str), arr_len = 0;
- if (len%2 != 0)
- return 0;
- for (idx = 0; idx < len; idx += 2) {
- if (sscanf(str+idx, "%2hhx", &arr[arr_len++]) < 1)
- return 0;
- }
- return arr_len;
- }
- static struct pattern *parse_pattern(char *parameter_list[])
- {
- struct pattern *pat;
- pat = g_malloc0(sizeof(struct pattern));
- if (!pat) {
- bt_shell_printf("Failed to allocate pattern\n");
- bt_shell_noninteractive_quit(EXIT_FAILURE);
- return NULL;
- }
- pat->start_pos = atoi(parameter_list[0]);
- pat->ad_data_type = atoi(parameter_list[1]);
- pat->content_len = str2bytearray(parameter_list[2], pat->content);
- if (pat->content_len == 0) {
- free_pattern(pat);
- return NULL;
- }
- return pat;
- }
- static GSList *parse_patterns(char *pattern_list[], int num)
- {
- GSList *patterns = NULL;
- int cnt;
- if (num == 0) {
- bt_shell_printf("No pattern provided\n");
- return NULL;
- }
- if (num%3) {
- bt_shell_printf("Expected %d more arguments\n", 3 - num%3);
- return NULL;
- }
- for (cnt = 0; cnt < num; cnt += 3) {
- struct pattern *pattern;
- pattern = parse_pattern(pattern_list+cnt);
- if (pattern == NULL) {
- g_slist_free_full(patterns, free_pattern);
- return NULL;
- }
- patterns = g_slist_append(patterns, pattern);
- }
- return patterns;
- }
- static void remove_adv_monitor(void *data, void *user_data)
- {
- struct adv_monitor *adv_monitor = data;
- DBusConnection *conn = user_data;
- adv_mons = g_slist_remove(adv_mons, adv_monitor);
- g_dbus_unregister_interface(conn, adv_monitor->path,
- ADV_MONITOR_INTERFACE);
- }
- static gint cmp_adv_monitor_with_idx(gconstpointer a, gconstpointer b)
- {
- const struct adv_monitor *adv_monitor = a;
- uint8_t idx = *(uint8_t *)b;
- return adv_monitor->idx != idx;
- }
- static struct adv_monitor *find_adv_monitor_with_idx(uint8_t monitor_idx)
- {
- GSList *list;
- list = g_slist_find_custom(adv_mons, &monitor_idx,
- cmp_adv_monitor_with_idx);
- if (list)
- return (struct adv_monitor *)list->data;
- return NULL;
- }
- static void print_bytearray(char *prefix, uint8_t *arr, uint8_t len)
- {
- int idx;
- bt_shell_printf("%s", prefix);
- for (idx = 0; idx < len; idx++)
- bt_shell_printf("%02hhx", arr[idx]);
- bt_shell_printf("\n");
- }
- static void print_adv_monitor(struct adv_monitor *adv_monitor)
- {
- GSList *l;
- bt_shell_printf("Advertisement Monitor %d\n", adv_monitor->idx);
- bt_shell_printf("\tpath: %s\n", adv_monitor->path);
- bt_shell_printf("\ttype: %s\n", adv_monitor->type);
- if (adv_monitor->rssi) {
- bt_shell_printf("\trssi:\n");
- bt_shell_printf("\t\thigh threshold: %hd\n",
- adv_monitor->rssi->high_threshold);
- bt_shell_printf("\t\thigh threshold timeout: %hu\n",
- adv_monitor->rssi->high_timeout);
- bt_shell_printf("\t\tlow threshold: %hd\n",
- adv_monitor->rssi->low_threshold);
- bt_shell_printf("\t\tlow threshold timeout: %hu\n",
- adv_monitor->rssi->low_timeout);
- bt_shell_printf("\t\tsampling period: %hu\n",
- adv_monitor->rssi->sampling_period);
- }
- if (adv_monitor->patterns) {
- int idx = 1;
- for (l = adv_monitor->patterns; l; l = g_slist_next(l), idx++) {
- struct pattern *pattern = l->data;
- bt_shell_printf("\tpattern %d:\n", idx);
- bt_shell_printf("\t\tstart position: %hhu\n",
- pattern->start_pos);
- bt_shell_printf("\t\tAD data type: %hhu\n",
- pattern->ad_data_type);
- print_bytearray("\t\tcontent: ", pattern->content,
- pattern->content_len);
- }
- }
- }
- static struct rssi_setting *get_current_rssi(void)
- {
- if (current_rssi)
- return current_rssi;
- current_rssi = g_malloc0(sizeof(struct rssi_setting));
- if (!current_rssi)
- bt_shell_printf("Failed to allocate rssi setting");
- current_rssi->low_threshold = RSSI_UNSET_THRESHOLD;
- current_rssi->high_threshold = RSSI_UNSET_THRESHOLD;
- current_rssi->low_timeout = RSSI_UNSET_TIMEOUT;
- current_rssi->high_timeout = RSSI_UNSET_TIMEOUT;
- current_rssi->sampling_period = RSSI_UNSET_SAMPLING_PERIOD;
- return current_rssi;
- }
- void adv_monitor_set_rssi_threshold(int16_t low_threshold,
- int16_t high_threshold)
- {
- struct rssi_setting *rssi = get_current_rssi();
- if (!rssi)
- return;
- rssi->low_threshold = low_threshold;
- rssi->high_threshold = high_threshold;
- }
- void adv_monitor_set_rssi_timeout(uint16_t low_timeout, uint16_t high_timeout)
- {
- struct rssi_setting *rssi = get_current_rssi();
- if (!rssi)
- return;
- rssi->low_timeout = low_timeout;
- rssi->high_timeout = high_timeout;
- }
- void adv_monitor_set_rssi_sampling_period(uint16_t sampling)
- {
- struct rssi_setting *rssi = get_current_rssi();
- if (!rssi)
- return;
- rssi->sampling_period = sampling;
- }
- void adv_monitor_add_monitor(DBusConnection *conn, char *type,
- int argc, char *argv[])
- {
- struct adv_monitor *adv_monitor;
- GSList *patterns = NULL;
- if (g_slist_length(adv_mons) >= UINT8_MAX) {
- bt_shell_printf("Number of advertisement monitor exceeds "
- "the limit");
- return;
- }
- while (find_adv_monitor_with_idx(adv_mon_idx))
- adv_mon_idx += 1;
- patterns = parse_patterns(argv+1, argc-1);
- if (patterns == NULL) {
- bt_shell_printf("pattern-list malformed\n");
- return;
- }
- adv_monitor = g_malloc0(sizeof(struct adv_monitor));
- if (!adv_monitor) {
- bt_shell_printf("Failed to allocate adv_monitor");
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- adv_monitor->idx = adv_mon_idx;
- adv_monitor->type = g_strdup(type);
- adv_monitor->rssi = current_rssi;
- adv_monitor->patterns = patterns;
- adv_monitor->path = g_strdup_printf("%s/%hhu", ADV_MONITOR_APP_PATH,
- adv_mon_idx);
- current_rssi = NULL;
- if (g_dbus_register_interface(conn, adv_monitor->path,
- ADV_MONITOR_INTERFACE,
- adv_monitor_methods, NULL,
- adv_monitor_props, adv_monitor,
- free_adv_monitor) == FALSE) {
- bt_shell_printf("Failed to register advertisement monitor\n");
- free_adv_monitor(adv_monitor);
- return bt_shell_noninteractive_quit(EXIT_FAILURE);
- }
- adv_mons = g_slist_append(adv_mons, adv_monitor);
- bt_shell_printf("Advertisement Monitor %d added\n", adv_monitor->idx);
- }
- void adv_monitor_print_monitor(DBusConnection *conn, int monitor_idx)
- {
- struct adv_monitor *adv_monitor;
- GSList *l;
- if (monitor_idx < 0) {
- for (l = adv_mons; l; l = g_slist_next(l)) {
- adv_monitor = l->data;
- print_adv_monitor(adv_monitor);
- }
- return;
- }
- adv_monitor = find_adv_monitor_with_idx(monitor_idx);
- if (adv_monitor == NULL) {
- bt_shell_printf("Can't find monitor with index %d\n",
- monitor_idx);
- return;
- }
- print_adv_monitor(adv_monitor);
- }
- void adv_monitor_remove_monitor(DBusConnection *conn, int monitor_idx)
- {
- struct adv_monitor *adv_monitor;
- if (monitor_idx < 0) {
- g_slist_foreach(adv_mons, remove_adv_monitor, conn);
- return;
- }
- adv_monitor = find_adv_monitor_with_idx(monitor_idx);
- if (adv_monitor == NULL) {
- bt_shell_printf("Can't find monitor with index %d\n",
- monitor_idx);
- return;
- }
- remove_adv_monitor(adv_monitor, conn);
- bt_shell_printf("Monitor %d deleted\n", monitor_idx);
- }
- static void print_supported_list(GSList *list)
- {
- GSList *iter;
- for (iter = list; iter; iter = g_slist_next(iter)) {
- char *data = iter->data;
- printf(" %s", data);
- }
- }
- void adv_monitor_get_supported_info(void)
- {
- bt_shell_printf("Supported Features:");
- print_supported_list(manager.supported_features);
- bt_shell_printf("\n");
- bt_shell_printf("Supported Moniter Types:");
- print_supported_list(manager.supported_types);
- bt_shell_printf("\n");
- }
|