2020-03-30 07:05:33

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v1 0/6] Add support of setting advertiing intervals.

Hi Linux bluetooth, this is a series of patches for supporting
setting of LE advertising intervals from D-Bus API.

Hi linux bluetooth, this is the lib/mgmt part of supporting LE
set advertising interval series patches.
Thanks

Hi linux bluetooth, this is the advertising part of supporting LE
set advertising interval series patches.
Thanks

Hi linux bluetooth, this is the documentation part of supporting LE
set advertising interval series patches.
Thanks

Hi linux bluetooth, this is the monitor part of supporting LE
set advertising interval series patches.
Thanks

Hi linux bluetooth, this is the test part of supporting LE set
advertising interval series patches.
Thanks

Hi linux bluetooth, this patch is the btmgmt part of supporting
LE Set Advertising Interval series.
Thanks


Howard Chung (6):
lib/mgmt: Add LE Set Advertising Interval definition
core/advertising: Add support for LE set adverting interval
doc: Add documentation for LE Set Advertising Interval
monitor: Add support for decoding LE Set Advertising Interval
test: Add test for LE Set Advertising Interval
tools/btmgmt: Add setting string for LE Set Advertising Interval

doc/advertising-api.txt | 13 +++++
doc/mgmt-api.txt | 25 +++++++++
lib/mgmt.h | 11 ++++
monitor/control.c | 1 +
monitor/packet.c | 21 +++++++
src/advertising.c | 90 ++++++++++++++++++++++++++++++
test/example-advertising-intervals | 48 ++++++++++++++++
tools/btmgmt.c | 1 +
8 files changed, 210 insertions(+)
create mode 100644 test/example-advertising-intervals

--
2.26.0.rc2.310.g2932bb562d-goog


2020-03-30 07:05:41

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v1 2/6] core/advertising: Add support for LE set adverting interval

Implement a new dbus method to set advertising intervals.
The advertising inervals are sent through a new mgmt method with
the opcode MGMT_OP_SET_ADVERTISING_INTERVALS to bluetooth kernel
subsystem.

Signed-off-by: Howard Chung <[email protected]>
---

src/advertising.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)

diff --git a/src/advertising.c b/src/advertising.c
index 45ff19fa0..444969f04 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -1342,6 +1342,92 @@ static const GDBusPropertyTable properties[] = {
{ }
};

