Skip to content

Add names for all identified HID++ 2.0 features#3153

Merged
pfps merged 1 commit intopwr-Solaar:masterfrom
ksanislo:let-there-be-names
Mar 20, 2026
Merged

Add names for all identified HID++ 2.0 features#3153
pfps merged 1 commit intopwr-Solaar:masterfrom
ksanislo:let-there-be-names

Conversation

@ksanislo
Copy link
Copy Markdown
Contributor

@ksanislo ksanislo commented Mar 4, 2026

Since it seems like a common point to ask about people's naming choices, I figured you might be interested in this as a patch.

Cross-referenced my own RE'd protocol doc to name all feature names that were missing from solaar. Covers Centurion-era headset audio, LogiVoice DSP pipeline, sim racing peripherals, and various common/keyboard/gaming features.

There are also some identifiable name mismatches with official names you may want to know about as well (not renamed to avoid breaking settings, UI strings, and config files):

Significantly misleading:

ID Solaar Name Doc Name Issue
0x0003 DEVICE_FW_VERSION FirmwareInfo Feature covers type, prefix, build, transport — not just version
0x0005 DEVICE_NAME DeviceTypeAndName Omits "Type" — feature also returns device type
0x0008 KEEP_ALIVE SwitchAndKeepAlive Omits "Switch" — feature also handles connection switching
0x2130 LOWRES_WHEEL RatchetFreeWheel Completely different concept
0x2250 XY_STATS AnalysisMode Completely different framing
0x8060 REPORT_RATE ReportRateLegacy Missing the modern "Legacy" qualifier, confused with 0x8061

Mildly misleading:

ID Solaar Name Doc Name Issue
0x2111 SMART_SHIFT_ENHANCED SmartShiftWithTunableTorque "Enhanced" is vague
0x2205 POINTER_SPEED PointerMotionScaling "Speed" vs "motion scaling"
0x1B04 REPROG_CONTROLS_V4 SpecialKeys Doc doesn't use v1-v4 lineage

@pfps
Copy link
Copy Markdown
Collaborator

pfps commented Mar 4, 2026

The names that Solaar uses here are mostly official internal Logitech names and correspond in many cases to released Logitech documentation so changing them, even to something perhaps more intuitive, is probably not a good idea.

@pfps
Copy link
Copy Markdown
Collaborator

pfps commented Mar 4, 2026

The additional names look good though.

@pfps
Copy link
Copy Markdown
Collaborator

pfps commented Mar 4, 2026

The names you added do look like official Logitech names, at least in capitalization. How did you find them?

@ksanislo
Copy link
Copy Markdown
Contributor Author

ksanislo commented Mar 4, 2026

@pfps They're scraped out of the g hub app, so they should be as official as we're likely to find. Specifically, they're from lghub_agent.aarch64 on macOS from ~3-6 months ago, which is why the official names for the latest fancy mouse aren't in there.

@ksanislo
Copy link
Copy Markdown
Contributor Author

ksanislo commented Mar 4, 2026

Well, I suppose I should say, nearly all of them are scraped from ghub, verified by spot checking with strings when you asked about them for the the G515 patch. The complete protocol docs are generated via AI without my involvement, specifically so I never actually look behind the curtain. My development is always being done only from written documentation to keep with clean room design (aka chinese wall) principals for reverse engineering.

@ksanislo
Copy link
Copy Markdown
Contributor Author

ksanislo commented Mar 4, 2026

So, in the spirit of accuracy, I went clear back to the original RE agent and asked to clarify the naming for the 9 items that were showing up as mismatched in the PR comment (note: none of these are in the PR change itself anyway, since changing established names is probably bad.) This should be acceptable since there's already legal ruling that function names themselves aren't protected by copyright, though doing this does kind of go against the spirit of clean room design. The following is the LLM's analysis about that set of names. It looks like only three of them were altered from the official names.

They come from the C++ class names in the devio namespace. Here's the summary:

ID Doc Name LGHUB Class Name In Source?
0x0003 FirmwareInfo Feature0003FirmwareInfo Yes (285 hits)
0x0005 DeviceTypeAndName Feature0005DeviceNameType No — LGHUB uses DeviceNameType (reversed order, no "And")
0x0008 SwitchAndKeepAlive Feature0008SwitchAndKeepAlive Yes
0x2130 RatchetFreeWheel Feature2130RatchetWheel No — LGHUB uses RatchetWheel (no "Free")
0x2250 AnalysisMode Feature2250AnalysisMode Yes
0x8060 ReportRateLegacy Feature8060ReportRate No — LGHUB uses just ReportRate (no "Legacy")
0x2111 SmartShiftWithTunableTorque Feature2111SmartShiftWithTunableTorque Yes
0x2205 PointerMotionScaling Feature2205PointerMotionScaling Yes
0x1B04 SpecialKeys Feature1B04SpecialKeys Yes
  1. DeviceTypeAndName — LGHUB says DeviceNameType. Order swapped, "And" added. Likely from Logitech's external HID++ documentation.
  2. RatchetFreeWheel — LGHUB says RatchetWheel. "Free" inserted from elsewhere — possibly an older spec or community interpretation.
  3. ReportRateLegacy — LGHUB says just ReportRate. "Legacy" was added externally (likely to distinguish from 0x8061 ExtendedAdjustableReportRate). LGHUB itself doesn't consider 0x8060 "legacy."

@pfps
Copy link
Copy Markdown
Collaborator

pfps commented Mar 5, 2026

Maybe take out the centurion names for now so that this can be merged indpendently of any centurion changes. Then the centurion names can be added (maybe in a separate file) as part of the overall centurion change.

@pfps
Copy link
Copy Markdown
Collaborator

pfps commented Mar 9, 2026

I worry that at some time there will be a clash so I think that the Centurion names should go in a different group, and probably in a different file.

Copy link
Copy Markdown
Collaborator

@pfps pfps left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's first just add the non-Centurion features.

@ksanislo
Copy link
Copy Markdown
Contributor Author

@pfps I was thinking the same thing, particularly with how everything is getting reorganized in the headset branch for centurion stuff. I've got this branch updated to do exactly that, I believe, but I haven't finished with testing to make sure there's no elsewhere problems yet. The updated push should be ready later this evening.

@pfps
Copy link
Copy Markdown
Collaborator

pfps commented Mar 10, 2026

So can you update this little PR to just have the HID++ 2.0 names? That puts all the centurion stuff in the other PR.

@ksanislo
Copy link
Copy Markdown
Contributor Author

@pfps I can split them up, based on if I'm using them in my centurion support patch, but it's important to remember that hid++ vs centurion is only the transport protocol, the features are actually available via either method if a device offers them. Just because I've only seen certain features over a specific protocol with what I own doesn't really mean they can't exist or be used over the older hid++ 2.0 protocol still as well, and the official app definitely supports them as such.

@pfps
Copy link
Copy Markdown
Collaborator

pfps commented Mar 10, 2026

But isn't the report_id different for the different protocols? This would indicate that the feature number could be reused. And how does feature discovery work?

Unfortunately I don't have a device to test all this on, but if you put the output of solaar -ddd show here I could probably see enough interaction to figure out a good way to go.

@ksanislo
Copy link
Copy Markdown
Contributor Author

ksanislo commented Mar 10, 2026

The actual differences between the transports is only feature 0x0003, and the "core" centurion feature of 0x0100–0x0116 which isn't used via hid++. Everything else is just a normal feature which can be used via any transport which offers it. Feature discovery is probed over 0x0003 (the Cent++ bridge) if you're connected wirelessly over a dongle. If a centurion device is directly connected, then 0x0003 isn't special anymore, and everything is basically identical to hid++ with a different wrapper.

Effectively, the dongles are 'special', but the devices behind them are for all intents and purposes the same as the rest of Logitech's lineup. You're just required to talk to the end device over an additional bridge layer which lives as feature 0x0003 of the dongle. That and the centurion protocol is over report_id 0x51 and 63 byte packets, but effectively contains the same internal language and function ids as the 0x10/0x11 hid++ data does.

@ksanislo
Copy link
Copy Markdown
Contributor Author

HID++ 2.0:
Short (0x10): 7 bytes total
[0] report_id (0x10)
[1] device_index
[2] feature_index
[3] func<<4 | swid
[4-6] params (3 bytes)

Long (0x11): 20 bytes total
[0] report_id (0x11)
[1] device_index
[2] feature_index
[3] func<<4 | swid
[4-19] params (16 bytes)

Centurion (e.g. PRO X 2):
64 bytes total (report_id + 63 payload)

Layer 1 — HID Report:
[0] report_id (0x51)

Layer 2 — CPL framing:
[1] length
[2] frag_ctrl = (frag_index << 1) | has_more

Layer 3 — CenturionTransport (fragment 0 only):
[3] feat_idx
[4] func<<4 | swid
[5-63] params (up to 59 bytes)

Continuation fragments (frag_index >= 1):
[3-63] payload continues (up to 61 bytes per fragment)

@pfps
Copy link
Copy Markdown
Collaborator

pfps commented Mar 19, 2026

Even if the centurion names end up here, can you create a PR with only the HID++ names? The centurion changes can then be added to your centurion PR. I think that is a cleaner separation.

Add 30 documented HID++ 2.0 feature names from LGHUB source analysis:
keyboard/mouse (PROPERTY_ACCESS, BLE_PRO_PRE_PAIRING, FULL_KEY_CUSTOMIZATION,
CONTROL_LIST, SWITCH_SWAPABILITY, DEVICE_MODE, ENABLE_HIDDEN_FEATURES,
KEYBOARD_DISABLE_CONTROLS, LOGI_MODIFIERS), racing peripherals
(RPM_INDICATOR, RPM_LED_PATTERN, LEGACY/AXIS_RESPONSE_CURVE, BANDED_AXIS,
COMBINED_PEDALS, BUNNY_HOPPING, PROFILE_MANAGEMENT, DUAL_CLUTCH,
WHEEL_CENTER_POSITION, DISPLAY_GAME_DATA, CENTER_SPRING, AXIS_MAPPING,
GLOBAL_DAMPING, BRAKE_FORCE, PEDAL_STATUS, TORQUE_LIMIT,
CONFIGURATION_PROFILES, OPERATING_RANGE, TRUE_FORCE, FFB_FILTER).

Sort RPM_INDICATOR/RPM_LED_PATTERN (0x807A-B) before PER_KEY_LIGHTING
(0x8080-81) to maintain ID ordering.
@ksanislo ksanislo force-pushed the let-there-be-names branch from 5b8bfe1 to e3065a2 Compare March 20, 2026 04:01
@ksanislo
Copy link
Copy Markdown
Contributor Author

Certainly, here's just the non-centurion era stuff instead.

ksanislo added a commit to ksanislo/Solaar-NG that referenced this pull request Mar 20, 2026
Add feature constants split out from the HID++ 2.0 names PR (pwr-Solaar#3153):
CENTURION_LED_BRIGHTNESS (0x0110), CENTURION_EU_POWER_MODE (0x0115),
CENTURION_DEVICE_BOOL_STATE (0x0116), HEADSET_ADVANCED_PARA_EQ (0x020D),
HEADSET_MIC_TEST (0x020E), HEADSET_EQ_STYLES (0x0213),
BT_HOST_INFO (0x0305), LIGHTSPEED_PAIRING (0x0309),
BT_GAMING_MODE (0x030A).
Copy link
Copy Markdown
Collaborator

@pfps pfps left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great now. Thanks.

@pfps pfps merged commit b9e0cf8 into pwr-Solaar:master Mar 20, 2026
3 checks passed
@ksanislo ksanislo deleted the let-there-be-names branch March 20, 2026 18:30
ksanislo added a commit to ksanislo/Solaar-NG that referenced this pull request Mar 20, 2026
Add feature constants split out from the HID++ 2.0 names PR (pwr-Solaar#3153):
CENTURION_LED_BRIGHTNESS (0x0110), CENTURION_EU_POWER_MODE (0x0115),
CENTURION_DEVICE_BOOL_STATE (0x0116), HEADSET_ADVANCED_PARA_EQ (0x020D),
HEADSET_MIC_TEST (0x020E), HEADSET_EQ_STYLES (0x0213),
BT_HOST_INFO (0x0305), LIGHTSPEED_PAIRING (0x0309),
BT_GAMING_MODE (0x030A).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants