Remove references to internal RE docs and lghub_agent from code comments

This commit is contained in:
Ken Sanislo 2026-04-19 12:57:34 -07:00
parent a1089cd8c5
commit 76b2ee8270
4 changed files with 24 additions and 39 deletions

View File

@ -24,16 +24,11 @@ gain is whole dB; getEQInfos returns 5 bytes [bandCount, dbRange,
caps, dbMin, dbMax].
V2 wire format: 5-byte band stride [filter_type, freq_hi, freq_lo,
gain_hi, gain_lo] with NO header. Filter types are 0x00=HP (cutoff),
gain_hi, gain_lo] with no header. Filter types are 0x00=HP (cutoff),
0x78=peaking. Frequency is raw BE u16 in Hz. Gain is signed BE int16
× step_db (step_db from getEQInfos). No Q on the wire firmware-fixed
per filter type. getEQInfos returns 13 bytes with gain bounds + step
count, format enum, XY-support flag, and onboard preset counts.
Authoritative source: HEADSET_ADVANCED_PARA_EQ_WIRE_PROTOCOL.md (the
V2 layout was confirmed via live G522 probe the default EQ is one
HP filter at 20 Hz plus nine peaking filters at ISO centers 50, 125,
250, 500, 1000, 2500, 5000, 10000, 20000 Hz with all gains at zero).
"""
from __future__ import annotations

View File

@ -666,13 +666,13 @@ class Device:
return hidpp20.feature_request(self, feature, function, *params, no_reply=no_reply)
# Max sub-message bytes in the first bridge fragment (for 0x51):
# 64 - 1 (report ID) - 1 (cpl_len) - 1 (flags) - 2 (bridge prefix) - 2 (bridge hdr) = 57
# LGHUB uses 56 for first fragment (60 byte payload - 4 bridge overhead)
# For 0x50, subtract 1 more for the device_addr byte.
# 64 - 1 (report ID) - 1 (cpl_len) - 1 (flags) - 2 (bridge prefix) - 2 (bridge hdr) = 57;
# one byte of conservative margin gives 56. For 0x50 the device_addr byte
# eats one more, so first_chunk = 55 (handled dynamically below).
_BRIDGE_FIRST_CHUNK = 56
# Continuation fragments carry raw sub_msg data (no bridge prefix/hdr):
# 64 - 1 (report ID) - 1 (cpl_len) - 1 (flags) = 61, but LGHUB uses 60
# For 0x50, subtract 1 more for the device_addr byte.
# 64 - 1 (report ID) - 1 (cpl_len) - 1 (flags) = 61; one byte of margin
# gives 60.
_BRIDGE_CONT_CHUNK = 60
def centurion_bridge_request(self, sub_feat_idx, sub_function=0x00, *params, no_reply=False):
@ -743,9 +743,8 @@ class Device:
# Fragments 1+: raw sub_msg continuation data (no bridge overhead)
# CPL flags = (frag_index << 1) | (1 if more_fragments else 0)
# All fragments are sent back-to-back without waiting for
# intermediate ACKs (verified via LGHUB pcap). The device
# reassembles internally and sends a single ACK + MessageEvent
# after the last fragment.
# intermediate ACKs. The device reassembles internally and
# sends a single ACK + MessageEvent after the last fragment.
frag_index = 0
offset = 0
while offset < sub_len:

View File

@ -27,11 +27,9 @@ import struct
from .hidpp20_constants import SupportedFeature
# Mystery bytes observed in every LGHUB pcap EQ write between band params
# and coefficient header. Purpose not fully understood — possibly a null-band
# terminator for DSPs that support >5 bands (advanced 10-band mode).
# First byte matches band_count; bytes 2-3 look like LE16 coeff blob size.
# Hardcoded from pcap for initial bring-up; revisit once device-tested.
# Opaque bytes observed between band params and coefficient header. First
# byte matches band_count; bytes 2-3 look like LE16 coeff blob size. Keep
# verbatim until a device counter-example forces a re-derivation.
_EQ_MYSTERY_BYTES = b"\x05\x5a\xe3\x00"
@ -85,7 +83,7 @@ def _build_coeff_section(bands, sample_rate, section_type=1):
coefficients (a1, a2) are left unchanged. The DSP multiplies the output by
rescale to restore correct gain.
"""
_HEADROOM = 1.19 # 19% headroom margin (matches LGHUB)
_HEADROOM = 1.19 # 19% headroom margin before quantization
num_bands = len(bands)
all_words = [num_bands] # first uint16 = num_bands