+static void set_advertising_intervals_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ DBusMessage *msg = user_data;
+ DBusMessage *reply;
+
+ switch (status) {
+ case MGMT_STATUS_SUCCESS:
+ reply = dbus_message_new_method_return(msg);
+ break;
+ case MGMT_STATUS_REJECTED:
+ reply = btd_error_failed(
+ msg, "A non-BLE device should not advertise!");
+ break;
+ case MGMT_STATUS_INVALID_PARAMS:
+ reply = btd_error_invalid_args(msg);
+ break;
+ case MGMT_STATUS_BUSY:
+ reply = btd_error_busy(msg);
+ break;
+ default:
+ reply = btd_error_failed(
+ msg, "failed to set advertising intervals");
+ }
+
+ g_dbus_send_message(btd_get_dbus_connection(), reply);
+ dbus_message_unref(msg);
+}
+
+static int adapter_set_advertising_intervals(struct btd_adv_manager *manager,
+ DBusMessage *msg,
+ uint16_t min_interval_ms,
+ uint16_t max_interval_ms)
+{
+ struct mgmt_cp_set_advertising_intervals cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+ /* Convert milli-seconds to multiples of 0.625 ms which are used
+ * in kernel.
+ */
+ cp.min_interval = min_interval_ms / ADVERTISING_INTERVAL_UNIT_TIME;
+ cp.max_interval = max_interval_ms / ADVERTISING_INTERVAL_UNIT_TIME;
+
+ btd_info(manager->mgmt_index,
+ "Set Advertising Intervals: 0x%04x, 0x%04x",
+ cp.min_interval, cp.max_interval);
+
+ if (mgmt_send(manager->mgmt,
+ MGMT_OP_SET_ADVERTISING_INTERVALS, manager->mgmt_index,
+ sizeof(cp), &cp, set_advertising_intervals_callback,
+ dbus_message_ref(msg), NULL) > 0) {
+ return true;
+ }
+
+ return false;
+}
+
+static DBusMessage *set_advertising_intervals(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ struct btd_adv_manager *manager = user_data;
+ const char *sender = dbus_message_get_sender(msg);
+ dbus_uint16_t min_interval_ms, max_interval_ms;
+
+ DBG("set_advertising_intervals: sender %s", sender);
+
+ if (!dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_UINT16, &min_interval_ms,
+ DBUS_TYPE_UINT16, &max_interval_ms,
+ DBUS_TYPE_INVALID)) {
+ return btd_error_invalid_args(msg);
+ }
+
+ /* The adapter is not required to be powered to set advertising
+ * intervals. Hence, just go ahead to set the intervals.
+ */
+ if (!adapter_set_advertising_intervals(manager, msg, min_interval_ms,
+ max_interval_ms)) {
+ return btd_error_failed(msg,
+ "failed to set advertising intervals");
+ }
+
+ return NULL;
+}
+
static const GDBusMethodTable methods[] = {
{ GDBUS_ASYNC_METHOD("RegisterAdvertisement",
GDBUS_ARGS({ "advertisement", "o" },
@@ -1351,6 +1437,10 @@ static const GDBusMethodTable methods[] = {
GDBUS_ARGS({ "service", "o" }),
NULL,
unregister_advertisement) },
+ { GDBUS_ASYNC_METHOD("SetAdvertisingIntervals",
+ GDBUS_ARGS({"min_interval_ms", "q"},
+ {"max_interval_ms", "q"}),
+ NULL, set_advertising_intervals)},
{ }
};

--
2.26.0.rc2.310.g2932bb562d-goog

2020-03-30 07:05:46

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v1 3/6] doc: Add documentation for LE Set Advertising Interval

Signed-off-by: Howard Chung <[email protected]>
---

doc/advertising-api.txt | 13 +++++++++++++
doc/mgmt-api.txt | 25 +++++++++++++++++++++++++
2 files changed, 38 insertions(+)

diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
index b0565eab2..9264cdb27 100644
--- a/doc/advertising-api.txt
+++ b/doc/advertising-api.txt
@@ -209,3 +209,16 @@ Properties byte ActiveInstances
Possible values: "1M"
"2M"
"Coded"
+
+ void SetAdvertisingIntervals(uint16 min_interval_ms,
+ uint16 max_interval_ms)
+
+ This method sets the advertising intervals.
+
+ The parameters min_interval_ms and max_interval_ms
+ are specified in milli-seconds. Valid values of
+ the intervals must fall between 20 ms and 10,240 ms.
+
+ Possible errors: org.bluez.Error.Failed
+ org.bluez.Error.InProgress
+ org.bluez.Error.InvalidArguments
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index 27a41f334..5eff87e24 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -2925,6 +2925,31 @@ Read Extended Controller Information Command
Invalid Index


+Set Advertising Intervals Command
+=================================
+
+ Command Code: 0x0101
+ Controller Index: <controller id>
+ Command Parameters: Min_Interval (2 Octets)
+ Max_Interval (2 Octets)
+ Return Parameters: Current_Settings (4 Octets)
+
+ This command is used to set advertising intervals. The intervals
+ are expressed in multiples of 0.625 ms. The default values of
+ both intervals are 0x0800. Valid Min_Interval and Max_Interval
+ values must fall between 0x0020 and 0x4000.
+
+ The advertising intervals are first kept in hdev struct. The values
+ would be sent to the controller and take effect when advertising is
+ actually enabled. If the advertising intervals are set when
+ advertising is already on, the advertising would be disabled and
+ re-enabled to make the intervals take effect.
+
+ Possible errors: Busy
+ Rejected
+ Invalid Parameters
+
+
Set Appearance Command
======================

--
2.26.0.rc2.310.g2932bb562d-goog

2020-03-30 07:06:05

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v1 4/6] monitor: Add support for decoding LE Set Advertising Interval

The following lines will show in btmon:
bluetoothd: Set Advertising Intervals: 0x0140, 0x0280

@ MGMT Command: LE Set Advertising Interval (0x0060) plen 4
Min advertising interval: 0x0140
Max advertising interval: 0x0280
@ MGMT Event: Command Complete (0x0001) plen 7
LE Set Advertising Interval (0x0060) plen 4
Status: Success (0x00)
Current settings: 0x00040ad0

Signed-off-by: Howard Chung <[email protected]>
---

monitor/control.c | 1 +
monitor/packet.c | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+)

diff --git a/monitor/control.c b/monitor/control.c
index 790890fb4..cbf8d41da 100644
--- a/monitor/control.c
+++ b/monitor/control.c
@@ -201,6 +201,7 @@ static const char *settings_str[] = {
"bondable", "link-security", "ssp", "br/edr", "hs", "le",
"advertising", "secure-conn", "debug-keys", "privacy",
"configuration", "static-addr", "phy-configuration", "wide-band-speech",
+ "advertising-intervals",
};

static void mgmt_new_settings(uint16_t len, const void *buf)
diff --git a/monitor/packet.c b/monitor/packet.c
index 3d32563e6..00825cbb4 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -11669,6 +11669,7 @@ static const struct bitfield_data mgmt_settings_table[] = {
{ 15, "Static Address" },
{ 16, "PHY Configuration" },
{ 17, "Wideband Speech" },
+ { 18, "Advertising Intervals" },
{ }
};

@@ -12988,6 +12989,23 @@ static void mgmt_set_phy_cmd(const void *data, uint16_t size)
mgmt_print_phys("Selected PHYs", selected_phys);
}

+static void mgmt_set_adv_interval_cmd(const void *data, uint16_t size)
+{
+ uint16_t min_adv_interval = get_le16(data);
+ uint16_t max_adv_interval = get_le16(data+2);
+
+ print_field("Min advertising interval: 0x%4.4x", min_adv_interval);
+ print_field("Max advertising interval: 0x%4.4x", max_adv_interval);
+}
+
+static void mgmt_set_adv_interval_rsp(const void *data, uint16_t size)
+{
+ uint32_t current_settings = get_le32(data);
+
+ print_field("Current settings: 0x%8.8x", current_settings);
+}
+
+
struct mgmt_data {
uint16_t opcode;
const char *str;
@@ -13207,6 +13225,9 @@ static const struct mgmt_data mgmt_command_table[] = {
{ 0x0045, "Set PHY Configuration",
mgmt_set_phy_cmd, 4, true,
mgmt_null_rsp, 0, true },
+ { 0x0060, "LE Set Advertising Interval",
+ mgmt_set_adv_interval_cmd, 4, true,
+ mgmt_set_adv_interval_rsp, 4, true},
{ }
};

--
2.26.0.rc2.310.g2932bb562d-goog

2020-03-30 07:06:27

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v1 1/6] lib/mgmt: Add LE Set Advertising Interval definition

Suggested-by: [email protected]

Signed-off-by: Howard Chung <[email protected]>
---

lib/mgmt.h | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/lib/mgmt.h b/lib/mgmt.h
index 7520c7ae9..75302f5fd 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -103,6 +103,7 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_STATIC_ADDRESS 0x00008000
#define MGMT_SETTING_PHY_CONFIGURATION 0x00010000
#define MGMT_SETTING_WIDEBAND_SPEECH 0x00020000
+#define MGMT_SETTING_ADVERTISING_INTERVALS 0x00040000

#define MGMT_OP_READ_INFO 0x0004
struct mgmt_rp_read_info {
@@ -602,6 +603,15 @@ struct mgmt_cp_set_blocked_keys {

#define MGMT_OP_SET_WIDEBAND_SPEECH 0x0047

+#define MGMT_OP_SET_ADVERTISING_INTERVALS 0x0048
+#define ADVERTISING_INTERVAL_UNIT_TIME 0.625
+struct mgmt_cp_set_advertising_intervals {
+ /* A unit of the intervals below is 0.625 ms.*/
+ uint16_t min_interval;
+ uint16_t max_interval;
+} __packed;
+#define MGMT_SET_ADVERTISING_INTERVALS_SIZE 4
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
uint16_t opcode;
@@ -898,6 +908,7 @@ static const char *mgmt_op[] = {
"Set PHY Configuration",
"Set Blocked Keys",
"Set Wideband Speech",
+ "Set Advertising Intervals", /* 0x0048 */
};

static const char *mgmt_ev[] = {
--
2.26.0.rc2.310.g2932bb562d-goog

2020-03-30 07:06:35

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v1 6/6] tools/btmgmt: Add setting string for LE Set Advertising Interval

$ btmgmt info
current settings: powered bondable ... advertising-intervals

Signed-off-by: Howard Chung <[email protected]>
---

tools/btmgmt.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index b1820b41c..91e9c0b40 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -355,6 +355,7 @@ static const char *settings_str[] = {
"static-addr",
"phy-configuration",
"wide-band-speech",
+ "advertising-intervals",
};

static const char *settings2str(uint32_t settings)
--
2.26.0.rc2.310.g2932bb562d-goog

2020-03-30 07:06:57

by Yun-hao Chung

[permalink] [raw]
Subject: [Bluez PATCH v1 5/6] test: Add test for LE Set Advertising Interval

Perform the following steps to verify advertising intervals.
Open a terminal on the DUT, and execute
$ btmon

Open another terminal on the DUT, and register an advertisement.
$ ./example-advertisement

Observe that the default intervals are 1280 msec in btmon log.
< HCI Command: LE Set Advertising Parameters (0x08|0x0006) plen 15
Min advertising interval: 1280.000 msec (0x0800)
Max advertising interval: 1280.000 msec (0x0800)
Press ctrl-c to terminate the advertisement.

Set new intervals to 200 ms.
$ ./example-advertising-intervals 200 200

It would show the following line in btmon log.
= bluetoothd: Set Advertising Intervals: 0x0140, 0x0140

Register an advertisement again.
$ ./example-advertisement

Observe that the new intervals bcome 200 msec in btmon log.
< HCI Command: LE Set Advertising Parameters (0x08|0x0006) plen 15
Min advertising interval: 200.000 msec (0x0140)
Max advertising interval: 200.000 msec (0x0140)
Press ctrl-c to terminate the advertisement.

Signed-off-by: Howard Chung <[email protected]>
---

test/example-advertising-intervals | 48 ++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
create mode 100644 test/example-advertising-intervals

diff --git a/test/example-advertising-intervals b/test/example-advertising-intervals
new file mode 100644
index 000000000..8afc7225e
--- /dev/null
+++ b/test/example-advertising-intervals
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+"""A simple script to set advertising intervals through the dbus method.
+
+Usage:
+ $ ./example_advertising_intervals.py min_interval_ms max_interval_ms
+
+ Example:
+ # Set both min and max advertising intervals to 200 ms.
+ $ ./exampel_advertising_intervals.py 200 200
+"""
+
+import dbus
+import time
+import subprocess
+import sys
+
+argv = sys.argv
+argc = len(argv)
+prog = argv[0]
+if argc == 3:
+ min_interval_ms = int(argv[1])
+ max_interval_ms = int(argv[2])
+ print 'Set advertising intervals: [%d, %d]' % (min_interval_ms,
+ max_interval_ms)
+else:
+ print 'Usage: python %s min_interval_ms max_interval_ms' % prog
+ print ' python %s 200 200' % prog
+ sys.exit(1)
+
+
+# Set advertising intervals.
+bus = dbus.SystemBus()
+adapter = bus.get_object('org.bluez', '/org/bluez/hci0')
+adapter.SetAdvertisingIntervals(
+ min_interval_ms, max_interval_ms,
+ dbus_interface='org.bluez.LEAdvertisingManager1')
+
+
+# Wait a little while for dbus method to complete.
+time.sleep(0.2)
+
+
+# Check the current settings using btmgmt.
+btmgmt_cmd = 'btmgmt info'
+for line in subprocess.check_output(btmgmt_cmd.split()).splitlines():
+ if 'current settings' in line:
+ print line.strip()
--
2.26.0.rc2.310.g2932bb562d-goog