* [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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ messages in thread
* RE: Add Role property to org.bluez.Bearer.LE1
2026-10-09 18:04 [PATCH BlueZ v3 1/5] org.bluez.Bearer: Add Role property Kevin Dewald
@ 2026-10-09 21:01 ` bluez.test.bot
0 siblings, 0 replies; 9+ messages in thread
From: bluez.test.bot @ 2026-10-09 21:01 UTC (permalink / raw)
To: linux-bluetooth, kevin
[-- Attachment #1: Type: text/plain, Size: 1022 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/1182613/
---Test result---
Test Summary:
CheckPatch PASS 2.34 seconds
GitLint PASS 1.64 seconds
BuildEll PASS 20.03 seconds
BluezMake PASS 388.62 seconds
MakeCheck PASS 14.38 seconds
MakeDistcheck PASS 145.70 seconds
CheckValgrind PASS 234.83 seconds
CheckSmatch PASS 296.08 seconds
bluezmakeextell PASS 95.20 seconds
TestFunctional PASS 1219.26 seconds
IncrementalBuild PASS 440.58 seconds
ScanBuild PASS 1152.57 seconds
https://github.com/bluez/bluez/pull/2645
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-10-09 21:01 UTC | newest]
Thread overview: 9+ 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
-- strict thread matches above, loose matches on Subject: below --
2026-10-09 18:04 [PATCH BlueZ v3 1/5] org.bluez.Bearer: Add Role property Kevin Dewald
2026-10-09 21:01 ` Add Role property to org.bluez.Bearer.LE1 bluez.test.bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox