Support advertising monitor add pattern with RSSI opcode
Subsystems (2)
cover Support advertising monitor add pattern with RSSI opcode
From: Archie Pusaka <[email protected]>
Hi linux-bluetooth,
This series of patches adds a new MGMT command for adding a monitor with RSSI parameter. Changes are focused on passing parameters to the kernel via btmgmt and bluetoothctl.
PTAL and thanks for your feedback!
Archie
Archie Pusaka (5):
lib/mgmt: Adding Add Adv Patterns Monitor RSSI opcode. src/adv_monitor: add monitor with rssi support for mgmt
btmgmt: advmon add rssi support
bluetoothctl: advmon rssi support for mgmt
monitor: Decode add advmon with RSSI parameter
client/adv_monitor.c | 90 ++++++++++++------------ client/adv_monitor.h | 1 + client/main.c | 29 ++++---- lib/mgmt.h | 15 ++++ monitor/packet.c | 43 ++++++++++-- src/adv_monitor.c | 143 +++++++++++++++++++++++++++++--------- tools/btmgmt.c | 160 ++++++++++++++++++++++++++++++++++++------- 7 files changed, 357 insertions(+), 124 deletions(-)
Signature · 1 line
2.30.0.284.gd98b1dd5eaa7-goog
PATCH 1/5 lib/mgmt: Adding Add Adv Patterns Monitor RSSI opcode.
From: Archie Pusaka <[email protected]>
The new op is to utilize RSSI in advertisement monitor
---
lib/mgmt.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
lib/mgmt.h +15 -0
@@ -738,6 +738,21 @@ struct mgmt_rp_add_ext_adv_data {uint8_t instance; } __packed; +struct mgmt_adv_rssi_thresholds { +int8_t high_threshold; +uint16_t high_threshold_timeout; +int8_t low_threshold; +uint16_t low_threshold_timeout; +uint8_t sampling_period; +} __packed; + +#define MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI 0x0056 +struct mgmt_cp_add_adv_patterns_monitor_rssi { +uint8_t pattern_count; +struct mgmt_adv_rssi_thresholds rssi; +struct mgmt_adv_pattern patterns[0 ]; +} __packed; +#define MGMT_EV_CMD_COMPLETE 0x0001struct mgmt_ev_cmd_complete {uint16_t opcode;
Signature · 1 line
2.30.0.284.gd98b1dd5eaa7-goog
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=413687
---Test result---
##############################
Test: CheckPatch - PASS
##############################
Test: CheckGitLint - FAIL
Output:
lib/mgmt: Adding Add Adv Patterns Monitor RSSI opcode.
1: T3 Title has trailing punctuation (.): "lib/mgmt: Adding Add Adv Patterns Monitor RSSI opcode."
##############################
Test: CheckBuild - PASS
##############################
Test: MakeCheck - PASS
---
Regards,
Linux Bluetooth
PATCH 2/5 src/adv_monitor: add monitor with rssi support for mgmt
In reply to Archie PusakaFrom: Archie Pusaka <[email protected]>
Using the new opcode MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI to monitor advertisement according to some RSSI criteria.
---
src/adv_monitor.c | 143 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 110 insertions(+), 33 deletions(-)
src/adv_monitor.c +110 -33
@@ -44,6 +44,8 @@#define ADV_MONITOR_UNSET_TIMER 0/* second */ #define ADV_MONITOR_MIN_TIMER 1/* second */ #define ADV_MONITOR_MAX_TIMER 300/* second */ +#define ADV_MONITOR_UNSET_SAMPLING_PERIOD 256/* 100 ms */ +#define ADV_MONITOR_MAX_SAMPLING_PERIOD 255/* 100 ms */ struct btd_adv_monitor_manager {struct btd_adapter *adapter;
@@ -95,6 +97,10 @@ struct adv_monitor {uint16_t high_rssi_timeout;/* High RSSI threshold timeout */ int8_t low_rssi;/* Low RSSI threshold */ uint16_t low_rssi_timeout;/* Low RSSI threshold timeout */ +uint16_t sampling_period;/* Merge packets in the same timeslot. +* Currenly unimplemented in user space. +* Used only to pass data to kernel. +*/ struct queue *devices;/* List of adv_monitor_device objects */ enum monitor_type type;/* MONITOR_TYPE_* */
@@ -363,6 +369,7 @@ static struct adv_monitor *monitor_new(struct adv_monitor_app *app, monitor->high_rssi_timeout =ADV_MONITOR_UNSET_TIMER ; monitor->low_rssi =ADV_MONITOR_UNSET_RSSI ; monitor->low_rssi_timeout =ADV_MONITOR_UNSET_TIMER ; + monitor->sampling_period =ADV_MONITOR_UNSET_SAMPLING_PERIOD ; monitor->devices =queue_new (); monitor->type =MONITOR_TYPE_NONE ;
@@ -432,6 +439,7 @@ static bool parse_rssi_and_timeout(struct adv_monitor *monitor,DBusMessageIter prop_struct, iter;int16_t h_rssi, l_rssi;uint16_t h_rssi_timer, l_rssi_timer; +int16_t sampling_period;uint16_t adapter_id = monitor->app->manager->adapter_id;/* Property RSSIThresholdsAndTimers is optional */
@@ -473,6 +481,13 @@ static bool parse_rssi_and_timeout(struct adv_monitor *monitor,if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_UINT16 ) goto failed;dbus_message_iter_get_basic (&iter, &l_rssi_timer); +if (!dbus_message_iter_next (&iter)) + goto failed; + +/* Extract SamplingPeriod */ +if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_UINT16 ) + goto failed; +dbus_message_iter_get_basic (&iter, &sampling_period);/* Verify the values of RSSIs and their timers. For simplicity, we * enforce the all-or-none rule to these fields. In other words, either
@@ -481,7 +496,8 @@ static bool parse_rssi_and_timeout(struct adv_monitor *monitor,if (h_rssi ==ADV_MONITOR_UNSET_RSSI && l_rssi ==ADV_MONITOR_UNSET_RSSI && h_rssi_timer ==ADV_MONITOR_UNSET_TIMER && - l_rssi_timer ==ADV_MONITOR_UNSET_TIMER ) { + l_rssi_timer ==ADV_MONITOR_UNSET_TIMER && + sampling_period ==ADV_MONITOR_UNSET_SAMPLING_PERIOD ) { goto done; }
@@ -498,17 +514,22 @@ static bool parse_rssi_and_timeout(struct adv_monitor *monitor, goto failed; } +if (sampling_period >ADV_MONITOR_MAX_SAMPLING_PERIOD ) + goto failed; + monitor->high_rssi = h_rssi; monitor->low_rssi = l_rssi; monitor->high_rssi_timeout = h_rssi_timer; monitor->low_rssi_timeout = l_rssi_timer; + monitor->sampling_period = sampling_period; done:DBG ("Adv Monitor at %s initiated with high RSSI threshold %d, high " "RSSI threshold timeout %d, low RSSI threshold %d, low RSSI " -"threshold timeout %d" , path, monitor->high_rssi, - monitor->high_rssi_timeout, monitor->low_rssi, - monitor->low_rssi_timeout); +"threshold timeout %d, sampling period %d" , path, + monitor->high_rssi, monitor->high_rssi_timeout, + monitor->low_rssi, monitor->low_rssi_timeout, + monitor->sampling_period);return true;
@@ -517,6 +538,7 @@ failed: monitor->low_rssi =ADV_MONITOR_UNSET_RSSI ; monitor->high_rssi_timeout =ADV_MONITOR_UNSET_TIMER ; monitor->low_rssi_timeout =ADV_MONITOR_UNSET_TIMER ; + monitor->sampling_period =ADV_MONITOR_UNSET_SAMPLING_PERIOD ;btd_error (adapter_id, "Invalid argument of property RSSIThresholdsAndTimers "
@@ -673,16 +695,88 @@ static void add_adv_patterns_monitor_cb(uint8_t status, uint16_t length,DBG ("Adv monitor with handle:0x%04x added" , monitor->monitor_handle); } -static void monitor_copy_patterns (void *data,void *user_data) +static bool monitor_rssi_is_unset (struct adv_monitor *monitor) { -struct bt_ad_pattern *pattern = data; -struct mgmt_cp_add_adv_monitor *cp = user_data; +return monitor->high_rssi ==ADV_MONITOR_UNSET_RSSI && + monitor->low_rssi ==ADV_MONITOR_UNSET_RSSI && + monitor->high_rssi_timeout ==ADV_MONITOR_UNSET_TIMER && + monitor->low_rssi_timeout ==ADV_MONITOR_UNSET_TIMER && + monitor->low_rssi_timeout ==ADV_MONITOR_UNSET_TIMER ; +} -if (!pattern) -return ; +/* sends MGMT_OP_ADD_ADV_PATTERNS_MONITOR */ +static bool monitor_send_add_pattern (struct adv_monitor *monitor) +{ +struct mgmt_cp_add_adv_monitor *cp =NULL ; +uint8_t pattern_count, cp_len; +const struct queue_entry *e; +bool success = true; + + pattern_count =queue_length (monitor->patterns); + cp_len =sizeof (*cp) + pattern_count *sizeof (struct mgmt_adv_pattern ); + + cp =malloc0 (cp_len); +if (!cp) +return false; -memcpy (cp->patterns + cp->pattern_count, pattern,sizeof (*pattern)); - cp->pattern_count++; +for (e =queue_get_entries (monitor->patterns); e; e = e->next) { +struct bt_ad_pattern *pattern = e->data; + +memcpy (&cp->patterns[cp->pattern_count++], pattern, +sizeof (*pattern)); + } + +if (!mgmt_send (monitor->app->manager->mgmt, +MGMT_OP_ADD_ADV_PATTERNS_MONITOR , + monitor->app->manager->adapter_id, cp_len, cp, + add_adv_patterns_monitor_cb, monitor,NULL )) { +error ("Unable to send Add Adv Patterns Monitor command" ); + success = false; + } + +free (cp); +return success; +} + +/* sends MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI */ +static bool monitor_send_add_pattern_rssi (struct adv_monitor *monitor) +{ +struct mgmt_cp_add_adv_patterns_monitor_rssi *cp =NULL ; +uint8_t pattern_count, cp_len; +const struct queue_entry *e; +bool success = true; + + pattern_count =queue_length (monitor->patterns); + cp_len =sizeof (*cp) + pattern_count *sizeof (struct mgmt_adv_pattern ); + + cp =malloc0 (cp_len); +if (!cp) +return false; + + cp->rssi.high_threshold = monitor->high_rssi; +/* High threshold timeout is unsupported in kernel. Value must be 0. */ + cp->rssi.high_threshold_timeout =0 ; + cp->rssi.low_threshold = monitor->low_rssi; + cp->rssi.low_threshold_timeout =htobs (monitor->low_rssi_timeout); + cp->rssi.sampling_period = monitor->sampling_period; + +for (e =queue_get_entries (monitor->patterns); e; e = e->next) { +struct bt_ad_pattern *pattern = e->data; + +memcpy (&cp->patterns[cp->pattern_count++], pattern, +sizeof (*pattern)); + } + +if (!mgmt_send (monitor->app->manager->mgmt, +MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI , + monitor->app->manager->adapter_id, cp_len, cp, + add_adv_patterns_monitor_cb, monitor,NULL )) { +error ("Unable to send Add Adv Patterns Monitor RSSI command" ); + success = false; + } + +free (cp); +return success; }/* Handles an Adv Monitor D-Bus proxy added event */
@@ -690,8 +784,6 @@ static void monitor_proxy_added_cb(GDBusProxy *proxy, void *user_data) {struct adv_monitor *monitor;struct adv_monitor_app *app = user_data; -struct mgmt_cp_add_adv_monitor *cp =NULL ; -uint8_t pattern_count, cp_len;uint16_t adapter_id = app->manager->adapter_id;const char *path =g_dbus_proxy_get_path (proxy);const char *iface =g_dbus_proxy_get_interface (proxy);
@@ -725,24 +817,12 @@ static void monitor_proxy_added_cb(GDBusProxy *proxy, void *user_data)queue_push_tail (app->monitors, monitor); - pattern_count =queue_length (monitor->patterns); - cp_len =sizeof (struct mgmt_cp_add_adv_monitor ) + - pattern_count *sizeof (struct mgmt_adv_pattern ); - - cp =malloc0 (cp_len); -queue_foreach (monitor->patterns, monitor_copy_patterns, cp); - -if (!mgmt_send (app->manager->mgmt,MGMT_OP_ADD_ADV_PATTERNS_MONITOR , - adapter_id, cp_len, cp, add_adv_patterns_monitor_cb, - monitor,NULL )) { -error ("Unable to send Add Adv Patterns Monitor command" ); - goto done; - } +if (monitor_rssi_is_unset (monitor)) +monitor_send_add_pattern (monitor); +else +monitor_send_add_pattern_rssi (monitor);DBG ("Adv Monitor allocated for the object at path %s" , path); - -done: -free (cp); }/* Handles the removal of an Adv Monitor D-Bus proxy */
@@ -1428,10 +1508,7 @@ static void adv_monitor_filter_rssi(struct adv_monitor *monitor,* DeviceFound() event without tracking for the RSSI as the Adv has * already matched the pattern filter. */ -if (monitor->high_rssi ==ADV_MONITOR_UNSET_RSSI && - monitor->low_rssi ==ADV_MONITOR_UNSET_RSSI && - monitor->high_rssi_timeout ==ADV_MONITOR_UNSET_TIMER && - monitor->low_rssi_timeout ==ADV_MONITOR_UNSET_TIMER ) { +if (monitor_rssi_is_unset (monitor)) {DBG ("Calling DeviceFound() on Adv Monitor of owner %s " "at path %s" , monitor->app->owner, monitor->path);
Signature · 1 line
2.30.0.284.gd98b1dd5eaa7-goog
PATCH 3/5 btmgmt: advmon add rssi support
In reply to Archie PusakaFrom: Archie Pusaka <[email protected]>
Using the new opcode MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI to monitor advertisement according to some RSSI criteria.
---
tools/btmgmt.c | 160 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 134 insertions(+), 26 deletions(-)
tools/btmgmt.c +134 -26
@@ -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 (); +"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 (); -"Monitor Types:\n\t-p <ad_type:offset:pattern>..." -"\tPattern Monitor\ne.g.:\n\tadd -p 0:1:c504 1:a:9a55beef" ); +"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" }, { } }, };
Signature · 1 line
2.30.0.284.gd98b1dd5eaa7-goog
PATCH 4/5 bluetoothctl: advmon rssi support for mgmt
In reply to Archie PusakaFrom: Archie Pusaka <[email protected]>
Using the new opcode MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI to monitor advertisement according to some RSSI criteria.
---
client/adv_monitor.c | 90 ++++++++++++++++++++++---------------------- client/adv_monitor.h | 1 + client/main.c | 29 +++++++------- 3 files changed, 59 insertions(+), 61 deletions(-)
client/adv_monitor.c +45 -45
@@ -33,6 +33,7 @@ struct rssi_setting {uint16_t high_timer;int16_t low_threshold;uint16_t low_timer; +uint16_t sampling_period; };struct pattern {
@@ -148,6 +149,8 @@ static gboolean get_rssi(const GDBusPropertyTable *property, &rssi->low_threshold);dbus_message_iter_append_basic (&data_iter,DBUS_TYPE_UINT16 , &rssi->low_timer); +dbus_message_iter_append_basic (&data_iter,DBUS_TYPE_UINT16 , + &rssi->sampling_period);dbus_message_iter_close_container (iter, &data_iter);return TRUE; }
@@ -212,7 +215,7 @@ static gboolean pattern_exists(const GDBusPropertyTable *property, void *data)static const GDBusPropertyTable adv_monitor_props[] = { {"Type" ,"s" , get_type }, - {"RSSIThresholdsAndTimers" ,"(nqnq)" , get_rssi,NULL , rssi_exists }, + {"RSSIThresholdsAndTimers" ,"(nqnqq)" , get_rssi,NULL , rssi_exists }, {"Patterns" ,"a(yyay)" , get_patterns,NULL , pattern_exists }, { } };
@@ -376,56 +379,51 @@ static uint8_t str2bytearray(char *str, uint8_t *arr)return arr_len; } -static void parse_rssi_value_pair (char *value_pair,int *low,int *high) -{ -char *val1, *val2; -bool flag = value_pair[0 ] ==',' ; - - val1 =strtok (value_pair,"," ); - -if (!val1) -return ; - - val2 =strtok (NULL ,"," ); - -if (!val2) { -if (!flag) - *low =atoi (val1); -else - *high =atoi (val1); - }else { - *low =atoi (val1); - *high =atoi (val2); - } -} - -static struct rssi_setting *parse_rssi (char *range,char *timeout) +static struct rssi_setting *parse_rssi (char *params) {struct rssi_setting *rssi; -int high_threshold, low_threshold, high_timer, low_timer; - - high_threshold =RSSI_DEFAULT_HIGH_THRESHOLD ; - low_threshold =RSSI_DEFAULT_LOW_THRESHOLD ; - high_timer =RSSI_DEFAULT_HIGH_TIMEOUT ; - low_timer =RSSI_DEFAULT_LOW_TIMEOUT ; +char *split, *endptr; +int i; +int values[5 ] = {RSSI_DEFAULT_LOW_THRESHOLD , +RSSI_DEFAULT_HIGH_THRESHOLD , +RSSI_DEFAULT_LOW_TIMEOUT , +RSSI_DEFAULT_HIGH_TIMEOUT , +RSSI_DEFAULT_SAMPLING_PERIOD }; + +for (i =0 ; i <5 ; i++) { +if (!params)/* Params too short */ + goto bad_format; + + split =strsep (¶ms,"," ); +if (*split !='\0' ) { + values[i] =strtol (split, &endptr,0 ); +if (*endptr !='\0' )/* Conversion failed */ + goto bad_format; + }/* Otherwise no parsing needed - use default */ + } -parse_rssi_value_pair (range, &low_threshold, &high_threshold); -parse_rssi_value_pair (timeout, &low_timer, &high_timer); +if (params)/* There are trailing unused params */ + goto bad_format; rssi =g_malloc0 (sizeof (struct rssi_setting )); -if (!rssi) { -bt_shell_printf ("Failed to allocate rssi_setting" ); +bt_shell_printf ("Failed to allocate rssi_setting\n" );bt_shell_noninteractive_quit (EXIT_FAILURE );return NULL ; } - rssi->high_threshold = high_threshold; - rssi->high_timer = high_timer; - rssi->low_threshold = low_threshold; - rssi->low_timer = low_timer; + rssi->low_threshold = values[0 ]; + rssi->high_threshold = values[1 ]; + rssi->low_timer = values[2 ]; + rssi->high_timer = values[3 ]; + rssi->sampling_period = values[4 ];return rssi; + +bad_format: +bt_shell_printf ("Failed to parse RSSI\n" ); +bt_shell_noninteractive_quit (EXIT_FAILURE ); +return NULL ; }static struct pattern *parse_pattern (char *parameter_list[])
@@ -435,7 +433,7 @@ static struct pattern *parse_pattern(char *parameter_list[]) pat =g_malloc0 (sizeof (struct pattern ));if (!pat) { -bt_shell_printf ("Failed to allocate pattern" ); +bt_shell_printf ("Failed to allocate pattern\n" );bt_shell_noninteractive_quit (EXIT_FAILURE );return NULL ; }
@@ -537,6 +535,8 @@ static void print_adv_monitor(struct adv_monitor *adv_monitor) adv_monitor->rssi->low_threshold);bt_shell_printf ("\t\tlow threshold timer: %hu\n" , adv_monitor->rssi->low_timer); +bt_shell_printf ("\t\tsampling period: %hu\n" , + adv_monitor->rssi->sampling_period); }if (adv_monitor->patterns) {
@@ -572,15 +572,15 @@ void adv_monitor_add_monitor(DBusConnection *conn, char *type,while (find_adv_monitor_with_idx (adv_mon_idx)) adv_mon_idx +=1 ; -if (rssi_enabled == FALSE) +if (rssi_enabled == FALSE) { rssi =NULL ; -else { - rssi =parse_rssi (argv[1 ], argv[2 ]); + }else { + rssi =parse_rssi (argv[1 ]);if (rssi ==NULL )return ; - argv +=2 ; - argc -=2 ; + argv +=1 ; + argc -=1 ; } patterns =parse_patterns (argv+1 , argc-1 );
client/adv_monitor.h +1 -0
@@ -12,6 +12,7 @@#define RSSI_DEFAULT_LOW_THRESHOLD -70#define RSSI_DEFAULT_HIGH_TIMEOUT 10#define RSSI_DEFAULT_LOW_TIMEOUT 5 +#define RSSI_DEFAULT_SAMPLING_PERIOD 0void adv_monitor_add_manager (DBusConnection *conn,GDBusProxy *proxy);void adv_monitor_remove_manager (DBusConnection *conn);
client/main.c +13 -16
@@ -2709,26 +2709,23 @@ static void cmd_ad_clear(int argc, char *argv[])static void print_add_or_pattern_with_rssi_usage (void ) { -bt_shell_printf ("rssi-range format:\n" -"\t<low-rssi>,<high-rssi>\n" -"\tBoth parameters can be skipped, in that case the\n" -"\tparamter will be set to its pre-defined value\n" ); -bt_shell_printf ("\tPre-defined low-rssi,high-rssi: %d,%d\n" , -RSSI_DEFAULT_LOW_THRESHOLD , -RSSI_DEFAULT_HIGH_THRESHOLD ); -bt_shell_printf ("timeout format:\n" -"\t<low-rssi>,<high-rssi>\n" -"\tBoth parameters can be skipped, in that case the\n" -"\tparamter will be set to its pre-defined value\n" ); -bt_shell_printf ("\tPre-defined low-timeout,high-timeout: %d,%d\n" , -RSSI_DEFAULT_LOW_TIMEOUT , +bt_shell_printf ("rssi format:\n" +"\t<low-rssi>,<high-rssi>,<low-rssi-timeout>," +"<high-rssi-timeout>,<sampling>\n" +"\tAll parameters can be skipped, in that case they\n" +"\twill be set to pre-defined values, which are:\n" ); +bt_shell_printf ("\t\tlow-rssi: %d\n" ,RSSI_DEFAULT_LOW_THRESHOLD ); +bt_shell_printf ("\t\thigh-rssi: %d\n" ,RSSI_DEFAULT_HIGH_THRESHOLD ); +bt_shell_printf ("\t\tlow-rssi-timeout: %d\n" ,RSSI_DEFAULT_LOW_TIMEOUT ); +bt_shell_printf ("\t\thigh-rssi-timeout: %d\n" ,RSSI_DEFAULT_HIGH_TIMEOUT ); +bt_shell_printf ("\t\tsampling: %d\n" ,RSSI_DEFAULT_SAMPLING_PERIOD );bt_shell_printf ("pattern format:\n" "\t<start_position> <ad_data_type> <content_of_pattern>\n" );bt_shell_printf ("e.g.\n" -"\tadd-or-pattern-rssi -10, ,10 1 2 01ab55\n" ); +"\tadd-or-pattern-rssi -10,,,10,0 1 2 01ab55\n" );bt_shell_printf ("or\n" -"\tadd-or-pattern-rssi -50,-30 , 1 2 01ab55 3 4 23cd66\n" ); +"\tadd-or-pattern-rssi -50,-30,,, 1 2 01ab55 3 4 23cd66\n" ); }static void print_add_or_pattern_usage (void )
@@ -2826,7 +2823,7 @@ static const struct bt_shell_menu advertise_monitor_menu = { .name = "monitor", .desc = "Advertisement Monitor Options Submenu", .entries = { - {"add-or-pattern-rssi" ,"<rssi-range=low,high> <timeout=low,high> " + {"add-or-pattern-rssi" ,"<rssi=low,high,low-time,high-time,sampling> " "[patterns=pattern1 pattern2 ...]" , cmd_adv_monitor_add_or_monitor_with_rssi,"Add 'or pattern' type monitor with RSSI "
Signature · 1 line
2.30.0.284.gd98b1dd5eaa7-goog
PATCH 5/5 monitor: Decode add advmon with RSSI parameter
In reply to Archie PusakaFrom: Archie Pusaka <[email protected]>
Add support for MGMT command of add advertisement monitor with RSSI parameter (0x0056).
@ MGMT Command: Add Advertisement.. (0x0056) plen 76 {0x0003}
RSSI data:
high threshold: 1 dBm
high timeout: 0 seconds
low threshold: -2 dBm
low timeout: 3 seconds
sampling: just once (0xFF)
Number of patterns: 2
Pattern 1:
AD type: 0
Offset: 1
Length: 2
Value : c504
Pattern 2:
AD type: 255
Offset: 10
Length: 4
Value : 9a55beef
---
monitor/packet.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)
monitor/packet.c +39 -4
@@ -13261,18 +13261,22 @@ static void mgmt_print_adv_monitor_patterns(const void *data, uint8_t len)/* Reference: struct mgmt_adv_pattern in lib/mgmt.h. */ while (data_idx +34 <= len) { -uint8_t ad_type =get_u8 (data + data_idx); -uint8_t offset =get_u8 (data + data_idx +1 ); -uint8_t length =get_u8 (data + data_idx +2 ); +uint8_t ad_type =get_u8 (data); +uint8_t offset =get_u8 (data +1 ); +uint8_t length =get_u8 (data +2 );print_field (" Pattern %d:" , pattern_idx);print_field (" AD type: %d" , ad_type);print_field (" Offset: %d" , offset);print_field (" Length: %d" , length); -print_hex_field (" Value " , data + data_idx +3 ,31 ); +if (length <=31 ) +print_hex_field (" Value " , data +3 , length); +else +print_text (COLOR_ERROR ," invalid length" ); pattern_idx +=1 ; data_idx +=34 ; + data +=34 ; } }
@@ -13284,6 +13288,33 @@ static void mgmt_add_adv_monitor_patterns_cmd(const void *data, uint16_t size)mgmt_print_adv_monitor_patterns (data +1 , size -1 ); } +static void mgmt_add_adv_monitor_patterns_rssi_cmd (const void *data, +uint16_t size) +{ +int8_t high_rssi =get_s8 (data); +uint16_t high_rssi_timeout =get_le16 (data +1 ); +int8_t low_rssi =get_s8 (data +3 ); +uint16_t low_rssi_timeout =get_le16 (data +4 ); +uint8_t sampling_period =get_u8 (data +6 ); +uint8_t pattern_count =get_u8 (data +7 ); + +print_field ("RSSI data:" ); +print_field (" high threshold: %d dBm" , high_rssi); +print_field (" high timeout: %d seconds" , high_rssi_timeout); +print_field (" low threshold: %d dBm" , low_rssi); +print_field (" low timeout: %d seconds" , low_rssi_timeout); + +if (sampling_period ==0 ) +print_field (" sampling: propagate all (0x00)" ); +else if (sampling_period ==0xff ) +print_field (" sampling: just once (0xFF)" ); +else +print_field (" sampling: every %d ms" ,100 * sampling_period); + +print_field ("Number of patterns: %d" , pattern_count); +mgmt_print_adv_monitor_patterns (data +8 , size -8 ); +} +static void mgmt_add_adv_monitor_patterns_rsp (const void *data,uint16_t size) {uint16_t handle =get_le16 (data);
@@ -13553,6 +13584,10 @@ static const struct mgmt_data mgmt_command_table[] = { {0x0055 ,"Add Ext Adv Data" , mgmt_add_ext_adv_data_cmd,3 , false, mgmt_add_ext_adv_data_rsp, 1, true }, + { 0x0056, "Add Advertisement Monitor With RSSI", + mgmt_add_adv_monitor_patterns_rssi_cmd,8 , + false, + mgmt_add_adv_monitor_patterns_rsp, 2, true}, { } };
Signature · 1 line
2.30.0.284.gd98b1dd5eaa7-goog