Solaar/tests/logitech_receiver
Ken Sanislo ead0188a2c base: fix sw_id at 0x0B instead of rotating 0x2..0xF
Solaar's old rotating sw_id (cycling 0x2..0xF on every request) eats
HID++ replies addressed to other userspace clients sharing the same
device, because reply matching is feature + function + sw_id only and
Solaar eventually claims every value in the range. Cooperative use
with OpenRGB, LGSTrayEx, etc. is impossible by construction.

Pick one value and hold it. Other tools can pick a different one and
filter Solaar's traffic out of their reply stream cleanly.

  0x07  OpenRGB
  0x0A  LGSTrayEx
  0x0D  Logitech G HUB (host-side)
  0x0F  Logitech firmware (sub-device self-enumeration on wired)

0x0B is unallocated among the above and keeps the high bit set so
replies stay trivially distinguishable from notifications (sw_id=0).

Audit of why nothing breaks:

- Reply matcher in request() still works — Solaar's request loop is
  synchronous per device, so (feat, func, fixed_sw_id) is enough to
  identify the in-flight request's reply. The rotation never bought
  uniqueness across processes; it only avoided self-collision across
  successive synchronous requests, which doesn't exist as a problem.

- Ping reply identification uses a separate random mark byte
  (getrandbits(8) appended to the request data, checked at byte 4 of
  the reply). That randomization is unchanged.

- Stale-reply protection comes from _read_input_buffer draining the
  device handle before every new write. A delayed reply from a prior
  timed-out request gets routed to the notification hook, not
  mistaken for the current request's reply — independent of whether
  sw_id rotates.

- The "separate results and notifications" claim in the old docstring
  was misleading: true notifications carry sw_id=0 per the HID++ spec.
  What actually keeps replies distinguishable is the high bit being
  set, which 0x0B preserves.

- Centurion bridge in device.py uses the same sw_id-as-correlation-
  token pattern with the same synchronous-per-device flow; fixed sw_id
  works identically.
2026-05-13 16:36:41 -07:00
..
__init__.py tests: Add tests of common module 2024-02-18 06:10:53 -05:00
fake_hidpp.py Add RGB lighting persistence and software LED power management for G515 2026-05-13 19:03:44 -04:00
test_base.py base: fix sw_id at 0x0B instead of rotating 0x2..0xF 2026-05-13 16:36:41 -07:00
test_base_usb.py Speedup lookup of known receivers 2025-01-01 11:33:07 -05:00
test_common.py ui: Show offline status for receiver-paired device batteries (#3217) 2026-05-13 17:32:03 -04:00
test_desktop_notifications.py testing: upgrade desktop notifications tests to take notifications availability into account 2025-01-02 10:47:53 -05:00
test_device.py centurion: support PRO X 2 LIGHTSPEED headphones Centurion features (#3150) 2026-04-14 11:43:23 -04:00
test_diversion.py Refactor: Introduce Feature enum 2024-10-14 07:28:09 -04:00
test_hidpp10.py device: Handle composite IntFlag.name on Python < 3.11 (#3187) 2026-04-16 11:38:25 -04:00
test_hidpp20_complex.py centurion: support PRO X 2 LIGHTSPEED headphones Centurion features (#3150) 2026-04-14 11:43:23 -04:00
test_hidpp20_simple.py device: Fix operator precedence bug and end-of-configuration timing in device.changed() (#3173) 2026-05-13 11:30:26 -04:00
test_notifications.py show better pairing errors (#3063) 2025-12-10 11:18:50 -05:00
test_receiver.py device: Support per-slot unpair on Lightspeed receivers (CLI + GUI) (#3183) 2026-04-17 09:34:58 -04:00
test_rgb_power.py rgb_power.perkey_has_paint: gate on IGNORE only, not on != True 2026-05-13 19:03:44 -04:00
test_setting_templates.py Add RGB lighting persistence and software LED power management for G515 2026-05-13 19:03:44 -04:00
test_settings_validator.py common: render RGB color values as 0xrrggbb in config and solaar show 2026-05-12 12:51:36 -04:00