Skip to content

logitech: factory reset for the PRO X 3 SUPERSTRIKE, and set up a mouse with no profiles - #166

Merged
snekxs merged 2 commits into
OpenMouse-Project:mainfrom
onyxhq-dev:feat/logitech-x3-factory-reset-and-init
Oct 5, 2026
Merged

snekxs merged 2 commits into
OpenMouse-Project:mainfrom
onyxhq-dev:feat/logitech-x3-factory-reset-and-init

Conversation

@onyxhq-dev

Copy link
Copy Markdown
Contributor

Part of OpenMouse-Project/openmouse#516 (Logitech mice show no profiles until G HUB has linked them once).

What

  • Factory reset for format 8. The X3 now has a captured factory image, so resetAllOnboardProfiles works on it. supportsFactoryReset(8) is now true.
  • initializeBlankOnboardProfiles() gives a mouse with no profiles the factory set without G HUB: the five factory sectors first, then the directory, then profile 1 selected, each read back. The directory is written last, so a failure part-way leaves the mouse as blank as it started, and it is returned to onboard mode.
  • factoryDirectoryForFormat(8, 255) builds the captured directory, and isBlankDirectory() recognises a directory that lists no profiles.

Where the bytes come from

Captured over USB (USBPcap) while G HUB reset every profile on a linked PRO X 3 SUPERSTRIKE:

  • All five profile sectors (1 to 5) received the same 255-byte image, CRC 0x2a38. It is byte-identical to the format 8 sector already in the tests, including the HITS defaults (actuation 5, rapid trigger 2 off, haptics 3).
  • The directory (sector 0) was written as 00 01 01 ff | 00 02 00 ff | 00 03 00 ff | 00 04 00 ff | 00 05 00 ff, then ff to the end, CRC 0x4037: sector 1 enabled, 2 to 5 disabled. It is byte-identical to the directory before the reset, so a reset does not change the directory.
  • G HUB then selected profile 1.

What is not verified

  • initializeBlankOnboardProfiles has not been run against a never-linked mouse. It replays G HUB's reset sequence, captured on a mouse that already had profiles. G HUB's own first-link sequence was not captured, and how a never-linked X3 reacts to these writes is unknown. The code comment and docs say so.
  • The factory directory layout is only captured for format 8. Other formats return null and the method refuses.

Tests

  • 7 new tests: the format 8 factory image against the captured sector, the factory directory bytes and CRC, the blank-directory check (including that a short read is not blank), and a fake onboard memory driving the whole sequence (blank mouse gets set up; a mouse that already has profiles is refused with nothing written; a write that does not stick leaves the directory blank and the mouse out of host mode).
  • tsc is clean. The Logitech test files pass (109). The full suite has 4 failures in mchose and registry, which are not Logitech; mchose fails the same way on a clean main.

…se with no profiles

Captured over USB while G HUB reset every profile on a linked X3: all five
profile sectors got one 255-byte image (CRC 0x2a38, identical to the format 8
fixture) and the directory (CRC 0x4037) lists sectors 1 to 5 with only the
first enabled. A reset leaves the directory unchanged.

- Format 8 now has a factory image, so resetAllOnboardProfiles works on the X3.
- factoryDirectoryForFormat builds the captured directory; isBlankDirectory
  recognises a directory that lists no profiles (a mouse G HUB never linked).
- initializeBlankOnboardProfiles writes the five factory sectors, then the
  directory, then selects profile 1, reading each back; a failure part-way
  leaves the directory blank and the mouse back in onboard mode.

The write sequence is G HUB's reset sequence. It has not been run against a
never-linked mouse, and G HUB's own first-link sequence was not captured.
…f them

The factory directory layout (5 profiles) was captured from a PRO X 3
SUPERSTRIKE. The PRO X 2 shares profile format 8, so it also reaches
initializeBlankOnboardProfiles, but nothing confirms it has the same layout.
Refuse unless the mouse's own getInfo profile count is at least the number of
profiles the captured directory lists.
@onyxhq-dev

Copy link
Copy Markdown
Contributor Author

Added a guard: initializeBlankOnboardProfiles now refuses unless the mouse's own getInfo profile count is at least the 5 profiles the captured factory directory lists. The directory was captured on a PRO X 3 SUPERSTRIKE; the PRO X 2 shares profile format 8 and so reaches the same code, but nothing confirms it has the same layout. A real X3 reports 5, so it is unaffected. One new test (a mouse reporting 3 is refused and nothing is written).

@snekxs
snekxs merged commit cd65ef0 into OpenMouse-Project:main Oct 5, 2026
5 checks passed
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 0.23.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@onyxhq-dev
onyxhq-dev deleted the feat/logitech-x3-factory-reset-and-init branch October 8, 2026 04:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants