* [PATCH BlueZ v1 2/2] monitor: Add decoding support for HIDS 1.1 flags and attributes
2026-04-30 19:51 [PATCH BlueZ v1 1/2] shared/util: Add decoding support for HIDS 1.1 UUIDs Luiz Augusto von Dentz
@ 2026-04-30 19:51 ` Luiz Augusto von Dentz
2026-04-30 20:54 ` [BlueZ,v1,1/2] shared/util: Add decoding support for HIDS 1.1 UUIDs bluez.test.bot
2026-05-01 14:10 ` [PATCH BlueZ v1 1/2] " patchwork-bot+bluetooth
2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2026-04-30 19:51 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds support for HIDS 1.1 SCI flags and attributes:
> LE-ACL: Handle 2048 flags 0x02 dlen 9
ATT: Read Response (0x0b) len 4
Handle: 0x0021 Type: HID Information (0x2a4a)
Value[4]:
11 01 00 0f ....
bcdHID: 0x0111
bCountryCode: 0x00
Flags: 0x0f
RemoteWake (0x01)
NormallyConnectable (0x02)
SCI Supported (0x04)
SCI Low Power Mode Supported (0x08)
< LE-ACL: Handle 2048 flags 0x00 dlen 7
ATT: Read Request (0x0a) len 2
Handle: 0x003d Type: HID SCI Information (0x2c3a)
> LE-ACL: Handle 2048 flags 0x02 dlen 19
ATT: Read Response (0x0b) len 14
Handle: 0x003d Type: HID SCI Information (0x2c3a)
Value[14]:
08 02 0a 00 14 00 0a 00 08 00 08 00 08 00 ..............
Minimum Supported Connection Interval: 1.000 ms (0x08)
Number of Supported Subgroups: 2
Minimum Connection Interval[0]: 1.250 ms (0x000a)
Maximum Connection Interval[0]: 2.500 ms (0x0014)
Connection Interval Stride[0]: 1.250 ms (0x000a)
Minimum Connection Interval[1]: 1.000 ms (0x0008)
Maximum Connection Interval[1]: 1.000 ms (0x0008)
Connection Interval Stride[1]: 1.000 ms (0x0008)
< LE-ACL: Handle 2048 flags 0x00 dlen 7
ATT: Read Request (0x0a) len 2
Handle: 0x003f Type: HID SCI Mode (0x2c39)
> LE-ACL: Handle 2048 flags 0x02 dlen 6
ATT: Read Response (0x0b) len 1
Handle: 0x003f Type: HID SCI Mode (0x2c39)
Value[1]:
00 .
Mode: None (0x00)
---
monitor/att.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++--
src/main.conf | 2 +-
2 files changed, 113 insertions(+), 4 deletions(-)
diff --git a/monitor/att.c b/monitor/att.c
index e8e0d499a826..03d46634fe17 100644
--- a/monitor/att.c
+++ b/monitor/att.c
@@ -4522,8 +4522,10 @@ static void ras_data_overwritten_notify(const struct l2cap_frame *frame)
ras_data_overwritten_notify)
static const struct bitfield_data hog_info_flags[] = {
- { 0, "RemoteWake (0x01)" },
- { 1, "NormallyConnectable (0x02)" },
+ { 0, "RemoteWake (0x01)" },
+ { 1, "NormallyConnectable (0x02)" },
+ { 2, "SCI Supported (0x04)" },
+ { 3, "SCI Low Power Mode Supported (0x08)" },
{ }
};
@@ -4598,9 +4600,116 @@ done:
print_hex_field(" Data", frame->data, frame->size);
}
+static void print_sci_mode(const struct l2cap_frame *frame)
+{
+ uint8_t mode;
+
+ if (!l2cap_frame_get_u8((void *)frame, &mode)) {
+ print_text(COLOR_ERROR, " Mode: invalid size");
+ goto done;
+ }
+
+ switch (mode) {
+ case 0x00:
+ print_field(" Mode: None (0x00)");
+ break;
+ case 0x02:
+ print_field(" Mode: SCI Default Mode (0x02)");
+ break;
+ case 0x03:
+ print_field(" Mode: SCI Fast Mode (0x03)");
+ break;
+ case 0x04:
+ print_field(" Mode: SCI Low Power Mode (0x04)");
+ break;
+ case 0x05:
+ print_field(" Mode: SCI Full Range Mode (0x04)");
+ break;
+ default:
+ print_field(" Mode: Reserved (0x%2.2x)", mode);
+ break;
+ }
+
+done:
+ if (frame->size)
+ print_hex_field(" Data", frame->data, frame->size);
+}
+
+static void hog_sci_mode_read(const struct l2cap_frame *frame)
+{
+ print_sci_mode(frame);
+}
+
+static void hog_sci_mode_notify(const struct l2cap_frame *frame)
+{
+ print_sci_mode(frame);
+}
+
+static void hog_sci_info_read(const struct l2cap_frame *frame)
+{
+ uint8_t min_conn_interval;
+ uint8_t num_grps;
+ uint8_t i;
+
+ if (!l2cap_frame_get_u8((void *)frame, &min_conn_interval)) {
+ print_text(COLOR_ERROR, " Minimum Supported Connection "
+ "Interval: invalid size");
+ goto done;
+ }
+
+ print_field(" Minimum Supported Connection Interval: %.3f ms "
+ "(0x%2.2x) ", min_conn_interval * 0.125, min_conn_interval);
+
+ if (!l2cap_frame_get_u8((void *)frame, &num_grps)) {
+ print_text(COLOR_ERROR, " Number of Supported Subgroups: "
+ "invalid size");
+ goto done;
+ }
+
+ print_field(" Number of Supported Subgroups: %d", num_grps);
+
+ for (i = 0; i < num_grps; i++) {
+ uint16_t min, max, stride;
+
+ if (!l2cap_frame_get_le16((void *)frame, &min)) {
+ print_text(COLOR_ERROR, " group[%u]: Minimum "
+ "Connection Interval: invalid size",
+ i);
+ goto done;
+ }
+
+ if (!l2cap_frame_get_le16((void *)frame, &max)) {
+ print_text(COLOR_ERROR, " group[%u]: Maximum "
+ "Connection Interval: invalid size",
+ i);
+ goto done;
+ }
+
+ if (!l2cap_frame_get_le16((void *)frame, &stride)) {
+ print_text(COLOR_ERROR, " group[%u]: Connection "
+ "Interval Stride: invalid size",
+ i);
+ goto done;
+ }
+
+ print_field(" Minimum Connection Interval[%u]: %.3f ms "
+ "(0x%4.4x)", i, min * 0.125, min);
+ print_field(" Maximum Connection Interval[%u]: %.3f ms "
+ "(0x%4.4x)", i, max * 0.125, max);
+ print_field(" Connection Interval Stride[%u]: %.3f ms "
+ "(0x%4.4x)", i, stride * 0.125, stride);
+ }
+
+done:
+ if (frame->size)
+ print_hex_field(" Data", frame->data, frame->size);
+}
+
#define HIDS \
GATT_HANDLER(0x2a4a, hog_info_read, NULL, NULL), \
- GATT_HANDLER(0x2a4c, NULL, hog_cp_write, NULL)
+ GATT_HANDLER(0x2a4c, NULL, hog_cp_write, NULL), \
+ GATT_HANDLER(0x2c39, hog_sci_mode_read, NULL, hog_sci_mode_notify), \
+ GATT_HANDLER(0x2c3a, hog_sci_info_read, NULL, NULL)
#define GATT_HANDLER(_uuid, _read, _write, _notify) \
{ \
diff --git a/src/main.conf b/src/main.conf
index 5846ef92d98d..39584e225c38 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -289,7 +289,7 @@
# Export claimed services by plugins
# Possible values: no, read-only, read-write
# Default: read-only
-#ExportClaimedServices = read-only
+ExportClaimedServices = read-write
# Security level:
# Sets security level of ATT channel, setting security anything other than
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread