diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/README.md b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/README.md new file mode 100644 index 0000000..2cce83e --- /dev/null +++ b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/README.md @@ -0,0 +1,21 @@ +# 01 - ndizazzo - initial hardware mode captures + +Provided-by: @ndizazzo +Provided-at: 2026-05-13 + +Initial exploratory USBPcap captures used to compare startup, hardware-mode enable/disable, live lighting preview, and fan/cooling preset traffic. + +Files: + +- `commander-duo-01-startup.pcap`: from `/tmp/opencode/duo-usbpcap/startup.pcap` +- `commander-duo-02-hardware-enable.pcap`: from `/tmp/opencode/duo-usbpcap/hardware-enable.pcap` +- `commander-duo-03-disable-hardware-mode.pcap`: from `/tmp/opencode/duo-usbpcap/disable-hardware-mode.pcap` +- `commander-duo-04-hardware-fixed-red.pcap`: from `/tmp/opencode/duo-usbpcap/hardware-red.pcap` +- `commander-duo-05-hardware-lighting-preview.pcap`: from `/tmp/opencode/duo-usbpcap/hardware-lighting.pcap` +- `commander-duo-06-hardware-lighting-speed-preview.pcap`: from `/tmp/opencode/duo-usbpcap/hardware-lighting-set-speed.pcap` +- `commander-duo-07-hardware-lighting-direction-preview.pcap`: from `/tmp/opencode/duo-usbpcap/hardware-lighting-set-direction.pcap` +- `commander-duo-08-fan-quiet.pcap`: from `/tmp/opencode/duo-usbpcap/fan-quiet.pcap` +- `commander-duo-09-fan-balanced.pcap`: from `/tmp/opencode/duo-usbpcap/fan-balanced.pcap` +- `commander-duo-10-fan-extreme.pcap`: from `/tmp/opencode/duo-usbpcap/fan-extreme.pcap` +- `commander-duo-11-fan-zero-rpm.pcap`: from `/tmp/opencode/duo-usbpcap/fan-zero.pcap` +- `commander-duo-12-hardware-set-cooling-preset.pcap`: from `/tmp/opencode/duo-usbpcap/harware-set-cooling-preset.pcap` diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-01-startup.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-01-startup.pcap new file mode 100644 index 0000000..c8d6e5d Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-01-startup.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-02-hardware-enable.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-02-hardware-enable.pcap new file mode 100644 index 0000000..70edaa8 Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-02-hardware-enable.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-03-disable-hardware-mode.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-03-disable-hardware-mode.pcap new file mode 100644 index 0000000..3ec990d Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-03-disable-hardware-mode.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-04-hardware-fixed-red.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-04-hardware-fixed-red.pcap new file mode 100644 index 0000000..a6621cb Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-04-hardware-fixed-red.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-05-hardware-lighting-preview.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-05-hardware-lighting-preview.pcap new file mode 100644 index 0000000..e29bb3a Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-05-hardware-lighting-preview.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-06-hardware-lighting-speed-preview.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-06-hardware-lighting-speed-preview.pcap new file mode 100644 index 0000000..9eb251b Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-06-hardware-lighting-speed-preview.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-07-hardware-lighting-direction-preview.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-07-hardware-lighting-direction-preview.pcap new file mode 100644 index 0000000..ad4f71f Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-07-hardware-lighting-direction-preview.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-08-fan-quiet.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-08-fan-quiet.pcap new file mode 100644 index 0000000..c7d8134 Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-08-fan-quiet.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-09-fan-balanced.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-09-fan-balanced.pcap new file mode 100644 index 0000000..c49a4d7 Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-09-fan-balanced.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-10-fan-extreme.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-10-fan-extreme.pcap new file mode 100644 index 0000000..5c20a1a Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-10-fan-extreme.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-11-fan-zero-rpm.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-11-fan-zero-rpm.pcap new file mode 100644 index 0000000..a11237a Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-11-fan-zero-rpm.pcap differ diff --git a/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-12-hardware-set-cooling-preset.pcap b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-12-hardware-set-cooling-preset.pcap new file mode 100644 index 0000000..a5b8718 Binary files /dev/null and b/Corsair Commander DUO/01 - ndizazzo - initial hardware mode captures/commander-duo-12-hardware-set-cooling-preset.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/README.md b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/README.md new file mode 100644 index 0000000..59d2f47 --- /dev/null +++ b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/README.md @@ -0,0 +1,20 @@ +# 02 - ndizazzo - device memory preview and apply captures + +Provided-by: @ndizazzo +Provided-at: 2026-05-13 + +Follow-up captures for Device Memory preview, fixed/off lighting, global red, LED-count changes, rainbow/speed/direction previews, palette preview, save/apply, and after-replug behavior. + +Files: + +- `commander-duo-13-device-memory-baseline-open.pcap`: from `/tmp/opencode/duo-new-captures/duo-00-baseline-device-memory-open.pcap` +- `commander-duo-14-device-memory-fixed-aa55cc-preview.pcap`: from `/tmp/opencode/duo-new-captures/duo-02-device-memory-fixed-aa55cc.pcap` +- `commander-duo-15-device-memory-off-preview.pcap`: from `/tmp/opencode/duo-new-captures/duo-03-device-memory-off.pcap` +- `commander-duo-16-device-memory-global-red-preview.pcap`: from `/tmp/opencode/duo-new-captures/duo-04-device-memory-port1-red-port2-red.pcap` +- `commander-duo-17-device-memory-led-count-change.pcap`: from `/tmp/opencode/duo-new-captures/duo-07-device-memory-led-count-change.pcap` +- `commander-duo-18-device-memory-rainbow-preview.pcap`: from `/tmp/opencode/duo-new-captures/duo-08-device-memory-effect-rainbow.pcap` +- `commander-duo-19-device-memory-rainbow-speed-preview.pcap`: from `/tmp/opencode/duo-new-captures/duo-09-device-memory-effect-speed-change.pcap` +- `commander-duo-20-device-memory-rainbow-direction-preview.pcap`: from `/tmp/opencode/duo-new-captures/duo-10-device-memory-effect-direction-change.pcap` +- `commander-duo-21-device-memory-two-color-palette-preview.pcap`: from `/tmp/opencode/duo-new-captures/duo-11device-memory-two-color-palette.pcap` +- `commander-duo-22-device-memory-save-apply-only.pcap`: from `/tmp/opencode/duo-new-captures/duo-12-device-memory-save-apply-only.pcap` +- `commander-duo-23-device-memory-after-replug-readback.pcap`: from `/tmp/opencode/duo-new-captures/duo-13-after-replog-readback.pcap` diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-13-device-memory-baseline-open.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-13-device-memory-baseline-open.pcap new file mode 100644 index 0000000..8c34d9f Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-13-device-memory-baseline-open.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-14-device-memory-fixed-aa55cc-preview.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-14-device-memory-fixed-aa55cc-preview.pcap new file mode 100644 index 0000000..03cce4e Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-14-device-memory-fixed-aa55cc-preview.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-15-device-memory-off-preview.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-15-device-memory-off-preview.pcap new file mode 100644 index 0000000..116dcc7 Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-15-device-memory-off-preview.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-16-device-memory-global-red-preview.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-16-device-memory-global-red-preview.pcap new file mode 100644 index 0000000..5a8f23c Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-16-device-memory-global-red-preview.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-17-device-memory-led-count-change.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-17-device-memory-led-count-change.pcap new file mode 100644 index 0000000..f4d7e0f Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-17-device-memory-led-count-change.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-18-device-memory-rainbow-preview.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-18-device-memory-rainbow-preview.pcap new file mode 100644 index 0000000..f84c279 Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-18-device-memory-rainbow-preview.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-19-device-memory-rainbow-speed-preview.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-19-device-memory-rainbow-speed-preview.pcap new file mode 100644 index 0000000..50f9962 Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-19-device-memory-rainbow-speed-preview.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-20-device-memory-rainbow-direction-preview.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-20-device-memory-rainbow-direction-preview.pcap new file mode 100644 index 0000000..0ef3f57 Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-20-device-memory-rainbow-direction-preview.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-21-device-memory-two-color-palette-preview.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-21-device-memory-two-color-palette-preview.pcap new file mode 100644 index 0000000..e27450e Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-21-device-memory-two-color-palette-preview.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-22-device-memory-save-apply-only.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-22-device-memory-save-apply-only.pcap new file mode 100644 index 0000000..a21891c Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-22-device-memory-save-apply-only.pcap differ diff --git a/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-23-device-memory-after-replug-readback.pcap b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-23-device-memory-after-replug-readback.pcap new file mode 100644 index 0000000..b95f1d7 Binary files /dev/null and b/Corsair Commander DUO/02 - ndizazzo - device memory preview and apply captures/commander-duo-23-device-memory-after-replug-readback.pcap differ diff --git a/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/README.md b/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/README.md new file mode 100644 index 0000000..66ac776 --- /dev/null +++ b/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/README.md @@ -0,0 +1,12 @@ +# 03 - ndizazzo - focused device memory commits and readback + +Provided-by: @ndizazzo +Provided-at: 2026-05-13 + +Focused captures that confirm persistent rainbow commit, fixed-color 112233 commit byte order, and Device Memory readback payloads. + +Files: + +- `commander-duo-24-device-memory-rainbow-commit.pcap`: from `/tmp/opencode/duo-redo-captures/redo-01-rainbow.pcap` +- `commander-duo-25-device-memory-fixed-112233-commit.pcap`: from `/tmp/opencode/duo-redo-captures/redo-02-color-commit.pcap` +- `commander-duo-26-device-memory-fixed-112233-readback.pcap`: from `/tmp/opencode/duo-redo-captures/redo-03-readback.pcap` diff --git a/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/commander-duo-24-device-memory-rainbow-commit.pcap b/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/commander-duo-24-device-memory-rainbow-commit.pcap new file mode 100644 index 0000000..d235dcc Binary files /dev/null and b/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/commander-duo-24-device-memory-rainbow-commit.pcap differ diff --git a/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/commander-duo-25-device-memory-fixed-112233-commit.pcap b/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/commander-duo-25-device-memory-fixed-112233-commit.pcap new file mode 100644 index 0000000..ebdbaff Binary files /dev/null and b/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/commander-duo-25-device-memory-fixed-112233-commit.pcap differ diff --git a/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/commander-duo-26-device-memory-fixed-112233-readback.pcap b/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/commander-duo-26-device-memory-fixed-112233-readback.pcap new file mode 100644 index 0000000..6b3f1e6 Binary files /dev/null and b/Corsair Commander DUO/03 - ndizazzo - focused device memory commits and readback/commander-duo-26-device-memory-fixed-112233-readback.pcap differ diff --git a/Corsair Commander DUO/README.md b/Corsair Commander DUO/README.md new file mode 100644 index 0000000..59f3c6a --- /dev/null +++ b/Corsair Commander DUO/README.md @@ -0,0 +1,21 @@ +# Corsair Commander DUO + +Provided-by: @ndizazzo +Provided-at: 2026-05-13 + +USBPcap captures used to reverse engineer liquidctl support for the Corsair Commander DUO. + +Highlights: + +- Standard 5 V ARGB software lighting uses live RGB writes on endpoint `0x22`. +- Device Memory fixed/off lighting commits use endpoint `65 6d` with data type `7e 20`. +- Focused readback confirms static Device Memory color order `ff bb gg rr`. +- Device Memory rainbow commits use endpoint `65 6d` with data type `02 a4`. +- Captured `61/62/63 6d` writes appear related to cooling/profile data and were not used as lighting writes. + +The Python scripts in `analyzer - ndizazzo/` summarize HID payloads from these USBPcap files. + +Capture groups: +- `01 - ndizazzo - initial hardware mode captures/`: Initial exploratory USBPcap captures used to compare startup, hardware-mode enable/disable, live lighting preview, and fan/cooling preset traffic. +- `02 - ndizazzo - device memory preview and apply captures/`: Follow-up captures for Device Memory preview, fixed/off lighting, global red, LED-count changes, rainbow/speed/direction previews, palette preview, save/apply, and after-replug behavior. +- `03 - ndizazzo - focused device memory commits and readback/`: Focused captures that confirm persistent rainbow commit, fixed-color 112233 commit byte order, and Device Memory readback payloads. diff --git a/Corsair Commander DUO/analyzer - ndizazzo/README.md b/Corsair Commander DUO/analyzer - ndizazzo/README.md new file mode 100644 index 0000000..4f1ac5d --- /dev/null +++ b/Corsair Commander DUO/analyzer - ndizazzo/README.md @@ -0,0 +1,11 @@ +# analyzer - ndizazzo + +Provided-by: @ndizazzo +Provided-at: 2026-05-13 + +Helper scripts used during Commander DUO protocol analysis. + +- `duo_hid_summary.py`: summarizes HID host writes, open endpoints, live RGB writes, and endpoint payloads. +- `duo_extract_hid_csv.py`: extracts HID packets to CSV for manual inspection. + +Both scripts require `tshark` in PATH and read HID payloads from `usbhid.data`. diff --git a/Corsair Commander DUO/analyzer - ndizazzo/duo_extract_hid_csv.py b/Corsair Commander DUO/analyzer - ndizazzo/duo_extract_hid_csv.py new file mode 100755 index 0000000..1566b88 --- /dev/null +++ b/Corsair Commander DUO/analyzer - ndizazzo/duo_extract_hid_csv.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +"""Extract focused Commander DUO HID packet rows from USBPcap captures.""" + +from __future__ import annotations + +import argparse +import csv +import subprocess +from pathlib import Path + + +def _hex_to_bytes(value: str) -> bytes: + return bytes.fromhex(value.replace(":", "")) + + +def _payload_body(payload: bytes) -> bytes: + if len(payload) >= 2 and payload[0] == 0x00 and payload[1] == 0x08: + return payload[1:] + return payload + + +def extract(path: Path, output: Path, endpoint_filter: set[str] | None) -> None: + cmd = [ + "tshark", + "-r", + str(path), + "-T", + "fields", + "-e", + "frame.number", + "-e", + "frame.time_relative", + "-e", + "usb.endpoint_address", + "-e", + "usbhid.data", + ] + proc = subprocess.run(cmd, check=True, text=True, capture_output=True) + with output.open("w", newline="") as fh: + writer = csv.writer(fh) + writer.writerow(["frame", "time_relative", "endpoint", "direction", "command", "payload_hex"]) + for line in proc.stdout.splitlines(): + frame, time_rel, endpoint, payload = (line.split("\t") + [""] * 4)[:4] + if not payload or (endpoint_filter and endpoint not in endpoint_filter): + continue + data = _payload_body(_hex_to_bytes(payload)) + if not data or data[0] != 0x08: + continue + direction = "host" if endpoint == "0x04" else "device" + command = data[1:3].hex(" ") if len(data) >= 3 else "" + writer.writerow([frame, time_rel, endpoint, direction, command, data.hex(" ")]) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("pcap", type=Path) + parser.add_argument("output", type=Path) + parser.add_argument( + "--endpoint", + action="append", + help="Endpoint to include, e.g. 0x04 or 0x84. Repeatable. Defaults to all HID endpoints.", + ) + args = parser.parse_args() + extract(args.pcap, args.output, set(args.endpoint) if args.endpoint else None) + + +if __name__ == "__main__": + main() diff --git a/Corsair Commander DUO/analyzer - ndizazzo/duo_hid_summary.py b/Corsair Commander DUO/analyzer - ndizazzo/duo_hid_summary.py new file mode 100755 index 0000000..e2f8b09 --- /dev/null +++ b/Corsair Commander DUO/analyzer - ndizazzo/duo_hid_summary.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +"""Summarize Commander DUO USBPcap HID transactions. + +Requires tshark in PATH. The reducer intentionally uses usbhid.data because +USBPcap captures for this device place HID payloads there, not usb.capdata. +""" + +from __future__ import annotations + +import argparse +import subprocess +from collections import Counter +from pathlib import Path + + +def _hex_to_bytes(value: str) -> bytes: + return bytes.fromhex(value.replace(":", "")) + + +def _tshark_rows(path: Path) -> list[tuple[int, float, str, bytes]]: + cmd = [ + "tshark", + "-r", + str(path), + "-T", + "fields", + "-e", + "frame.number", + "-e", + "frame.time_relative", + "-e", + "usb.endpoint_address", + "-e", + "usbhid.data", + ] + proc = subprocess.run(cmd, check=True, text=True, capture_output=True) + rows = [] + for line in proc.stdout.splitlines(): + number, time_rel, endpoint, payload = (line.split("\t") + [""] * 4)[:4] + if not payload: + continue + rows.append((int(number), float(time_rel or 0), endpoint, _hex_to_bytes(payload))) + return rows + + +def _payload_body(payload: bytes) -> bytes: + # Older captures include HID report id 00 before 08; newer captures start at 08. + if len(payload) >= 2 and payload[0] == 0x00 and payload[1] == 0x08: + return payload[1:] + return payload + + +def _command_data(data: bytes) -> bytes: + if len(data) < 3: + return bytes() + command = data[1:3] + body = data[3:] + if command == bytes([0x0D, 0x01]): + return body.rstrip(bytes([0x00])) + if command == bytes([0x06, 0x01]) and len(data) >= 9: + length = int.from_bytes(data[3:5], "little") + return data[3 : 7 + length] + if command in (bytes([0x06, 0x00]), bytes([0x07, 0x00])) and len(data) >= 5: + length = int.from_bytes(data[3:5], "little") + return data[3 : 7 + length] + return body.rstrip(bytes([0x00])) + + +def summarize(path: Path) -> None: + rows = _tshark_rows(path) + host = [(n, t, _payload_body(p)) for n, t, ep, p in rows if ep == "0x04"] + dev = [(n, t, _payload_body(p)) for n, t, ep, p in rows if ep == "0x84"] + opens = [] + endpoint_writes = [] + color_writes = [] + for number, time_rel, data in host: + if len(data) < 4 or data[0] != 0x08: + continue + command = data[1:3] + if command == bytes([0x0D, 0x01]): + opens.append(_command_data(data).hex(" ")) + elif command == bytes([0x06, 0x01]) and len(data) >= 9: + length = int.from_bytes(data[3:5], "little") + dtype = data[7:9] + payload = data[9 : 7 + length] + endpoint_writes.append((number, time_rel, length, dtype, payload)) + elif command in (bytes([0x06, 0x00]), bytes([0x07, 0x00])): + color_writes.append((number, time_rel, command, data[3:])) + + print(f"{path}") + print(f" host writes: {len(host)}") + print(f" device responses: {len(dev)}") + print(f" open endpoints: {Counter(opens).most_common(12)}") + print(f" live color writes: {len(color_writes)}") + for number, time_rel, length, dtype, payload in endpoint_writes: + print( + " endpoint write " + f"frame={number} time={time_rel:.6f} len={length} " + f"dtype={dtype.hex(' ')} payload={payload.hex(' ')}" + ) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("pcap", nargs="+", type=Path) + args = parser.parse_args() + for pcap in args.pcap: + summarize(pcap) + + +if __name__ == "__main__": + main()