* [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1
@ 2026-10-08 17:29 Kevin Dewald
2026-10-08 17:29 ` [PATCH BlueZ v2 1/3] org.bluez.Bearer: Add Role property Kevin Dewald
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Kevin Dewald @ 2026-10-08 17:29 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald
Applications acting as a peripheral, or in both roles, cannot tell
whether a connected device is a central that connected to the adapter
or a peripheral the adapter connected to. When several applications
share the adapter, a device object can appear because of any of them,
so the order of events does not answer it either.
bluetoothd already tracks this per bearer from the Device Connected
event. This series exposes it as a Role property on
org.bluez.Bearer.LE1, "central" or "peripheral", present only while
the device is connected over LE, and prints it as LE.Role in
bluetoothctl info. The documentation states that it is the link layer
role and says nothing about GATT client and server roles.
Like the rest of the bearer interfaces, the property is experimental,
so applications only see it when bluetoothd runs with -E, which few
systems do. Is there a plan to promote the bearer interfaces, or some
of their properties, to stable? I would be glad to help with whatever
that needs.
Tested with two btvirt controllers, where the advertising side reports
the other as "central" and the connecting side reports it as
"peripheral", and with a real adapter connecting to an nRF52840. The
property goes away when the connection does.
Changes in v2:
- Move the property from org.bluez.Device1 to org.bluez.Bearer.LE1, so
it is clearly per connection (Luiz)
- State in the documentation that it says nothing about GATT roles
(Luiz)
Kevin Dewald (3):
org.bluez.Bearer: Add Role property
bearer: Add Role property
client: Print LE.Role in info
client/main.c | 1 +
doc/org.bluez.Bearer.LE.rst | 24 +++++++++++++++++++++
src/bearer.c | 42 +++++++++++++++++++++++++++++++++++++
src/device.c | 5 +++++
src/device.h | 1 +
5 files changed, 73 insertions(+)
--
2.54.0 (Apple Git-157)
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH BlueZ v2 1/3] org.bluez.Bearer: Add Role property 2026-10-08 17:29 [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 Kevin Dewald @ 2026-10-08 17:29 ` Kevin Dewald 2026-10-08 22:35 ` Add Role property to org.bluez.Bearer.LE1 bluez.test.bot 2026-10-08 17:29 ` [PATCH BlueZ v2 2/3] bearer: Add Role property Kevin Dewald ` (2 subsequent siblings) 3 siblings, 1 reply; 8+ messages in thread From: Kevin Dewald @ 2026-10-08 17:29 UTC (permalink / raw) To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald This adds Role property to org.bluez.Bearer.LE1 which indicates whether the remote device is the central or the peripheral of the current LE connection, so applications can tell a central that connected to the adapter from a peripheral the adapter connected to. Assisted-by: Claude:claude-opus-5.5 --- doc/org.bluez.Bearer.LE.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/org.bluez.Bearer.LE.rst b/doc/org.bluez.Bearer.LE.rst index ec92a5ce5..dfd809739 100644 --- a/doc/org.bluez.Bearer.LE.rst +++ b/doc/org.bluez.Bearer.LE.rst @@ -153,3 +153,27 @@ The property is only present once the device has been discovered or connected over LE bearer. A PropertiesChanged signal indicate changes to this status. + +string Role [readonly, optional, experimental] +`````````````````````````````````````````````` + +Indicates the role of the remote device in the current connection on LE bearer. +It is only present while the remote device is connected over LE bearer. + +It is the link layer role of the connection. It does not imply which side acts +as GATT client or server, as GATT roles are independent of it and both may be +used at the same time. + +Possible values: + +:"central": + + The remote device initiated the connection, and the adapter is the + peripheral. + +:"peripheral": + + The adapter initiated the connection, and the remote device is the + peripheral. + +A PropertiesChanged signal indicate changes to this status. -- 2.54.0 (Apple Git-157) ^ permalink raw reply related [flat|nested] 8+ messages in thread
* RE: Add Role property to org.bluez.Bearer.LE1 2026-10-08 17:29 ` [PATCH BlueZ v2 1/3] org.bluez.Bearer: Add Role property Kevin Dewald @ 2026-10-08 22:35 ` bluez.test.bot 0 siblings, 0 replies; 8+ messages in thread From: bluez.test.bot @ 2026-10-08 22:35 UTC (permalink / raw) To: linux-bluetooth, kevin [-- Attachment #1: Type: text/plain, Size: 1156 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/series/1181777/ ---Test result--- Test Summary: CheckPatch PASS 1.14 seconds GitLint PASS 0.79 seconds BuildEll PASS 16.14 seconds BluezMake PASS 281.25 seconds MakeCheck PASS 13.74 seconds MakeDistcheck PASS 117.94 seconds CheckValgrind PASS 188.17 seconds CheckSmatch PASS 202.45 seconds bluezmakeextell PASS 74.32 seconds TestFunctional PASS 961.44 seconds IncrementalBuild PENDING 350.27 seconds ScanBuild PASS 822.65 seconds Details ############################## Test: IncrementalBuild - PENDING Desc: Incremental build with the patches in the series Output: https://github.com/bluez/bluez/pull/2637 --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH BlueZ v2 2/3] bearer: Add Role property 2026-10-08 17:29 [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 Kevin Dewald 2026-10-08 17:29 ` [PATCH BlueZ v2 1/3] org.bluez.Bearer: Add Role property Kevin Dewald @ 2026-10-08 17:29 ` Kevin Dewald 2026-10-08 17:30 ` [PATCH BlueZ v2 3/3] client: Print LE.Role in info Kevin Dewald 2026-10-08 19:10 ` [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 Luiz Augusto von Dentz 3 siblings, 0 replies; 8+ messages in thread From: Kevin Dewald @ 2026-10-08 17:29 UTC (permalink / raw) To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald This implements Role property for the LE bearer using the initiator flag of the Device Connected event, which the kernel sets when the adapter created the connection as central, and emits PropertiesChanged along with Connected. Assisted-by: Claude:claude-opus-5.5 --- src/bearer.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/device.c | 5 +++++ src/device.h | 1 + 3 files changed, 48 insertions(+) diff --git a/src/bearer.c b/src/bearer.c index f3b7a2337..25224dcc7 100644 --- a/src/bearer.c +++ b/src/bearer.c @@ -274,6 +274,34 @@ static gboolean bearer_connectable_exists(const GDBusPropertyTable *property, return btd_device_bdaddr_type_seen(bearer->device, bearer->type); } +static gboolean bearer_get_role(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct btd_bearer *bearer = data; + const char *role; + + /* The initiator of an LE connection is always the central */ + if (btd_device_bdaddr_type_initiator(bearer->device, bearer->type)) + role = "peripheral"; + else + role = "central"; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &role); + + return TRUE; +} + +static gboolean bearer_role_exists(const GDBusPropertyTable *property, + void *data) +{ + struct btd_bearer *bearer = data; + + if (bearer->type == BDADDR_BREDR) + return FALSE; + + return btd_device_bdaddr_type_connected(bearer->device, bearer->type); +} + static const GDBusSignalTable bearer_signals[] = { { GDBUS_SIGNAL("Disconnected", GDBUS_ARGS({ "name", "s" }, { "message", "s" })) }, @@ -292,6 +320,8 @@ static const GDBusPropertyTable bearer_properties[] = { { "Connectable", "b", bearer_get_connectable, NULL, bearer_connectable_exists, G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, + { "Role", "s", bearer_get_role, NULL, bearer_role_exists, + G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, {} }; @@ -416,6 +446,12 @@ void btd_bearer_connected(struct btd_bearer *bearer, int err) g_dbus_emit_property_changed(btd_get_dbus_connection(), bearer->path, bearer_interface(bearer->type), "Connected"); + + if (!err && bearer->type != BDADDR_BREDR) + g_dbus_emit_property_changed(btd_get_dbus_connection(), + bearer->path, + bearer_interface(bearer->type), + "Role"); } void btd_bearer_disconnected(struct btd_bearer *bearer, uint8_t reason) @@ -444,6 +480,12 @@ void btd_bearer_disconnected(struct btd_bearer *bearer, uint8_t reason) bearer_interface(bearer->type), "Connected"); + if (bearer->type != BDADDR_BREDR) + g_dbus_emit_property_changed(btd_get_dbus_connection(), + bearer->path, + bearer_interface(bearer->type), + "Role"); + switch (reason) { case MGMT_DEV_DISCONN_UNKNOWN: name = "org.bluez.Reason.Unknown"; diff --git a/src/device.c b/src/device.c index 1ab4e5342..4ccafd15a 100644 --- a/src/device.c +++ b/src/device.c @@ -3869,6 +3869,11 @@ bool btd_device_bdaddr_type_seen(struct btd_device *dev, uint8_t type) return get_state(dev, type)->last_seen != 0; } +bool btd_device_bdaddr_type_initiator(struct btd_device *dev, uint8_t type) +{ + return get_state(dev, type)->initiator; +} + static void clear_temporary_timer(struct btd_device *dev) { if (dev->temporary_timer) { diff --git a/src/device.h b/src/device.h index 756540056..5ead73958 100644 --- a/src/device.h +++ b/src/device.h @@ -129,6 +129,7 @@ bool btd_device_bearer_is_connected(struct btd_device *dev); bool btd_device_bdaddr_type_connected(struct btd_device *dev, uint8_t type); bool btd_device_bdaddr_type_connectable(struct btd_device *dev, uint8_t type); bool btd_device_bdaddr_type_seen(struct btd_device *dev, uint8_t type); +bool btd_device_bdaddr_type_initiator(struct btd_device *dev, uint8_t type); uint8_t btd_device_get_bdaddr_type(struct btd_device *dev); bool device_is_retrying(struct btd_device *device); void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type, -- 2.54.0 (Apple Git-157) ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH BlueZ v2 3/3] client: Print LE.Role in info 2026-10-08 17:29 [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 Kevin Dewald 2026-10-08 17:29 ` [PATCH BlueZ v2 1/3] org.bluez.Bearer: Add Role property Kevin Dewald 2026-10-08 17:29 ` [PATCH BlueZ v2 2/3] bearer: Add Role property Kevin Dewald @ 2026-10-08 17:30 ` Kevin Dewald 2026-10-08 19:10 ` [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 Luiz Augusto von Dentz 3 siblings, 0 replies; 8+ messages in thread From: Kevin Dewald @ 2026-10-08 17:30 UTC (permalink / raw) To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald This prints the Role property of the LE bearer with the likes of info command: bluetoothctl> info <addr> ... LE.Connected: yes LE.Connectable: yes LE.Role: central Assisted-by: Claude:claude-opus-5.5 --- client/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.c b/client/main.c index f5fdd7d12..d2d25b9f4 100644 --- a/client/main.c +++ b/client/main.c @@ -2097,6 +2097,7 @@ static void cmd_info(int argc, char *argv[]) print_property_with_label(bearer, "Connected", "LE.Connected"); print_property_with_label(bearer, "Connectable", "LE.Connectable"); + print_property_with_label(bearer, "Role", "LE.Role"); } return bt_shell_noninteractive_quit(EXIT_SUCCESS); -- 2.54.0 (Apple Git-157) ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 2026-10-08 17:29 [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 Kevin Dewald ` (2 preceding siblings ...) 2026-10-08 17:30 ` [PATCH BlueZ v2 3/3] client: Print LE.Role in info Kevin Dewald @ 2026-10-08 19:10 ` Luiz Augusto von Dentz 2026-10-09 3:45 ` Kevin Dewald 3 siblings, 1 reply; 8+ messages in thread From: Luiz Augusto von Dentz @ 2026-10-08 19:10 UTC (permalink / raw) To: Kevin Dewald; +Cc: linux-bluetooth Hi Kevin, On Thu, Oct 8, 2026 at 1:30 PM Kevin Dewald <kevin@simpleble.org> wrote: > > Applications acting as a peripheral, or in both roles, cannot tell > whether a connected device is a central that connected to the adapter > or a peripheral the adapter connected to. When several applications > share the adapter, a device object can appear because of any of them, > so the order of events does not answer it either. > > bluetoothd already tracks this per bearer from the Device Connected > event. This series exposes it as a Role property on > org.bluez.Bearer.LE1, "central" or "peripheral", present only while > the device is connected over LE, and prints it as LE.Role in > bluetoothctl info. The documentation states that it is the link layer > role and says nothing about GATT client and server roles. > > Like the rest of the bearer interfaces, the property is experimental, > so applications only see it when bluetoothd runs with -E, which few > systems do. Is there a plan to promote the bearer interfaces, or some > of their properties, to stable? I would be glad to help with whatever > that needs. Good question. Perhaps we should consider marking them stable, but first we need to implement test automation using test-functional to ensure they are truly stable. > Tested with two btvirt controllers, where the advertising side reports > the other as "central" and the connecting side reports it as > "peripheral", and with a real adapter connecting to an nRF52840. The > property goes away when the connection does. For this type of testing we can use the test-functional framework nowadays, so we just have to create a few tests to validate our expectations. Prototyping something like doc/functional-bearer.rst for testing the interfaces. > Changes in v2: > - Move the property from org.bluez.Device1 to org.bluez.Bearer.LE1, so > it is clearly per connection (Luiz) > - State in the documentation that it says nothing about GATT roles > (Luiz) > > Kevin Dewald (3): > org.bluez.Bearer: Add Role property > bearer: Add Role property > client: Print LE.Role in info > > client/main.c | 1 + > doc/org.bluez.Bearer.LE.rst | 24 +++++++++++++++++++++ > src/bearer.c | 42 +++++++++++++++++++++++++++++++++++++ > src/device.c | 5 +++++ > src/device.h | 1 + > 5 files changed, 73 insertions(+) > > -- > 2.54.0 (Apple Git-157) > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 2026-10-08 19:10 ` [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 Luiz Augusto von Dentz @ 2026-10-09 3:45 ` Kevin Dewald 2026-10-09 13:42 ` Luiz Augusto von Dentz 0 siblings, 1 reply; 8+ messages in thread From: Kevin Dewald @ 2026-10-09 3:45 UTC (permalink / raw) To: Luiz Augusto von Dentz; +Cc: linux-bluetooth Hi Luiz, On Thu, Oct 8, 2026, Luiz Augusto von Dentz wrote: > Good question. Perhaps we should consider marking them stable, but > first we need to implement test automation using test-functional to > ensure they are truly stable. > > For this type of testing we can use the test-functional framework > nowadays, so we just have to create a few tests to validate our > expectations. Prototyping something like doc/functional-bearer.rst for > testing the interfaces. I can write those: a test/functional/test_bearer.py with a matching doc/functional-bearer.rst, covering Connect and Disconnect, Connected and the Disconnected signal, Paired and Bonded on both bearers, Connectable, and Role. Would you like them added to this series as a v3, or sent separately so this one can go in as it is? Kevin ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 2026-10-09 3:45 ` Kevin Dewald @ 2026-10-09 13:42 ` Luiz Augusto von Dentz 0 siblings, 0 replies; 8+ messages in thread From: Luiz Augusto von Dentz @ 2026-10-09 13:42 UTC (permalink / raw) To: Kevin Dewald; +Cc: linux-bluetooth Hi Kevin, On Thu, Oct 8, 2026 at 11:45 PM Kevin Dewald <kevin@simpleble.org> wrote: > > Hi Luiz, > > On Thu, Oct 8, 2026, Luiz Augusto von Dentz wrote: > > Good question. Perhaps we should consider marking them stable, but > > first we need to implement test automation using test-functional to > > ensure they are truly stable. > > > > For this type of testing we can use the test-functional framework > > nowadays, so we just have to create a few tests to validate our > > expectations. Prototyping something like doc/functional-bearer.rst for > > testing the interfaces. > > I can write those: a test/functional/test_bearer.py with a matching > doc/functional-bearer.rst, covering Connect and Disconnect, Connected > and the Disconnected signal, Paired and Bonded on both bearers, > Connectable, and Role. > > Would you like them added to this series as a v3, or sent separately so > this one can go in as it is? Either approach works; we only recommend splitting the series if it grows too large (20+ commits). > Kevin -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-10-09 13:43 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-08 17:29 [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 Kevin Dewald 2026-10-08 17:29 ` [PATCH BlueZ v2 1/3] org.bluez.Bearer: Add Role property Kevin Dewald 2026-10-08 22:35 ` Add Role property to org.bluez.Bearer.LE1 bluez.test.bot 2026-10-08 17:29 ` [PATCH BlueZ v2 2/3] bearer: Add Role property Kevin Dewald 2026-10-08 17:30 ` [PATCH BlueZ v2 3/3] client: Print LE.Role in info Kevin Dewald 2026-10-08 19:10 ` [PATCH BlueZ v2 0/3] Add Role property to org.bluez.Bearer.LE1 Luiz Augusto von Dentz 2026-10-09 3:45 ` Kevin Dewald 2026-10-09 13:42 ` 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