View File

@ -1593,17 +1593,10 @@ class HeadsetEcoMode(settings.Setting):
@classmethod
def build(cls, device):
# LGHUB's service layer for 0x0618 HeadsetBatterySaverMode compares
# incoming new_state against its cached current_state and SKIPS the
# devio SetEcoModeState write when they match (verified in
# on_headset_battery_saver_set_handler @ 0x100c21790). The G522
# firmware rejects no-op writes with device-specific NACK 0x0B.
#
# BooleanValidator's prepare_write already has the "skip if same as
# current" logic — it just needs needs_current_value=True to make
# Setting.write read the device state first. Default-mask (0xFF)
# BooleanValidators get needs_current_value=False, so we flip it here
# to match LGHUB's guard.
# G522 firmware rejects no-op writes with device-specific NACK 0x0B.
# BooleanValidator.prepare_write already skips writes that match the
# current value when needs_current_value=True; default-mask (0xFF)
# BooleanValidators get needs_current_value=False, so flip it here.
rw = settings.FeatureRW(cls.feature)
validator = settings_validator.BooleanValidator()
validator.needs_current_value = True
@ -1695,7 +1688,8 @@ class HeadsetMicGain(settings.Setting):
@classmethod
def build(cls, device):
# GetInfo (function 0) returns [min_gain (int8), max_gain (int8)].
# LGHUB caches these once at startup to rescale SetMicGain writes.
# Query once at build time so the slider range reflects the device's
# actual supported range rather than a generic int8 window.
try:
info = device.feature_request(cls.feature, 0x00)
except Exception as e:
@ -1855,10 +1849,9 @@ class HeadsetOnboardEQ(settings.RangeFieldSetting):
class HeadsetAdvancedEQ(settings.RangeFieldSetting):
"""Read-only display of the headset's active AdvancedParaEQ (0x020D) bands.
Writes are intentionally disabled for now. We now know the V2 wire format
(see HEADSET_ADVANCED_PARA_EQ_WIRE_PROTOCOL.md) so a write path is
buildable, but we still want a round-trip test on real hardware before
enabling user-facing writes that could misconfigure the DSP.
Writes are intentionally disabled for now. The V2 wire format is known
(see advanced_para_eq.py) but we want a round-trip test on real hardware
before enabling user-facing writes that could misconfigure the DSP.
V0/V1: 3-byte band stride [freq_hi, freq_lo, gain_i8], gain is whole dB.
V2: 5-byte band stride [filter_type, freq_hi, freq_lo, gain_hi, gain_lo],
@ -2099,9 +2092,9 @@ class HeadsetRGBColor(settings.Setting):
# Byte 0 is frame_type: 0x01 = transient commit, 0x02 = persistent.
# G522 firmware rejects 0x02 with LOGITECH_INTERNAL (0x05) — the
# persistent commit path may require additional state (e.g. onboard
# profile activation) we haven't mapped yet. Stick with 0x01 for
# now so the LEDs at least refresh visually; we can revisit 0x02
# once a wireshark capture of the LGHUB sequence is available.
# profile activation) that isn't mapped yet. Stick with 0x01 so the
# LEDs refresh visually; revisit persistence once the preconditions
# are known.
resp = device.feature_request(_F.HEADSET_RGB_HOSTMODE, 0x60, bytes([0x01, 0x00, 0x00, 0x00]))
frame_type = 0x01
logger.info(