linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode
@ 2021-01-15 11:50 Archie Pusaka
  2021-01-15 11:50 ` [Bluez PATCH v4 1/6] lib/mgmt: Adding Add Adv Patterns Monitor " Archie Pusaka
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Archie Pusaka @ 2021-01-15 11:50 UTC (permalink / raw)
  To: linux-bluetooth, Luiz Augusto von Dentz; +Cc: CrosBT Upstreaming, Archie Pusaka

From: Archie Pusaka <apusaka@chromium.org>

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(-)

-- 
2.30.0.296.g2bfb1c46d8-goog


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bluez PATCH v4 1/6] lib/mgmt: Adding Add Adv Patterns Monitor RSSI opcode
  2021-01-15 11:50 [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Archie Pusaka
@ 2021-01-15 11:50 ` Archie Pusaka
  2021-01-15 12:22   ` Support advertising monitor add pattern with " bluez.test.bot
  2021-01-15 11:50 ` [Bluez PATCH v4 2/6] doc/advmon-api: Introduce sampling period property Archie Pusaka
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Archie Pusaka @ 2021-01-15 11:50 UTC (permalink / raw)
  To: linux-bluetooth, Luiz Augusto von Dentz
  Cc: CrosBT Upstreaming, Archie Pusaka, Miao-chen Chou, Yun-Hao Chung,
	Manish Mandlik

From: Archie Pusaka <apusaka@chromium.org>

The new op is to utilize RSSI in advertisement monitor

Reviewed-by: Miao-chen Chou <mcchou@chromium.org>
Reviewed-by: Yun-Hao Chung <howardchung@google.com>
Reviewed-by: Manish Mandlik <mmandlik@chromium.org>
---

(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(+)

diff --git a/lib/mgmt.h b/lib/mgmt.h
index f37f7e6540..76a03c9c24 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -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		0x0001
 struct mgmt_ev_cmd_complete {
 	uint16_t opcode;
-- 
2.30.0.296.g2bfb1c46d8-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Bluez PATCH v4 2/6] doc/advmon-api: Introduce sampling period property
  2021-01-15 11:50 [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Archie Pusaka
  2021-01-15 11:50 ` [Bluez PATCH v4 1/6] lib/mgmt: Adding Add Adv Patterns Monitor " Archie Pusaka
@ 2021-01-15 11:50 ` Archie Pusaka
  2021-01-15 11:50 ` [Bluez PATCH v4 3/6] src/adv_monitor: add monitor with rssi support for mgmt Archie Pusaka
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Archie Pusaka @ 2021-01-15 11:50 UTC (permalink / raw)
  To: linux-bluetooth, Luiz Augusto von Dentz; +Cc: CrosBT Upstreaming, Archie Pusaka

From: Archie Pusaka <apusaka@chromium.org>

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(-)

diff --git a/doc/advertisement-monitor-api.txt b/doc/advertisement-monitor-api.txt
index 92c8ffc38e..8100717c03 100644
--- a/doc/advertisement-monitor-api.txt
+++ b/doc/advertisement-monitor-api.txt
@@ -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]
 
-- 
2.30.0.296.g2bfb1c46d8-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Bluez PATCH v4 3/6] src/adv_monitor: add monitor with rssi support for mgmt
  2021-01-15 11:50 [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Archie Pusaka
  2021-01-15 11:50 ` [Bluez PATCH v4 1/6] lib/mgmt: Adding Add Adv Patterns Monitor " Archie Pusaka
  2021-01-15 11:50 ` [Bluez PATCH v4 2/6] doc/advmon-api: Introduce sampling period property Archie Pusaka
@ 2021-01-15 11:50 ` Archie Pusaka
  2021-01-15 11:50 ` [Bluez PATCH v4 4/6] btmgmt: advmon add rssi support Archie Pusaka
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Archie Pusaka @ 2021-01-15 11:50 UTC (permalink / raw)
  To: linux-bluetooth, Luiz Augusto von Dentz
  Cc: CrosBT Upstreaming, Archie Pusaka, Yun-Hao Chung

From: Archie Pusaka <apusaka@chromium.org>

Using the new opcode MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI to
monitor advertisement according to some RSSI criteria.

Reviewed-by: Yun-Hao Chung <howardchung@google.com>
---

(no changes since v3)

Changes in v3:
* split the struct RSSIThresholdsAndTimers

 src/adv_monitor.c | 267 ++++++++++++++++++++++++++++++----------------
 1 file changed, 174 insertions(+), 93 deletions(-)

diff --git a/src/adv_monitor.c b/src/adv_monitor.c
index 5a0498ec2e..54751db0b5 100644
--- a/src/adv_monitor.c
+++ b/src/adv_monitor.c
@@ -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);
 
-- 
2.30.0.296.g2bfb1c46d8-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Bluez PATCH v4 4/6] btmgmt: advmon add rssi support
  2021-01-15 11:50 [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Archie Pusaka
                   ` (2 preceding siblings ...)
  2021-01-15 11:50 ` [Bluez PATCH v4 3/6] src/adv_monitor: add monitor with rssi support for mgmt Archie Pusaka
@ 2021-01-15 11:50 ` Archie Pusaka
  2021-01-15 11:50 ` [Bluez PATCH v4 5/6] bluetoothctl: advmon rssi support for mgmt Archie Pusaka
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Archie Pusaka @ 2021-01-15 11:50 UTC (permalink / raw)
  To: linux-bluetooth, Luiz Augusto von Dentz
  Cc: CrosBT Upstreaming, Archie Pusaka, Yun-Hao Chung

From: Archie Pusaka <apusaka@chromium.org>

Using the new opcode MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI to
monitor advertisement according to some RSSI criteria.

Reviewed-by: Yun-Hao Chung <howardchung@google.com>
---

(no changes since v1)

 tools/btmgmt.c | 160 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 134 insertions(+), 26 deletions(-)

diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index c0e55f58e6..383e7199e4 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -4858,64 +4858,169 @@ static bool str2pattern(struct mgmt_adv_pattern *pattern, const char *str)
 	return true;
 }
 
-static void advmon_add_usage(void)
+static struct option add_monitor_rssi_options[] = {
+	{ "help",		0, 0, 'h' },
+	{ "high-threshold",	1, 0, 'R' },
+	{ "low-threshold",	1, 0, 'r' },
+	{ "high-timeout",	1, 0, 'T' },
+	{ "low-timeout",	1, 0, 't' },
+	{ "sampling",		1, 0, 's' },
+	{ 0, 0, 0, 0 }
+};
+
+static void advmon_add_pattern_usage(void)
+{
+	bt_shell_usage();
+	print("patterns format:\n"
+		"\t<ad_type:offset:pattern> [patterns]\n"
+		"e.g.:\n"
+		"\tadd-pattern 0:1:c504 ff:a:9a55beef");
+}
+
+static void advmon_add_pattern_rssi_usage(void)
 {
 	bt_shell_usage();
-	print("Monitor Types:\n\t-p <ad_type:offset:pattern>..."
-		"\tPattern Monitor\ne.g.:\n\tadd -p 0:1:c504 1:a:9a55beef");
+	print("RSSI options:\n"
+		"\t -R, --high-threshold <dBm>  "
+			"RSSI high threshold. Default: -70\n"
+		"\t -r, --low-threshold <dBm>   "
+			"RSSI low threshold. Default: -50\n"
+		"\t -T, --high-timeout <s>      "
+			"RSSI high threshold duration. Default: 0\n"
+		"\t -t, --low-timeout <s>       "
+			"RSSI low threshold duration. Default: 5\n"
+		"\t -s, --sampling <N * 100ms>  "
+			"RSSI sampling period. Default: 0\n"
+		"patterns format:\n"
+		"\t<ad_type:offset:pattern> [patterns]\n"
+		"e.g.:\n"
+		"\tadd-pattern-rssi -R 0xb2 -r -102 0:1:c504 ff:a:9a55beef");
 }
 
-static bool advmon_add_pattern(int argc, char **argv)
+static void cmd_advmon_add_pattern(int argc, char **argv)
 {
+	bool success = true;
 	uint16_t index;
 	int i, cp_len;
 	struct mgmt_cp_add_adv_monitor *cp = NULL;
-	bool success = false;
 
-	index = mgmt_index;
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
+	if (!strcmp(argv[1], "-h"))
+		goto done;
 
-	cp_len = sizeof(struct mgmt_cp_add_adv_monitor) +
-			argc * sizeof(struct mgmt_adv_pattern);
+	argc -= 1;
+	argv += 1;
 
+	cp_len = sizeof(*cp) + argc * sizeof(struct mgmt_adv_pattern);
 	cp = malloc0(cp_len);
 	cp->pattern_count = argc;
 
 	for (i = 0; i < argc; i++) {
 		if (!str2pattern(&cp->patterns[i], argv[i])) {
 			error("Failed to parse monitor patterns.");
+			success = false;
 			goto done;
 		}
 	}
 
-	if (!mgmt_send(mgmt, MGMT_OP_ADD_ADV_PATTERNS_MONITOR, index, cp_len,
-					cp, advmon_add_rsp, NULL, NULL)) {
-		error("Unable to send \"Add Advertising Monitor\" command");
+	index = mgmt_index;
+	if (index == MGMT_INDEX_NONE)
+		index = 0;
+
+	if (!mgmt_send(mgmt, MGMT_OP_ADD_ADV_PATTERNS_MONITOR, index,
+				cp_len, cp, advmon_add_rsp, NULL, NULL)) {
+		error("Unable to send Add Advertising Monitor command");
+		success = false;
 		goto done;
 	}
 
-	success = true;
+	free(cp);
+	return;
 
 done:
 	free(cp);
-	return success;
+	advmon_add_pattern_usage();
+	bt_shell_noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
-static void cmd_advmon_add(int argc, char **argv)
+static void cmd_advmon_add_pattern_rssi(int argc, char **argv)
 {
-	bool success = false;
+	bool success = true;
+	int opt;
+	int8_t rssi_low = -70;
+	int8_t rssi_high = -50;
+	uint16_t rssi_low_timeout = 5;
+	uint16_t rssi_high_timeout = 0;
+	uint8_t rssi_sampling_period = 0;
+	uint16_t index;
+	int i, cp_len;
+	struct mgmt_cp_add_adv_patterns_monitor_rssi *cp = NULL;
 
-	if (strcasecmp(argv[1], "-p") == 0 && argc > 2) {
-		argc -= 2;
-		argv += 2;
-		success = advmon_add_pattern(argc, argv);
+	while ((opt = getopt_long(argc, argv, "+hr:R:t:T:s:",
+				add_monitor_rssi_options, NULL)) != -1) {
+		switch (opt) {
+		case 'h':
+			goto done;
+		case 'r':
+			rssi_low = strtol(optarg, NULL, 0);
+			break;
+		case 'R':
+			rssi_high = strtol(optarg, NULL, 0);
+			break;
+		case 't':
+			rssi_low_timeout = strtol(optarg, NULL, 0);
+			break;
+		case 'T':
+			rssi_high_timeout = strtol(optarg, NULL, 0);
+			break;
+		case 's':
+			rssi_sampling_period = strtol(optarg, NULL, 0);
+			break;
+		default:
+			success = false;
+			goto done;
+		}
 	}
 
-	if (!success) {
-		advmon_add_usage();
-		bt_shell_noninteractive_quit(EXIT_FAILURE);
+	argc -= optind;
+	argv += optind;
+	optind = 0;
+
+	cp_len = sizeof(*cp) + argc * sizeof(struct mgmt_adv_pattern);
+	cp = malloc0(cp_len);
+	cp->pattern_count = argc;
+	cp->rssi.high_threshold = rssi_high;
+	cp->rssi.low_threshold = rssi_low;
+	cp->rssi.high_threshold_timeout = htobs(rssi_high_timeout);
+	cp->rssi.low_threshold_timeout = htobs(rssi_low_timeout);
+	cp->rssi.sampling_period = rssi_sampling_period;
+
+	for (i = 0; i < argc; i++) {
+		if (!str2pattern(&cp->patterns[i], argv[i])) {
+			error("Failed to parse monitor patterns.");
+			success = false;
+			goto done;
+		}
+	}
+
+	index = mgmt_index;
+	if (index == MGMT_INDEX_NONE)
+		index = 0;
+
+	if (!mgmt_send(mgmt, MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, index,
+				cp_len, cp, advmon_add_rsp, NULL, NULL)) {
+		error("Unable to send Add Advertising Monitor RSSI command");
+		success = false;
+		goto done;
 	}
+
+	free(cp);
+	return;
+
+done:
+	free(cp);
+	optind = 0;
+	advmon_add_pattern_rssi_usage();
+	bt_shell_noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
 static void advmon_remove_rsp(uint8_t status, uint16_t len, const void *param,
@@ -5037,8 +5142,11 @@ static const struct bt_shell_menu monitor_menu = {
 					"features"			},
 	{ "remove",		"<handle>",
 		cmd_advmon_remove,	"Remove advertisement monitor "	},
-	{ "add",		"<-p|-h> [options...]",
-		cmd_advmon_add,		"Add advertisement monitor"	},
+	{ "add-pattern",	"[-h] <patterns>",
+		cmd_advmon_add_pattern,	"Add advertisement monitor pattern" },
+	{ "add-pattern-rssi",	"[options] <patterns>",
+		cmd_advmon_add_pattern_rssi,
+		"Add advertisement monitor pattern with RSSI options"    },
 	{ } },
 };
 
-- 
2.30.0.296.g2bfb1c46d8-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Bluez PATCH v4 5/6] bluetoothctl: advmon rssi support for mgmt
  2021-01-15 11:50 [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Archie Pusaka
                   ` (3 preceding siblings ...)
  2021-01-15 11:50 ` [Bluez PATCH v4 4/6] btmgmt: advmon add rssi support Archie Pusaka
@ 2021-01-15 11:50 ` Archie Pusaka
  2021-01-15 11:50 ` [Bluez PATCH v4 6/6] monitor: Decode add advmon with RSSI parameter Archie Pusaka
  2021-01-15 19:55 ` [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Luiz Augusto von Dentz
  6 siblings, 0 replies; 9+ messages in thread
From: Archie Pusaka @ 2021-01-15 11:50 UTC (permalink / raw)
  To: linux-bluetooth, Luiz Augusto von Dentz; +Cc: CrosBT Upstreaming, Archie Pusaka

From: Archie Pusaka <apusaka@chromium.org>

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(-)

diff --git a/client/adv_monitor.c b/client/adv_monitor.c
index f62e9f4442..792379fc40 100644
--- a/client/adv_monitor.c
+++ b/client/adv_monitor.c
@@ -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);
 	}
 
diff --git a/client/adv_monitor.h b/client/adv_monitor.h
index dd6f615799..2c25af3339 100644
--- a/client/adv_monitor.h
+++ b/client/adv_monitor.h
@@ -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);
diff --git a/client/main.c b/client/main.c
index 9403f1af6e..79658a463f 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2707,30 +2707,6 @@ static void cmd_ad_clear(int argc, char *argv[])
 		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 }
 
-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,
-						RSSI_DEFAULT_HIGH_TIMEOUT);
-	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");
-	bt_shell_printf("or\n"
-			"\tadd-or-pattern-rssi -50,-30 , 1 2 01ab55 3 4 23cd66\n");
-}
-
 static void print_add_or_pattern_usage(void)
 {
 	bt_shell_printf("pattern format:\n"
@@ -2743,20 +2719,38 @@ static void cmd_adv_monitor_print_usage(int argc, char *argv[])
 {
 	if (strcmp(argv[1], "add-or-pattern") == 0)
 		print_add_or_pattern_usage();
-	else if (strcmp(argv[1], "add-or-pattern-rssi") == 0)
-		print_add_or_pattern_with_rssi_usage();
 	else
 		bt_shell_printf("Invalid argument %s", argv[1]);
 }
 
-static void cmd_adv_monitor_add_or_monitor_with_rssi(int argc, char *argv[])
+static void cmd_adv_monitor_set_rssi_threshold(int argc, char *argv[])
+{
+	int low_threshold, high_threshold;
+
+	low_threshold = atoi(argv[1]);
+	high_threshold = atoi(argv[2]);
+	adv_monitor_set_rssi_threshold(low_threshold, high_threshold);
+}
+
+static void cmd_adv_monitor_set_rssi_timeout(int argc, char *argv[])
 {
-	adv_monitor_add_monitor(dbus_conn, "or_patterns", TRUE, argc, argv);
+	int low_timeout, high_timeout;
+
+	low_timeout = atoi(argv[1]);
+	high_timeout = atoi(argv[2]);
+	adv_monitor_set_rssi_timeout(low_timeout, high_timeout);
+}
+
+static void cmd_adv_monitor_set_rssi_sampling_period(int argc, char *argv[])
+{
+	int sampling = atoi(argv[1]);
+
+	adv_monitor_set_rssi_sampling_period(sampling);
 }
 
 static void cmd_adv_monitor_add_or_monitor(int argc, char *argv[])
 {
-	adv_monitor_add_monitor(dbus_conn, "or_patterns", FALSE, argc, argv);
+	adv_monitor_add_monitor(dbus_conn, "or_patterns", argc, argv);
 }
 
 static void cmd_adv_monitor_print_monitor(int argc, char *argv[])
@@ -2826,15 +2820,19 @@ 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> "
-				"[patterns=pattern1 pattern2 ...]",
-				cmd_adv_monitor_add_or_monitor_with_rssi,
-				"Add 'or pattern' type monitor with RSSI "
-				"filter" },
+	{ "set-rssi-threshold", "<low_threshold> <high_threshold>",
+				cmd_adv_monitor_set_rssi_threshold,
+				"Set RSSI threshold parameter" },
+	{ "set-rssi-timeout", "<low_timeout> <high_timeout>",
+				cmd_adv_monitor_set_rssi_timeout,
+				"Set RSSI timeout parameter" },
+	{ "set-rssi-sampling-period", "<sampling_period>",
+				cmd_adv_monitor_set_rssi_sampling_period,
+				"Set RSSI sampling period parameter" },
 	{ "add-or-pattern", "[patterns=pattern1 pattern2 ...]",
 				cmd_adv_monitor_add_or_monitor,
-				"Add 'or pattern' type monitor without RSSI "
-				"filter" },
+				"Register 'or pattern' type monitor with the "
+				"specified RSSI parameters" },
 	{ "get-pattern", "<monitor-id/all>",
 				cmd_adv_monitor_print_monitor,
 				"Get advertisement monitor" },
@@ -2845,7 +2843,7 @@ static const struct bt_shell_menu advertise_monitor_menu = {
 				cmd_adv_monitor_get_supported_info,
 				"Get advertisement manager supported "
 				"features and supported monitor types" },
-	{ "print-usage", "<add-or-pattern/add-or-pattern-rssi>",
+	{ "print-usage", "<add-or-pattern>",
 				cmd_adv_monitor_print_usage,
 				"Print the command usage"},
 	{ } },
-- 
2.30.0.296.g2bfb1c46d8-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Bluez PATCH v4 6/6] monitor: Decode add advmon with RSSI parameter
  2021-01-15 11:50 [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Archie Pusaka
                   ` (4 preceding siblings ...)
  2021-01-15 11:50 ` [Bluez PATCH v4 5/6] bluetoothctl: advmon rssi support for mgmt Archie Pusaka
@ 2021-01-15 11:50 ` Archie Pusaka
  2021-01-15 19:55 ` [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Luiz Augusto von Dentz
  6 siblings, 0 replies; 9+ messages in thread
From: Archie Pusaka @ 2021-01-15 11:50 UTC (permalink / raw)
  To: linux-bluetooth, Luiz Augusto von Dentz
  Cc: CrosBT Upstreaming, Archie Pusaka, Yun-Hao Chung

From: Archie Pusaka <apusaka@chromium.org>

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

Reviewed-by: Yun-Hao Chung <howardchung@google.com>
---

(no changes since v1)

 monitor/packet.c | 43 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/monitor/packet.c b/monitor/packet.c
index c91b91e2b2..fcd698d92a 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -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},
 	{ }
 };
 
-- 
2.30.0.296.g2bfb1c46d8-goog


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* RE: Support advertising monitor add pattern with RSSI opcode
  2021-01-15 11:50 ` [Bluez PATCH v4 1/6] lib/mgmt: Adding Add Adv Patterns Monitor " Archie Pusaka
@ 2021-01-15 12:22   ` bluez.test.bot
  0 siblings, 0 replies; 9+ messages in thread
From: bluez.test.bot @ 2021-01-15 12:22 UTC (permalink / raw)
  To: linux-bluetooth, apusaka

[-- Attachment #1: Type: text/plain, Size: 557 bytes --]

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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode
  2021-01-15 11:50 [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Archie Pusaka
                   ` (5 preceding siblings ...)
  2021-01-15 11:50 ` [Bluez PATCH v4 6/6] monitor: Decode add advmon with RSSI parameter Archie Pusaka
@ 2021-01-15 19:55 ` Luiz Augusto von Dentz
  6 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2021-01-15 19:55 UTC (permalink / raw)
  To: Archie Pusaka; +Cc: linux-bluetooth, CrosBT Upstreaming, Archie Pusaka

Hi Archie,

On Fri, Jan 15, 2021 at 3:51 AM Archie Pusaka <apusaka@google.com> wrote:
>
> From: Archie Pusaka <apusaka@chromium.org>
>
> 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(-)
>
> --
> 2.30.0.296.g2bfb1c46d8-goog

Applied, thanks.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-01-15 19:57 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-15 11:50 [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Archie Pusaka
2021-01-15 11:50 ` [Bluez PATCH v4 1/6] lib/mgmt: Adding Add Adv Patterns Monitor " Archie Pusaka
2021-01-15 12:22   ` Support advertising monitor add pattern with " bluez.test.bot
2021-01-15 11:50 ` [Bluez PATCH v4 2/6] doc/advmon-api: Introduce sampling period property Archie Pusaka
2021-01-15 11:50 ` [Bluez PATCH v4 3/6] src/adv_monitor: add monitor with rssi support for mgmt Archie Pusaka
2021-01-15 11:50 ` [Bluez PATCH v4 4/6] btmgmt: advmon add rssi support Archie Pusaka
2021-01-15 11:50 ` [Bluez PATCH v4 5/6] bluetoothctl: advmon rssi support for mgmt Archie Pusaka
2021-01-15 11:50 ` [Bluez PATCH v4 6/6] monitor: Decode add advmon with RSSI parameter Archie Pusaka
2021-01-15 19:55 ` [Bluez PATCH v4 0/6] Support advertising monitor add pattern with RSSI opcode Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).