All skills
hyperb1iss avatar

/protocol-research

@05acaca

This skill should be used when researching device protocols before implementing drivers. Triggers on "reverse engineer protocol", "research device", "find protocol docs", "USB capture", "Wireshark USB", "how does this device work", "capture USB traffic", "document wire format", "write a protocol spec", "what protocol does this use", "add support for new device", "new device driver", or any pre-implementation research for crates/hypercolor-hal/ drivers.

  • 3 files
  • 24.5 KB
  • Updated last month
  • GitHub

Use this Skill: https://skilld.dev/gh/hyperb1iss/hypercolor/protocol-research

This session only. Nothing lands on disk.

referencesresearch-methodology.md

≈2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Protocol Research Methodology

How to research and document device protocols for Hypercolor driver development. The vendor's own software + USB captures are the ground truth. Community protocol documentation, wikis, and open-source projects in the RGB ecosystem can provide additional context.

Research Sources (Priority Order)

  1. USB traffic captures — Capture the vendor's Windows/macOS software communicating with the device. This is ground truth. See the capture workflow below.
  2. Vendor documentation — Some vendors publish SDK docs or protocol specs (rare but invaluable when available).
  3. Community protocol documentation — Wikis, blog posts, forum threads where people have documented wire formats. Search for the device name + "protocol" or "reverse engineer."
  4. Open-source RGB projects — Projects like liquidctl, openrazer, and others in the RGB ecosystem may have documented protocol details for specific device families. Study their docs and protocol descriptions to understand how the device communicates. Always write clean Hypercolor implementations using our own architecture.
  5. Existing Hypercolor drivers — If a similar device family already has a driver (e.g., adding a new Razer variant when razer/protocol.rs exists), start from our own code.

USB Traffic Capture Workflow

  1. Set solid red, capture, then set solid green — diffing these two captures isolates exactly which bytes carry color data and reveals byte ordering (RGB vs RBG vs BGR)
  2. Identify checksum bytes — bytes that change between the two captures but aren't in color positions. XOR the full packets to spotlight them
  3. Verify color byte ordering — red capture should show 0xFF in R positions and 0x00 in G/B; green capture inverts this. If R and B swap, the device uses RBG or BGR
  4. Note inter-packet timing — capture timestamps reveal required post_delay values between commands
  5. Capture the init sequence — record what happens when the vendor software first opens the device (before setting any colors). This reveals firmware queries, mode switches, and topology discovery
  6. Capture shutdown — what the software sends when it exits (restores hardware control mode)

What to Document

For each protocol, produce a spec in docs/specs/ covering:

  • Packet layouts — byte-by-byte diagrams for each command type
  • Command vocabulary — init, firmware query, color data, commit, brightness, shutdown
  • Color encoding — byte order (RGB/RBG/BGR), max LEDs per packet, packing format
  • Checksums — algorithm, which bytes are covered, verification examples
  • Timing — inter-packet delays, frame intervals, response timeouts
  • Topology — LED counts per zone, addressing scheme (linear/matrix/ring), variant differences
  • Firmware variants — which firmware versions use which protocol, how to detect

C++ → Rust Translation Patterns

When studying open-source protocol implementations (in any language), these patterns map to Hypercolor's architecture:

Transport vs Transfer: A protocol reference's transport call determines TWO things in Hypercolor:

  • TransportType (registry.rs) — device-level transport binding, resolved once per DeviceDescriptor. Determines how the backend opens and talks to the device (e.g., UsbControl, UsbHidApi, UsbHidRaw, UsbBulk, I2cSmBus). HID descriptors declare a platform-free TransportIntent and let resolve_current_transport map it per target OS, because hidraw exists only on Linux.
  • TransferType (protocol.rs) — per-command path hint on ProtocolCommand. Allows a single protocol to mix transfer paths within one device session (e.g., HID feature reports for init, bulk for frame data). Variants: Primary, Bulk, HidReport.
Source Pattern Hypercolor Equivalent
Fixed-size byte buffer with manual offsets Zerocopy struct; whether it carries a report_id field depends on the resolved transport (see Common Pitfalls)
HID feature report send TransportIntent::Hid(HidTransportIntent { report_mode: FeatureReport, .. }) + TransferType::HidReport
USB control transfer TransportType::UsbControl + TransferType::Primary
HID interrupt write HidAccessMode::Direct (resolves to UsbHid on Linux, UsbHidApi elsewhere) + TransferType::Primary
Per-LED color loop with count mismatch a private per-driver normalize_colors(&self, ..) -> Cow<'a, [[u8; 3]]> method — borrow when the LED count matches, allocate only when padding
Sleep/delay between commands post_delay: Duration::from_millis(N)
Read response after command expects_response: true + parse_response()

Common Pitfalls

Pattern Pitfall Correct Hypercolor Translation
RGBGetRValue(color) Assumes RGB ordering Check actual byte positions — may be RBG or BGR
HID write with len+1 +1 is the report ID Under UsbHidApi or UsbHidRaw, pick the report_mode to match: a *WithReportId mode means the struct carries the byte, a plain mode means the transport prepends it. Under every other transport there is no prepend step, so the struct carries it
usleep(1000) Units are microseconds Duration::from_micros(1000) (= 1ms)
HID get feature report Blocks until response expects_response: true on preceding command
sizeof(buf) May include the report ID The size assertion must match the struct, which is the wire size minus any byte the transport prepends, and only UsbHidApi and UsbHidRaw prepend anything
Magic numbers at byte offsets Undocumented, easy to mismap Define named constants for every offset

The report ID rule is per transport, not global. report_mode exists on exactly two of the nine TransportType variants, UsbHidApi and UsbHidRaw, and the prepend lives only in their encoders. Every other transport sends the payload verbatim; UsbControl and UsbBulk pass the report ID in the control-transfer wValue, and UsbHid, UsbMidi, UsbSerial, I2cSmBus, and UsbVendor add nothing at all, so there the packet struct owns the byte. Lian Li ENE is the counterexample worth remembering: its descriptors declare TransportType::UsbHid, which has no report_mode at all, and every ENE packet struct starts with a report_id field. HidAccessMode::Direct resolves to UsbHid on Linux, so an intent that names a report_mode can still land on a transport that ignores it.

Verifying Your Understanding

Always verify your protocol understanding against actual USB traffic from the vendor's software:

  1. Run the vendor's Windows/macOS software
  2. Capture with Wireshark + USBPcap (Windows) or usbmon (Linux)
  3. Compare captured packets byte-by-byte with your spec
  4. Pay special attention to: byte ordering, checksum algorithms, timing between packets

The vendor's software is always ground truth. Community documentation and open-source implementations may have bugs, be incomplete, or cover different firmware versions.

Source: SKILL.md on GitHub

No third-party reports yet.

Signed by skilld at 05acaca. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated last month
version
1.0.0

README badge

README badge for hyperb1iss/hypercolor/protocol-research