* [PATCH BlueZ v3 0/6] mgmt/device: report link security level to D-Bus clients
@ 2026-08-21 9:09 Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 1/6] mgmt: Add Security Level Changed event Frédéric Danis
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Frédéric Danis @ 2026-08-21 9:09 UTC (permalink / raw)
To: linux-bluetooth
This series adds connection security-level reporting.
The new MGMT_EV_SECURITY_LEVEL_CHANGED event [1] is documented and
org.bluez.Device1 is updates with new experimental read-only properties
SecurityLevel and EncryptionType.
Those properties can be displayed using "bluetoothctl info".
This is intended to let clients (including test tooling such as btpclient)
observe effective link security changes.
[1] https://lore.kernel.org/all/20260805132203.176213-1-frederic.danis@collabora.com/
v1->v2: Fix struct mgmt_ev_security_level_changed definition
v2->v3: Re-work Security Level possible values in mgmt-protocol.rst to be in
with other *-protocol.rst files
Frédéric Danis (6):
mgmt: Add Security Level Changed event
mgmt-tester: Add Security Level Changed event tests
monitor: Add support for Mgmt Security Level changed event
device: Add SecurityLevel properties to org.bluez.Device1
org.bluez.Device: Add Security Level related properties
client: Display SecurityLevel in device info
client/main.c | 2 +
doc/mgmt-protocol.rst | 45 +++++++++++++
doc/org.bluez.Device.rst | 36 +++++++++++
lib/bluetooth/mgmt.h | 15 +++++
monitor/packet.c | 117 ++++++++++++++++++++++++++++++++++
src/adapter.c | 33 ++++++++++
src/device.c | 84 +++++++++++++++++++++++++
src/device.h | 3 +
tools/mgmt-tester.c | 133 +++++++++++++++++++++++++++++++++++++++
9 files changed, 468 insertions(+)
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH BlueZ v3 1/6] mgmt: Add Security Level Changed event
2026-08-21 9:09 [PATCH BlueZ v3 0/6] mgmt/device: report link security level to D-Bus clients Frédéric Danis
@ 2026-08-21 9:09 ` Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 2/6] mgmt-tester: Add Security Level Changed event tests Frédéric Danis
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Frédéric Danis @ 2026-08-21 9:09 UTC (permalink / raw)
To: linux-bluetooth
This provides a TLV list of values related to the security level of
the connection to a remote device.
Currently Security Level and Encryption type are implemented.
---
v1->v2: Fix struct mgmt_ev_security_level_changed definition
v2->v3: Re-work Security Level possible values in mgmt-protocol.rst to be in
with other *-protocol.rst files
doc/mgmt-protocol.rst | 45 +++++++++++++++++++++++++++++++++++++++++++
lib/bluetooth/mgmt.h | 15 +++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/doc/mgmt-protocol.rst b/doc/mgmt-protocol.rst
index f0564075f..983ffc3aa 100644
--- a/doc/mgmt-protocol.rst
+++ b/doc/mgmt-protocol.rst
@@ -5521,3 +5521,48 @@ The Supervision_Timeout parameter specifies the supervision timeout in units
of 10 ms.
This event will be sent to all management sockets.
+
+Security Level Changed
+``````````````````````
+
+:Event Code: 0x0034
+:Controller Index: <controller_id>
+:Event Parameters: Address (6 Octets)
+:...: Address_Type (1 Octet)
+:...: Count (1 Octet)
+:...: TLV_List (variable)
+
+This event indicates that the security level of a device has changed.
+
+Possible values for the TLV type parameter:
+
+.. csv-table::
+ :header: "Type", "Description"
+ :widths: auto
+
+ 0x0000, Security Level
+ 0x0001, Encryption type
+
+Possible values for the Security Level type:
+
+.. csv-table::
+ :header: "Value", "Security Level", "Link Key Type", "Encryption"
+ :widths: auto
+
+ **BT_SECURITY_SDP**, 0 (SDP Only), None, Not required
+ **BT_SECURITY_LOW**, 1 (Low), Unauthenticated, Not required
+ **BT_SECURITY_MEDIUM**, 2 (Medium - default), Unauthenticated, Desired
+ **BT_SECURITY_HIGH**, 3 (High), Authenticated, Required
+ **BT_SECURITY_FIPS** (since Linux 3.15), 4 (Secure Only), Authenticated (P-256 based Secure Simple Pairing and Secure Authentication), Required
+
+Possible values for the Encryption type:
+
+.. csv-table::
+ :header: "Value", "Description"
+ :widths: auto
+
+ 0x00, No encryption
+ 0x01, E0 encryption
+ 0x02, AES-CCM encryption
+
+This event will be sent to all management sockets.
diff --git a/lib/bluetooth/mgmt.h b/lib/bluetooth/mgmt.h
index 9df0c1ba2..7b98ff8a9 100644
--- a/lib/bluetooth/mgmt.h
+++ b/lib/bluetooth/mgmt.h
@@ -1136,6 +1136,20 @@ struct mgmt_ev_conn_subrate {
uint16_t supv_timeout;
} __packed;
+#define MGMT_CONN_SEC_ENCRYPT_NONE 0x00
+#define MGMT_CONN_SEC_ENCRYPT_E0 0x01
+#define MGMT_CONN_SEC_ENCRYPT_AES_CCM 0x02
+
+#define MGMT_SEC_LEVEL_CHANGED_PARAM_LEVEL 0x0000
+#define MGMT_SEC_LEVEL_CHANGED_PARAM_ENC_TYPE 0x0001
+
+#define MGMT_EV_SECURITY_LEVEL_CHANGED 0x0034
+struct mgmt_ev_security_level_changed {
+ struct mgmt_addr_info addr;
+ uint8_t tlv_count;
+ uint8_t tlv_data[];
+} __packed;
+
static const char *mgmt_op[] = {
"<0x0000>",
"Read Version",
@@ -1285,6 +1299,7 @@ static const char *mgmt_ev[] = {
"Mesh Packet Found",
"Mesh Packet Complete",
"Connection Subrate",
+ "Security Level Changed",
};
static const char *mgmt_status[] = {
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ v3 2/6] mgmt-tester: Add Security Level Changed event tests
2026-08-21 9:09 [PATCH BlueZ v3 0/6] mgmt/device: report link security level to D-Bus clients Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 1/6] mgmt: Add Security Level Changed event Frédéric Danis
@ 2026-08-21 9:09 ` Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 3/6] monitor: Add support for Mgmt Security Level changed event Frédéric Danis
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Frédéric Danis @ 2026-08-21 9:09 UTC (permalink / raw)
To: linux-bluetooth
Test that MGMT_EV_SECURITY_LEVEL_CHANGED is correctly received during
BREDR and LE secured connection.
Assisted-by: GPT:GPT-5.3-Codex
---
tools/mgmt-tester.c | 133 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 133 insertions(+)
diff --git a/tools/mgmt-tester.c b/tools/mgmt-tester.c
index 4b432002d..bd8b67209 100644
--- a/tools/mgmt-tester.c
+++ b/tools/mgmt-tester.c
@@ -3776,6 +3776,110 @@ static bool verify_link_key(const void *param, uint16_t length)
return true;
}
+static bool verify_security_level_changed(const void *param, uint16_t length)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *event = param;
+ const uint8_t *expected_addr;
+ uint8_t expected_addr_type;
+ uint8_t expected_enc_type;
+ uint8_t tlv_count;
+ uint8_t i;
+ uint16_t offset;
+ bool saw_level = false;
+ bool saw_enc_type = false;
+
+ if (length < sizeof(struct mgmt_addr_info) + 1) {
+ tester_warn("Invalid security level changed length %u", length);
+ return false;
+ }
+
+ expected_addr = hciemu_get_client_bdaddr(data->hciemu);
+ if (!expected_addr) {
+ tester_warn("No central bdaddr");
+ return false;
+ }
+
+ expected_addr_type = data->hciemu_type == HCIEMU_TYPE_LE ?
+ BDADDR_LE_PUBLIC : BDADDR_BREDR;
+ expected_enc_type = data->hciemu_type == HCIEMU_TYPE_LE ?
+ MGMT_CONN_SEC_ENCRYPT_NONE :
+ MGMT_CONN_SEC_ENCRYPT_E0;
+
+ if (memcmp(event, expected_addr, 6)) {
+ tester_warn("Unexpected security level changed address");
+ return false;
+ }
+
+ if (event[6] != expected_addr_type) {
+ tester_warn("Unexpected security level changed address type %u != %u",
+ event[6], expected_addr_type);
+ return false;
+ }
+
+ tlv_count = event[7];
+ offset = sizeof(struct mgmt_addr_info) + 1;
+
+ for (i = 0; i < tlv_count; i++) {
+ const struct mgmt_tlv *tlv;
+ uint16_t type;
+
+ if (offset + sizeof(*tlv) > length) {
+ tester_warn("Malformed security level changed TLV header");
+ return false;
+ }
+
+ tlv = (const struct mgmt_tlv *)(event + offset);
+ type = get_le16(&tlv->type);
+
+ if (offset + sizeof(*tlv) + tlv->length > length) {
+ tester_warn("Malformed security level changed TLV payload");
+ return false;
+ }
+
+ switch (type) {
+ case MGMT_SEC_LEVEL_CHANGED_PARAM_LEVEL:
+ if (tlv->length != 1) {
+ tester_warn("Invalid security level TLV length %u",
+ tlv->length);
+ return false;
+ }
+ saw_level = true;
+ break;
+ case MGMT_SEC_LEVEL_CHANGED_PARAM_ENC_TYPE:
+ if (tlv->length != 1) {
+ tester_warn("Invalid encryption type TLV length %u",
+ tlv->length);
+ return false;
+ }
+
+ if (tlv->value[0] != expected_enc_type) {
+ tester_warn("Unexpected encryption type %u != %u",
+ tlv->value[0],
+ expected_enc_type);
+ return false;
+ }
+
+ saw_enc_type = true;
+ break;
+ }
+
+ offset += sizeof(*tlv) + tlv->length;
+ }
+
+ if (offset != length) {
+ tester_warn("Unexpected security level changed trailing bytes");
+ return false;
+ }
+
+ if (!saw_level || !saw_enc_type) {
+ tester_warn("Missing expected security level changed TLVs");
+ return false;
+ }
+
+ return true;
+}
+
static uint16_t settings_powered_le_sc_bondable[] = {
MGMT_OP_SET_LE,
MGMT_OP_SET_SSP,
@@ -3879,6 +3983,19 @@ static const struct generic_data pairing_acceptor_ssp_1 = {
.just_works = true,
};
+static const struct generic_data pairing_acceptor_ssp_sec_level_changed = {
+ .setup_settings = settings_powered_connectable_bondable_ssp,
+ .client_enable_ssp = true,
+ .expect_alt_ev = MGMT_EV_SECURITY_LEVEL_CHANGED,
+ .expect_alt_ev_len = 16,
+ .verify_alt_ev_func = verify_security_level_changed,
+ .expect_hci_command = BT_HCI_CMD_USER_CONFIRM_REQUEST_REPLY,
+ .expect_hci_func = client_bdaddr_param_func,
+ .io_cap = 0x03, /* NoInputNoOutput */
+ .client_io_cap = 0x03, /* NoInputNoOutput */
+ .just_works = true,
+};
+
static const struct generic_data pairing_acceptor_ssp_2 = {
.setup_settings = settings_powered_connectable_bondable_ssp,
.client_enable_ssp = true,
@@ -3986,6 +4103,16 @@ static const struct generic_data pairing_acceptor_le_1 = {
.verify_alt_ev_func = verify_ltk,
};
+static const struct generic_data pairing_acceptor_le_sec_level_changed = {
+ .setup_settings = settings_powered_bondable_connectable_advertising,
+ .io_cap = 0x03, /* NoInputNoOutput */
+ .client_io_cap = 0x03, /* NoInputNoOutput */
+ .just_works = true,
+ .expect_alt_ev = MGMT_EV_SECURITY_LEVEL_CHANGED,
+ .expect_alt_ev_len = 16,
+ .verify_alt_ev_func = verify_security_level_changed,
+};
+
static const struct generic_data pairing_acceptor_le_2 = {
.setup_settings = settings_powered_bondable_connectable_advertising,
.io_cap = 0x04, /* KeyboardDisplay */
@@ -13832,6 +13959,9 @@ int main(int argc, char *argv[])
test_bredrle("Pairing Acceptor - SSP 1",
&pairing_acceptor_ssp_1, setup_pairing_acceptor,
test_pairing_acceptor);
+ test_bredrle("Pairing Acceptor - SSP Security Level Changed",
+ &pairing_acceptor_ssp_sec_level_changed,
+ setup_pairing_acceptor, test_pairing_acceptor);
test_bredrle("Pairing Acceptor - SSP 2",
&pairing_acceptor_ssp_2, setup_pairing_acceptor,
test_pairing_acceptor);
@@ -13850,6 +13980,9 @@ int main(int argc, char *argv[])
test_le("Pairing Acceptor - LE 1",
&pairing_acceptor_le_1, setup_pairing_acceptor,
test_pairing_acceptor);
+ test_le("Pairing Acceptor - LE Security Level Changed",
+ &pairing_acceptor_le_sec_level_changed,
+ setup_pairing_acceptor, test_pairing_acceptor);
test_le("Pairing Acceptor - LE 2",
&pairing_acceptor_le_2, setup_pairing_acceptor,
test_pairing_acceptor);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ v3 3/6] monitor: Add support for Mgmt Security Level changed event
2026-08-21 9:09 [PATCH BlueZ v3 0/6] mgmt/device: report link security level to D-Bus clients Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 1/6] mgmt: Add Security Level Changed event Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 2/6] mgmt-tester: Add Security Level Changed event tests Frédéric Danis
@ 2026-08-21 9:09 ` Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 4/6] device: Add SecurityLevel properties to org.bluez.Device1 Frédéric Danis
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Frédéric Danis @ 2026-08-21 9:09 UTC (permalink / raw)
To: linux-bluetooth
@ MGMT Event: Security Level Changed (0x0034) plen 16
BR/EDR Address: 00:AA:01:01:00:00 (Intel Corporation)
Count: 2
Security Level: No security (0x00000000)
Encryption Type: No encryption (0x00000000)
---
monitor/packet.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/monitor/packet.c b/monitor/packet.c
index 0d3b23cc3..217fcdad1 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -17680,6 +17680,121 @@ static void mgmt_conn_subrate_evt(const void *data, uint16_t size)
print_field("Supervision timeout: %u", supv_timeout);
}
+static void mgmt_print_security_level(const char *desc, uint32_t value)
+{
+ const char *level;
+
+ switch (value) {
+ case BT_SECURITY_SDP:
+ level = "No security";
+ break;
+ case BT_SECURITY_LOW:
+ level = "Unauthenticated pairing with encryption not required";
+ break;
+ case BT_SECURITY_MEDIUM:
+ level = "Unauthenticated pairing with encryption desired";
+ break;
+ case BT_SECURITY_HIGH:
+ level = "Authenticated pairing with encryption";
+ break;
+ case BT_SECURITY_FIPS:
+ level = "FIPS authenticated pairing with encryption";
+ break;
+ default:
+ level = "Reserved";
+ break;
+ }
+
+ print_field("%s: %s (0x%8.8x)", desc, level, value);
+}
+
+static void mgmt_print_encryption_type(const char *desc, uint32_t value)
+{
+ const char *type;
+
+ switch (value) {
+ case MGMT_CONN_SEC_ENCRYPT_NONE:
+ type = "No encryption";
+ break;
+ case MGMT_CONN_SEC_ENCRYPT_E0:
+ type = "E0";
+ break;
+ case MGMT_CONN_SEC_ENCRYPT_AES_CCM:
+ type = "AES-CCM";
+ break;
+ default:
+ type = "Reserved";
+ break;
+ }
+
+ print_field("%s: %s (0x%8.8x)", desc, type, value);
+}
+
+static void mgmt_print_sec_level_tlv(void *data, void *user_data)
+{
+ const struct mgmt_tlv *entry = data;
+ uint16_t type = get_le16(&entry->type);
+ const char *desc = default_system_config(type);
+ uint32_t value;
+ char buf[8];
+
+ switch (type) {
+ case MGMT_SEC_LEVEL_CHANGED_PARAM_LEVEL:
+ desc = "Security Level";
+ break;
+ case MGMT_SEC_LEVEL_CHANGED_PARAM_ENC_TYPE:
+ desc = "Encryption Type";
+ break;
+ default:
+ snprintf(buf, sizeof(buf), "0x%4.4x", entry->type);
+ desc = buf;
+ break;
+ }
+
+ if (entry->length == 1 || entry->length == 2 || entry->length == 4) {
+ if (entry->length == 1)
+ value = get_u8(entry->value);
+ else if (entry->length == 2)
+ value = get_le16(entry->value);
+ else
+ value = get_le32(entry->value);
+
+ switch (type) {
+ case MGMT_SEC_LEVEL_CHANGED_PARAM_LEVEL:
+ mgmt_print_security_level(desc, value);
+ break;
+ case MGMT_SEC_LEVEL_CHANGED_PARAM_ENC_TYPE:
+ mgmt_print_encryption_type(desc, value);
+ break;
+ default:
+ print_field("%s: %u", desc, value);
+ break;
+ }
+ } else {
+ print_hex_field(desc, entry->value, entry->length);
+ }
+}
+
+static void mgmt_security_level_changed_evt(const void *data, uint16_t size)
+{
+ const uint8_t *addr = data;
+ uint8_t addr_type = get_u8(data + 6);
+ uint8_t count = get_u8(data + 7);
+ struct mgmt_tlv_list *tlv_list;
+
+ mgmt_print_address(addr, addr_type);
+ print_field("Count: %d", count);
+
+ tlv_list = mgmt_tlv_list_load_from_buf(data + 8, size - 8);
+ if (!tlv_list) {
+ print_text(COLOR_ERROR, " Unable to parse security level "
+ "changed event");
+ return;
+ }
+ mgmt_tlv_list_foreach(tlv_list, mgmt_print_sec_level_tlv, NULL);
+ mgmt_tlv_list_free(tlv_list);
+}
+
static const struct mgmt_data mgmt_event_table[] = {
{ 0x0001, "Command Complete",
mgmt_command_complete_evt, 3, false },
@@ -17779,6 +17894,8 @@ static const struct mgmt_data mgmt_event_table[] = {
mgmt_mesh_packet_cmplt_evt, 1, true },
{ 0x0033, "Connection Subrate",
mgmt_conn_subrate_evt, 18, true },
+ { 0x0034, "Security Level Changed",
+ mgmt_security_level_changed_evt, 8, false },
{ }
};
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ v3 4/6] device: Add SecurityLevel properties to org.bluez.Device1
2026-08-21 9:09 [PATCH BlueZ v3 0/6] mgmt/device: report link security level to D-Bus clients Frédéric Danis
` (2 preceding siblings ...)
2026-08-21 9:09 ` [PATCH BlueZ v3 3/6] monitor: Add support for Mgmt Security Level changed event Frédéric Danis
@ 2026-08-21 9:09 ` Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 5/6] org.bluez.Device: Add Security Level related properties Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 6/6] client: Display SecurityLevel in device info Frédéric Danis
5 siblings, 0 replies; 7+ messages in thread
From: Frédéric Danis @ 2026-08-21 9:09 UTC (permalink / raw)
To: linux-bluetooth
This uses the new MGMT_EV_SECURITY_LEVEL_CHANGED event.
It will be used by btpclient to reduce test time.
---
src/adapter.c | 33 ++++++++++++++++++++
src/device.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/device.h | 3 ++
3 files changed, 120 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index c21b3e7fb..2fd5e005e 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -10036,6 +10036,34 @@ static void unpaired_callback(uint16_t index, uint16_t length,
device_set_unpaired(device, ev->addr.type);
}
+static void device_sec_level_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_ev_security_level_changed *ev = param;
+ struct btd_adapter *adapter = user_data;
+ struct btd_device *dev;
+ char addr[18];
+
+ if (length < sizeof(*ev)) {
+ btd_error(adapter->dev_id,
+ "Too small Device Security Level Changed event: %d",
+ length);
+ return;
+ }
+
+ ba2str(&ev->addr.bdaddr, addr);
+
+ dev = btd_adapter_find_device(adapter, &ev->addr.bdaddr, ev->addr.type);
+ if (!dev) {
+ btd_error(adapter->dev_id,
+ "Device Security Level Changed for unknown device %s",
+ addr);
+ return;
+ }
+
+ btd_device_sec_level_changed(dev, ev->tlv_data, length - 8);
+}
+
static void clear_devices_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -10754,6 +10782,11 @@ static void read_info_complete(uint8_t status, uint16_t length,
controller_resume_callback,
adapter, NULL);
+ mgmt_register(adapter->mgmt, MGMT_EV_SECURITY_LEVEL_CHANGED,
+ adapter->dev_id,
+ device_sec_level_callback,
+ adapter, NULL);
+
set_dev_class(adapter);
set_name(adapter, btd_adapter_get_name(adapter));
diff --git a/src/device.c b/src/device.c
index 65d84be56..c6cb0aecf 100644
--- a/src/device.c
+++ b/src/device.c
@@ -306,6 +306,9 @@ struct btd_device {
uint32_t auth_failures;
guint auth_retry_id;
+
+ uint8_t sec_level;
+ uint8_t enc_type;
};
static const uint16_t uuid_list[] = {
@@ -3689,6 +3692,26 @@ dev_property_prefer_bearer_exists(const GDBusPropertyTable *property,
return device_prefer_bearer_str(device) != NULL;
}
+static gboolean dev_get_security_level(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *dev = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &dev->sec_level);
+
+ return TRUE;
+}
+
+static gboolean dev_get_encryption_type(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *dev = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &dev->enc_type);
+
+ return TRUE;
+}
+
static const GDBusPropertyTable device_properties[] = {
{ "Address", "s", dev_property_get_address },
{ "AddressType", "s", property_get_address_type },
@@ -3732,6 +3755,10 @@ static const GDBusPropertyTable device_properties[] = {
dev_property_set_prefer_bearer,
dev_property_prefer_bearer_exists,
G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+ { "SecurityLevel", "y", dev_get_security_level, NULL, NULL,
+ G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+ { "EncryptionType", "y", dev_get_encryption_type, NULL, NULL,
+ G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
{ }
};
@@ -8341,3 +8368,60 @@ next:
l = next;
}
}
+
+static void parse_sec_level_tlv(void *data, void *user_data)
+{
+ struct btd_device *dev = user_data;
+ const struct mgmt_tlv *entry = data;
+ uint16_t type = get_le16(&entry->type);
+ uint32_t value;
+
+ if (entry->length != 1 && entry->length != 2 && entry->length != 4) {
+ warn("Invalid length %u for security level TLV type %u",
+ entry->length, type);
+ return;
+ }
+
+ if (entry->length == 1)
+ value = get_u8(entry->value);
+ else if (entry->length == 2)
+ value = get_le16(entry->value);
+ else
+ value = get_le32(entry->value);
+
+ switch (type) {
+ case MGMT_SEC_LEVEL_CHANGED_PARAM_LEVEL:
+ if (dev->sec_level != value) {
+ dev->sec_level = value;
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE,
+ "SecurityLevel");
+ }
+ break;
+ case MGMT_SEC_LEVEL_CHANGED_PARAM_ENC_TYPE:
+ if (dev->enc_type != value) {
+ dev->enc_type = value;
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE,
+ "EncryptionType");
+ }
+ break;
+ default:
+ DBG("Unknown security level TLV type %u", type);
+ break;
+ }
+}
+
+void btd_device_sec_level_changed(struct btd_device *dev, const uint8_t *data,
+ uint16_t size)
+{
+ struct mgmt_tlv_list *tlv_list;
+
+ tlv_list = mgmt_tlv_list_load_from_buf(data, size);
+ if (!tlv_list) {
+ error("Failed to parse security level TLV list");
+ return;
+ }
+ mgmt_tlv_list_foreach(tlv_list, parse_sec_level_tlv, dev);
+ mgmt_tlv_list_free(tlv_list);
+}
diff --git a/src/device.h b/src/device.h
index b890f23d4..3dff67eb0 100644
--- a/src/device.h
+++ b/src/device.h
@@ -245,3 +245,6 @@ void btd_device_foreach_service(struct btd_device *dev,
void *user_data);
void device_remove_pending_services(struct btd_device *dev,
uint8_t bdaddr_type);
+
+void btd_device_sec_level_changed(struct btd_device *dev, const uint8_t *data,
+ uint16_t size);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ v3 5/6] org.bluez.Device: Add Security Level related properties
2026-08-21 9:09 [PATCH BlueZ v3 0/6] mgmt/device: report link security level to D-Bus clients Frédéric Danis
` (3 preceding siblings ...)
2026-08-21 9:09 ` [PATCH BlueZ v3 4/6] device: Add SecurityLevel properties to org.bluez.Device1 Frédéric Danis
@ 2026-08-21 9:09 ` Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 6/6] client: Display SecurityLevel in device info Frédéric Danis
5 siblings, 0 replies; 7+ messages in thread
From: Frédéric Danis @ 2026-08-21 9:09 UTC (permalink / raw)
To: linux-bluetooth
This adds the SecurityLevel and EncryptionType properties which can be
used by clients to get the security level and encryption type in use
for a connection.
---
doc/org.bluez.Device.rst | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/doc/org.bluez.Device.rst b/doc/org.bluez.Device.rst
index 3e6a30aaf..5120dbede 100644
--- a/doc/org.bluez.Device.rst
+++ b/doc/org.bluez.Device.rst
@@ -478,3 +478,39 @@ Possible values:
Examples:
:bluetoothctl: > bearer <dev> [last-seen/bredr/le]
+
+byte SecurityLevel [readonly, experimental]
+```````````````````````````````````````````
+Indicate the Security Level of a connection.
+
+Possible values:
+
+:0:
+ No security
+
+:1:
+ Unauthenticated pairing with encryption not required
+
+:2:
+ Unauthenticated pairing with encryption desired
+
+:3:
+ Authenticated pairing with encryption
+
+:4:
+ FIPS authenticated pairing with encryption
+
+byte EncryptionType [readonly, experimental]
+````````````````````````````````````````````
+Indicate the Encryption type in use for a connection.
+
+Possible values:
+
+:0:
+ No encryption
+
+:1:
+ E0 encryption
+
+:2:
+ AES-CCM encryption
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ v3 6/6] client: Display SecurityLevel in device info
2026-08-21 9:09 [PATCH BlueZ v3 0/6] mgmt/device: report link security level to D-Bus clients Frédéric Danis
` (4 preceding siblings ...)
2026-08-21 9:09 ` [PATCH BlueZ v3 5/6] org.bluez.Device: Add Security Level related properties Frédéric Danis
@ 2026-08-21 9:09 ` Frédéric Danis
5 siblings, 0 replies; 7+ messages in thread
From: Frédéric Danis @ 2026-08-21 9:09 UTC (permalink / raw)
To: linux-bluetooth
---
client/main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/client/main.c b/client/main.c
index 069e20485..0531c9de1 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1918,6 +1918,8 @@ static void cmd_info(int argc, char *argv[])
print_property(proxy, "WakeAllowed");
print_property(proxy, "LegacyPairing");
print_property(proxy, "CablePairing");
+ print_property(proxy, "SecurityLevel");
+ print_property(proxy, "EncryptionType");
print_uuids(proxy);
print_property(proxy, "Modalias");
print_property(proxy, "ManufacturerData");
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-21 9:09 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-21 9:09 [PATCH BlueZ v3 0/6] mgmt/device: report link security level to D-Bus clients Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 1/6] mgmt: Add Security Level Changed event Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 2/6] mgmt-tester: Add Security Level Changed event tests Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 3/6] monitor: Add support for Mgmt Security Level changed event Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 4/6] device: Add SecurityLevel properties to org.bluez.Device1 Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 5/6] org.bluez.Device: Add Security Level related properties Frédéric Danis
2026-08-21 9:09 ` [PATCH BlueZ v3 6/6] client: Display SecurityLevel in device info Frédéric Danis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox