diff --git a/lib/logitech_receiver/base.py b/lib/logitech_receiver/base.py index 0bbe5f88..47a76a16 100644 --- a/lib/logitech_receiver/base.py +++ b/lib/logitech_receiver/base.py @@ -107,6 +107,8 @@ _CENTURION_MSG_SIZE = 63 # max reconstructed message size after unwrapping (2 + # Set of handles that use Centurion framing _centurion_handles: set[int] = set() +# Raw Centurion protocol version (major, minor) by handle, from ping response +_centurion_protocol_versions: dict[int, tuple[int, int]] = {} """Default timeout on read (in seconds).""" @@ -300,6 +302,7 @@ def close(handle): try: if isinstance(handle, int): _centurion_handles.discard(handle) + _centurion_protocol_versions.pop(handle, None) hidapi.close(handle) else: handle.close() @@ -715,7 +718,11 @@ def ping(handle, devnumber, long_message: bool = False): mark_ok = is_centurion or reply_data[4:5] == request_data[-1:] if reply_data[:2] == request_data[:2] and mark_ok: # HID++ 2.0+ device, currently connected - return ord(reply_data[2:3]) + ord(reply_data[3:4]) / 10.0 + major = ord(reply_data[2:3]) + minor = ord(reply_data[3:4]) + if is_centurion: + _centurion_protocol_versions[int(handle)] = (major, minor) + return major + minor / 10.0 if ( report_id == HIDPP_SHORT_MESSAGE_ID diff --git a/lib/logitech_receiver/device.py b/lib/logitech_receiver/device.py index cb9ec47b..2c787fba 100644 --- a/lib/logitech_receiver/device.py +++ b/lib/logitech_receiver/device.py @@ -1089,6 +1089,10 @@ class Device: return False if protocol: self._protocol = protocol + # Pick up raw Centurion protocol version from ping response + cent_ver = base._centurion_protocol_versions.get(int(handle)) + if cent_ver: + self._centurion_protocol = cent_ver # Dongle responded — now check if headset is actually on by probing through bridge. # Send ROOT.GetFeature(0x0001) to the sub-device via CentPPBridge. bridge_idx = getattr(self, "_centurion_bridge_index", None) diff --git a/lib/solaar/cli/show.py b/lib/solaar/cli/show.py index 673dfd2b..f0214fd3 100644 --- a/lib/solaar/cli/show.py +++ b/lib/solaar/cli/show.py @@ -164,7 +164,11 @@ def _print_device(dev, num=None): print(" Kind :", dev.kind) if dev.protocol: proto_name = "Centurion" if is_centurion else "HID++" - print(f" Protocol : {proto_name} {dev.protocol:1.1f}") + cent_proto = getattr(dev, "_centurion_protocol", None) + if cent_proto: + print(f" Protocol : {proto_name} {cent_proto[0]}.{cent_proto[1]}") + else: + print(f" Protocol : {proto_name} {dev.protocol:1.1f}") else: print(" Protocol : unknown (device is offline)") if not is_centurion and dev.polling_rate: diff --git a/lib/solaar/ui/window.py b/lib/solaar/ui/window.py index a9f117e1..f2d5ed5f 100644 --- a/lib/solaar/ui/window.py +++ b/lib/solaar/ui/window.py @@ -536,7 +536,13 @@ def _update_details(button): if device.product_id: yield _("Product ID"), f"{LOGITECH_VENDOR_ID:04x}:" + device.product_id hid_version = device.protocol - yield _("Protocol"), f"HID++ {hid_version:1.1f}" if hid_version else _("Unknown") + cent_proto = getattr(device, "_centurion_protocol", None) + if cent_proto: + yield _("Protocol"), f"Centurion {cent_proto[0]}.{cent_proto[1]}" + elif hid_version: + yield _("Protocol"), f"HID++ {hid_version:1.1f}" + else: + yield _("Protocol"), _("Unknown") if read_all and device.polling_rate: yield _("Polling rate"), device.polling_rate