Support advertising monitor add pattern with RSSI opcode
Subsystems (2)
v4 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
Changes in v4:
* split the add-or-pattern-rssi command
* update doc
Changes in v3:
* split the struct RSSIThresholdsAndTimers
Changes in v2:
* Remove trailing period and fix order of mgmt parameter
Archie Pusaka (6):
lib/mgmt: Adding Add Adv Patterns Monitor RSSI opcode doc/advmon-api: Introduce sampling period property 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 | 258 +++++++++++++++++++---------- client/adv_monitor.h | 11 +- client/main.c | 72 ++++---- doc/advertisement-monitor-api.txt | 78 ++++++--- lib/mgmt.h | 15 ++ monitor/packet.c | 43 ++++- src/adv_monitor.c | 267 +++++++++++++++++++----------- tools/btmgmt.c | 160 +++++++++++++++--- 8 files changed, 625 insertions(+), 279 deletions(-)
Signature · 1 line
2.30.0.296.g2bfb1c46d8-goog
PATCH v4 1/6 lib/mgmt: Adding Add Adv Patterns Monitor RSSI opcode
From: Archie Pusaka <[email protected]>
The new op is to utilize RSSI in advertisement monitor
---
(no changes since v2)
Changes in v2:
* Remove trailing period and fix order of mgmt parameter
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 { +struct mgmt_adv_rssi_thresholds rssi; +uint8_t pattern_count; +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.296.g2bfb1c46d8-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=415375
---Test result---
##############################
Test: CheckPatch - PASS
##############################
Test: CheckGitLint - PASS
##############################
Test: CheckBuild - PASS
##############################
Test: MakeCheck - PASS
---
Regards,
Linux Bluetooth
PATCH v4 2/6 doc/advmon-api: Introduce sampling period property
In reply to Archie PusakaFrom: Archie Pusaka <[email protected]>
The sampling period is used to align with the new MGMT opcode which also have sampling period.
---
Changes in v4:
* update doc
doc/advertisement-monitor-api.txt | 78 +++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 25 deletions(-)
doc/advertisement-monitor-api.txt +53 -25
@@ -49,31 +49,59 @@ Properties string Type [read-only] org.bluez.AdvertisementMonitorManager1 for the available options. - (Int16, Uint16, Int16, Uint16) RSSIThresholdsAndTimers [read-only, optional] - - This contains HighRSSIThreshold, HighRSSIThresholdTimer, - LowRSSIThreshold, LowRSSIThresholdTimer in order. The - unit of HighRSSIThreshold and LowRSSIThreshold is dBm. - The unit of HighRSSIThresholdTimer and - LowRSSIThresholdTimer is second. - - If these are provided, RSSI would be used as a factor to - notify the client of whether a device stays in range or - move out of range. A device is considered in-range when - the RSSIs of the received advertisement(s) during - HighRSSIThresholdTimer seconds exceed HighRSSIThreshold. - Likewise, a device is considered out-of-range when the - RSSIs of the received advertisement(s) during - LowRSSIThresholdTimer do not reach LowRSSIThreshold. - - The valid range of a RSSI is -127 to +20 dBm while 127 - dBm indicates unset. The valid range of a timer is 1 to - 300 seconds while 0 indicates unset. - - If the peer device advertising interval is greater than the - HighRSSIThresholdTimer, the device will never be found. Similarly, - if it is greater than LowRSSIThresholdTimer, the device will be - considered as lost. Consider configuring these values accordingly. + Int16 RSSILowThreshold [read-only, optional] + + Used in conjunction with RSSILowTimeout to determine + whether a device becomes out-of-range. Valid range is + -127 to 20 (dBm), while 127 indicates unset. + + Int16 RSSIHighThreshold [read-only, optional] + + Used in conjunction with RSSIHighTimeout to determine + whether a device becomes in-range. Valid range is + -127 to 20 (dBm), while 127 indicates unset. + + Uint16 RSSILowTimeout [read-only, optional] + + The time it takes to consider a device as out-of-range. + If this many seconds elapses without receiving any + signal at least as strong as RSSILowThreshold, a + currently in-range device will be considered as + out-of-range (lost). Valid range is 1 to 300 (seconds), + while 0 indicates unset. + + Uint16 RSSIHighTimeout [read-only, optional] + + The time it takes to consider a device as in-range. + If this many seconds elapses while we continuously + receive signals at least as strong as RSSIHighThreshold, + a currently out-of-range device will be considered as + in-range (found). Valid range is 1 to 300 (seconds), + while 0 indicates unset. + + Uint16 RSSISamplingPeriod [read-only, optional] + + Grouping rules on how to propagate the received + advertisement packets to the client. Valid range is 0 to + 255 while 256 indicates unset. + + The meaning of this property is as follows: + 0: + All advertisement packets from in-range devices + would be propagated. + 255: + Only the first advertisement packet of in-range + devices would be propagated. If the device + becomes lost, then the first packet when it is + found again will also be propagated. + 1 to 254: + Advertisement packets would be grouped into + 100ms * N time period. Packets in the same group + will only be reported once, with the RSSI value + being averaged out. + + Currently this is unimplemented in user space, so the + value is only used to be forwarded to the kernel. array{(uint8, uint8, array{byte})} Patterns [read-only, optional]
Signature · 1 line
2.30.0.296.g2bfb1c46d8-goog
PATCH v4 3/6 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.
---
(no changes since v3)
Changes in v3:
* split the struct RSSIThresholdsAndTimers
src/adv_monitor.c | 267 ++++++++++++++++++++++++++++++---------------- 1 file changed, 174 insertions(+), 93 deletions(-)
src/adv_monitor.c +174 -93
@@ -41,9 +41,14 @@#define ADV_MONITOR_UNSET_RSSI 127/* dBm */ #define ADV_MONITOR_MAX_RSSI 20/* dBm */ #define ADV_MONITOR_MIN_RSSI -127/* dBm */ -#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_TIMEOUT 0/* second */ +#define ADV_MONITOR_MIN_TIMEOUT 1/* second */ +#define ADV_MONITOR_MAX_TIMEOUT 300/* second */ +#define ADV_MONITOR_DEFAULT_LOW_TIMEOUT 5/* second */ +#define ADV_MONITOR_DEFAULT_HIGH_TIMEOUT 10/* second */ +#define ADV_MONITOR_UNSET_SAMPLING_PERIOD 256/* 100 ms */ +#define ADV_MONITOR_MAX_SAMPLING_PERIOD 255/* 100 ms */ +#define ADV_MONITOR_DEFAULT_SAMPLING_PERIOD 0/* 100 ms */ struct btd_adv_monitor_manager {struct btd_adapter *adapter;
@@ -95,6 +100,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_* */
@@ -360,9 +369,10 @@ static struct adv_monitor *monitor_new(struct adv_monitor_app *app, monitor->state =MONITOR_STATE_NEW ; monitor->high_rssi =ADV_MONITOR_UNSET_RSSI ; - monitor->high_rssi_timeout =ADV_MONITOR_UNSET_TIMER ; + monitor->high_rssi_timeout =ADV_MONITOR_UNSET_TIMEOUT ; monitor->low_rssi =ADV_MONITOR_UNSET_RSSI ; - monitor->low_rssi_timeout =ADV_MONITOR_UNSET_TIMER ; + monitor->low_rssi_timeout =ADV_MONITOR_UNSET_TIMEOUT ; + monitor->sampling_period =ADV_MONITOR_UNSET_SAMPLING_PERIOD ; monitor->devices =queue_new (); monitor->type =MONITOR_TYPE_NONE ;
@@ -423,103 +433,119 @@ failed:return false; } -/* Retrieves RSSIThresholdsAndTimers from the remote Adv Monitor object, +/* Retrieves RSSI thresholds and timeouts from the remote Adv Monitor object, * verifies the values and update the local Adv Monitor */ static bool parse_rssi_and_timeout (struct adv_monitor *monitor,const char *path) { -DBusMessageIter prop_struct, iter; -int16_t h_rssi, l_rssi; -uint16_t h_rssi_timer, l_rssi_timer; +DBusMessageIter iter; +GDBusProxy *proxy = monitor->proxy; +int16_t h_rssi =ADV_MONITOR_UNSET_RSSI ; +int16_t l_rssi =ADV_MONITOR_UNSET_RSSI ; +uint16_t h_rssi_timeout =ADV_MONITOR_UNSET_TIMEOUT ; +uint16_t l_rssi_timeout =ADV_MONITOR_UNSET_TIMEOUT ; +int16_t sampling_period =ADV_MONITOR_UNSET_SAMPLING_PERIOD ;uint16_t adapter_id = monitor->app->manager->adapter_id; -/* Property RSSIThresholdsAndTimers is optional */ -if (!g_dbus_proxy_get_property (monitor->proxy, -"RSSIThresholdsAndTimers" , - &prop_struct)) { -DBG ("Adv Monitor at path %s provides no RSSI thresholds and " -"timeouts" , path); -return true; +/* Extract RSSIHighThreshold */ +if (g_dbus_proxy_get_property (proxy,"RSSIHighThreshold" , &iter)) { +if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_INT16 ) + goto failed; +dbus_message_iter_get_basic (&iter, &h_rssi); } -if (dbus_message_iter_get_arg_type (&prop_struct) !=DBUS_TYPE_STRUCT ) - goto failed; - -dbus_message_iter_recurse (&prop_struct, &iter); - -/* Extract HighRSSIThreshold */ -if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_INT16 ) - goto failed; -dbus_message_iter_get_basic (&iter, &h_rssi); -if (!dbus_message_iter_next (&iter)) - goto failed; +/* Extract RSSIHighTimeout */ +if (g_dbus_proxy_get_property (proxy,"RSSIHighTimeout" , &iter)) { +if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_UINT16 ) + goto failed; +dbus_message_iter_get_basic (&iter, &h_rssi_timeout); + } -/* Extract HighRSSIThresholdTimer */ -if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_UINT16 ) - goto failed; -dbus_message_iter_get_basic (&iter, &h_rssi_timer); -if (!dbus_message_iter_next (&iter)) - goto failed; +/* Extract RSSILowThreshold */ +if (g_dbus_proxy_get_property (proxy,"RSSILowThreshold" , &iter)) { +if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_INT16 ) + goto failed; +dbus_message_iter_get_basic (&iter, &l_rssi); + } -/* Extract LowRSSIThreshold */ -if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_INT16 ) - goto failed; -dbus_message_iter_get_basic (&iter, &l_rssi); -if (!dbus_message_iter_next (&iter)) - goto failed; +/* Extract RSSILowTimeout */ +if (g_dbus_proxy_get_property (proxy,"RSSILowTimeout" , &iter)) { +if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_UINT16 ) + goto failed; +dbus_message_iter_get_basic (&iter, &l_rssi_timeout); + } -/* Extract LowRSSIThresholdTimer */ -if (dbus_message_iter_get_arg_type (&iter) !=DBUS_TYPE_UINT16 ) - goto failed; -dbus_message_iter_get_basic (&iter, &l_rssi_timer); +/* Extract RSSISamplingPeriod */ +if (g_dbus_proxy_get_property (proxy,"RSSISamplingPeriod" , &iter)) { +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 -* all are set to the unset values or all are set within valid ranges. +/* Verify the values of RSSIs and their timeouts. All fields should be +* either set to the unset values or are set within valid ranges. +* If the fields are only partially set, we would try our best to fill +* in with some sane values. */ 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 ) { + h_rssi_timeout ==ADV_MONITOR_UNSET_TIMEOUT && + l_rssi_timeout ==ADV_MONITOR_UNSET_TIMEOUT && + sampling_period ==ADV_MONITOR_UNSET_SAMPLING_PERIOD ) { goto done; } +if (l_rssi ==ADV_MONITOR_UNSET_RSSI ) + l_rssi =ADV_MONITOR_MIN_RSSI ; + +if (h_rssi ==ADV_MONITOR_UNSET_RSSI ) + h_rssi = l_rssi; + +if (l_rssi_timeout ==ADV_MONITOR_UNSET_TIMEOUT ) + l_rssi_timeout =ADV_MONITOR_DEFAULT_LOW_TIMEOUT ; + +if (h_rssi_timeout ==ADV_MONITOR_UNSET_TIMEOUT ) + h_rssi_timeout =ADV_MONITOR_DEFAULT_HIGH_TIMEOUT ; + +if (sampling_period ==ADV_MONITOR_UNSET_SAMPLING_PERIOD ) + sampling_period =ADV_MONITOR_DEFAULT_SAMPLING_PERIOD ; +if (h_rssi <ADV_MONITOR_MIN_RSSI || h_rssi >ADV_MONITOR_MAX_RSSI || l_rssi <ADV_MONITOR_MIN_RSSI || - l_rssi >ADV_MONITOR_MAX_RSSI || h_rssi <= l_rssi) { + l_rssi >ADV_MONITOR_MAX_RSSI || h_rssi < l_rssi) { goto failed; } -if (h_rssi_timer <ADV_MONITOR_MIN_TIMER || - h_rssi_timer >ADV_MONITOR_MAX_TIMER || - l_rssi_timer <ADV_MONITOR_MIN_TIMER || - l_rssi_timer >ADV_MONITOR_MAX_TIMER ) { +if (h_rssi_timeout <ADV_MONITOR_MIN_TIMEOUT || + h_rssi_timeout >ADV_MONITOR_MAX_TIMEOUT || + l_rssi_timeout <ADV_MONITOR_MIN_TIMEOUT || + l_rssi_timeout >ADV_MONITOR_MAX_TIMEOUT ) { 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->high_rssi_timeout = h_rssi_timeout; + monitor->low_rssi_timeout = l_rssi_timeout; + 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; failed: - 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 ; -btd_error (adapter_id, -"Invalid argument of property RSSIThresholdsAndTimers " +"Invalid argument of RSSI thresholds and timeouts " "of the Adv Monitor at path %s" , path);
@@ -673,16 +699,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_TIMEOUT && + monitor->low_rssi_timeout ==ADV_MONITOR_UNSET_TIMEOUT && + monitor->sampling_period ==ADV_MONITOR_UNSET_SAMPLING_PERIOD ; +} -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 ); -memcpy (cp->patterns + cp->pattern_count, pattern,sizeof (*pattern)); - cp->pattern_count++; + cp =malloc0 (cp_len); +if (!cp) +return false; + +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 +788,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 +821,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 +1512,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.296.g2bfb1c46d8-goog
PATCH v4 4/6 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.
---
(no changes since v1)
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.296.g2bfb1c46d8-goog
PATCH v4 5/6 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.
---
Changes in v4:
* split the add-or-pattern-rssi command
Changes in v3:
* split the struct RSSIThresholdsAndTimers
client/adv_monitor.c | 258 ++++++++++++++++++++++++++++--------------- client/adv_monitor.h | 11 +- client/main.c | 72 ++++++------ 3 files changed, 210 insertions(+), 131 deletions(-)
client/adv_monitor.c +170 -88
@@ -28,11 +28,16 @@#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_timer; +uint16_t high_timeout;int16_t low_threshold; -uint16_t low_timer; +uint16_t low_timeout; +uint16_t sampling_period; };struct pattern {
@@ -59,6 +64,7 @@ static struct adv_monitor_manager {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);
@@ -131,32 +137,105 @@ static gboolean get_type(const GDBusPropertyTable *property,return TRUE; } -static gboolean get_rssi (const GDBusPropertyTable *property, +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; -DBusMessageIter data_iter; -dbus_message_iter_open_container (iter,DBUS_TYPE_STRUCT , -NULL , &data_iter); -dbus_message_iter_append_basic (&data_iter,DBUS_TYPE_INT16 , - &rssi->high_threshold); -dbus_message_iter_append_basic (&data_iter,DBUS_TYPE_UINT16 , - &rssi->high_timer); -dbus_message_iter_append_basic (&data_iter,DBUS_TYPE_INT16 , +dbus_message_iter_append_basic (iter,DBUS_TYPE_INT16 , &rssi->low_threshold); -dbus_message_iter_append_basic (&data_iter,DBUS_TYPE_UINT16 , - &rssi->low_timer); -dbus_message_iter_close_container (iter, &data_iter);return TRUE; } -static gboolean rssi_exists (const GDBusPropertyTable *property,void *data) +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 ; +return adv_monitor->rssi !=NULL && + adv_monitor->rssi->sampling_period != +RSSI_UNSET_SAMPLING_PERIOD ; } static void append_pattern_content_to_dbus(DBusMessageIter *iter,
@@ -212,7 +291,14 @@ 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 }, + {"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 }, { } };
@@ -266,6 +352,9 @@ void adv_monitor_remove_manager(DBusConnection *conn) manager.proxy =NULL ; manager.app_registered = FALSE; + +g_free (current_rssi); + current_rssi =NULL ; }static void register_setup (DBusMessageIter *iter,void *user_data)
@@ -376,58 +465,6 @@ 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) -{ -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 ; - -parse_rssi_value_pair (range, &low_threshold, &high_threshold); -parse_rssi_value_pair (timeout, &low_timer, &high_timer); - - rssi =g_malloc0 (sizeof (struct rssi_setting )); - -if (!rssi) { -bt_shell_printf ("Failed to allocate rssi_setting" ); -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; - -return rssi; -} -static struct pattern *parse_pattern (char *parameter_list[]) {struct pattern *pat;
@@ -435,7 +472,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 ; }
@@ -531,12 +568,14 @@ static void print_adv_monitor(struct adv_monitor *adv_monitor)bt_shell_printf ("\trssi:\n" );bt_shell_printf ("\t\thigh threshold: %hd\n" , adv_monitor->rssi->high_threshold); -bt_shell_printf ("\t\thigh threshold timer: %hu\n" , - adv_monitor->rssi->high_timer); +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 timer: %hu\n" , - adv_monitor->rssi->low_timer); +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) {
@@ -556,11 +595,62 @@ static void print_adv_monitor(struct adv_monitor *adv_monitor) } } +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, -gboolean rssi_enabled,int argc,char *argv[]) +int argc,char *argv[]) {struct adv_monitor *adv_monitor; -struct rssi_setting *rssi;GSList *patterns =NULL ;if (g_slist_length (adv_mons) >=UINT8_MAX ) {
@@ -572,17 +662,6 @@ 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) - rssi =NULL ; -else { - rssi =parse_rssi (argv[1 ], argv[2 ]); -if (rssi ==NULL ) -return ; - - argv +=2 ; - argc -=2 ; - } - patterns =parse_patterns (argv+1 , argc-1 );if (patterns ==NULL ) {bt_shell_printf ("pattern-list malformed\n" );
@@ -598,16 +677,19 @@ void adv_monitor_add_monitor(DBusConnection *conn, char *type, adv_monitor->idx = adv_mon_idx; adv_monitor->type =g_strdup (type); - adv_monitor->rssi = rssi; + 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 ); }
client/adv_monitor.h +5 -6
@@ -8,17 +8,16 @@* */ -#define RSSI_DEFAULT_HIGH_THRESHOLD -50 -#define RSSI_DEFAULT_LOW_THRESHOLD -70 -#define RSSI_DEFAULT_HIGH_TIMEOUT 10 -#define RSSI_DEFAULT_LOW_TIMEOUT 5 -void adv_monitor_add_manager (DBusConnection *conn,GDBusProxy *proxy);void adv_monitor_remove_manager (DBusConnection *conn);void adv_monitor_register_app (DBusConnection *conn);void adv_monitor_unregister_app (DBusConnection *conn); +void adv_monitor_set_rssi_threshold (int16_t low_threshold, +int16_t high_threshold); +void adv_monitor_set_rssi_timeout (uint16_t low_timeout,uint16_t high_timeout); +void adv_monitor_set_rssi_sampling_period (uint16_t sampling);void adv_monitor_add_monitor (DBusConnection *conn,char *type, -gboolean rssi_enabled,int argc,char *argv[]); +int argc,char *argv[]);void adv_monitor_print_monitor (DBusConnection *conn,int monitor_idx);void adv_monitor_remove_monitor (DBusConnection *conn,int monitor_idx);void adv_monitor_get_supported_info (void );
client/main.c +35 -37
107 lines not on this page · raw message
Signature · 1 line
2.30.0.296.g2bfb1c46d8-goog
PATCH v4 6/6 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
---
(no changes since v1)
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.296.g2bfb1c46d8-goog
Hi Archie,
Quoted 40 lines · Archie Pusaka
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!
ArchieChanges in v4:
* split the add-or-pattern-rssi command
* update docChanges in v3:
* split the struct RSSIThresholdsAndTimersChanges in v2:
* Remove trailing period and fix order of mgmt parameterArchie Pusaka (6):
lib/mgmt: Adding Add Adv Patterns Monitor RSSI opcode doc/advmon-api: Introduce sampling period property 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 parameterclient/adv_monitor.c | 258 +++++++++++++++++++---------- client/adv_monitor.h | 11 +- client/main.c | 72 ++++---- doc/advertisement-monitor-api.txt | 78 ++++++--- lib/mgmt.h | 15 ++ monitor/packet.c | 43 ++++- src/adv_monitor.c | 267 +++++++++++++++++++----------- tools/btmgmt.c | 160 +++++++++++++++--- 8 files changed, 625 insertions(+), 279 deletions(-)
Quoted 2 lines
--
2.30.0.296.g2bfb1c46d8-goog
Applied, thanks.
Signature · 1 line
Luiz Augusto von Dentz