# RED RCP2 Protocol — verified findings Sources: - `kjayasa/commander` — `components/rcp/rcp.cpp`: full RCP2 parameter table (293 params w/ types + supported JSON ops), extracted from official RED docs (910-0327 protocol + per-camera parameter PDFs) - `intGus/komodo-remote` — `code.py`: working client against real Komodo, exact wire format ## Transport (corrects our v1 driver) - **WebSocket**, `ws://:9998/rcp` — NOT raw TCP, NOT length-prefixed - Text frames, one JSON object per frame - Camera can push unsolicited notifications (e.g. RECORD_STATE changes) ## Handshake First message after connect: ```json {"type":"rcp_config","strings_decoded":0,"json_minified":1, "include_cacheable_flags":0,"encoding_type":"html", "client":{"name":"Forge"}} ``` Camera replies once; then normal traffic. ## Messages - Get: `{"type":"rcp_get","id":"RECORD_STATE"}` - Set: `{"type":"rcp_set","id":"RECORD_STATE","value":"2"}` - Param IDs = `RCP_PARAM_*` names **with `RCP_PARAM_` prefix stripped** - Response/notification: `{"id":"RECORD_STATE","cur":{"val":}, ...}` — value under `cur.val` - Other ops exist: `rcp_get_list`, `rcp_get_status`, `rcp_notification`, `rcp_subscribe` (see rcp.cpp enum) ## Parameters we use | Purpose | Param (wire id) | Type | |---|---|---| | Rec state | `RECORD_STATE` | value; 0=idle 1=recording 2=toggle-request | | Clip name | `CLIP_NAME` | status | | ISO/EI | `ISO` | value | | White balance | `COLOR_TEMPERATURE` | value | | Tint | `TINT` | value | | FPS | `SENSOR_FRAME_RATE` | value | | Timecode | `TIMECODE` | status | | CDL enable | `CDL_ENABLE` | value | | CDL slope | `CDL_SLOPE_RED/GREEN/BLUE` | value (per channel!) | | CDL offset | `CDL_OFFSET_RED/GREEN/BLUE` | value | | CDL power | `CDL_POWER_RED/GREEN/BLUE` | value | | CDL sat | `CDL_SATURATION` | value | | Active LUT name | `APPLIED_CAMERA_LUT` | status (read-only) | | Select camera LUT | `CAMERA_LUT` | value (selects from camera's stored list) | | Import LUT from media | `MEDIA_LUT_IMPORT_TO_CAMERA` | action | ## Capability corrections for our driver 1. **CDL is per-channel scalar params**, not a JSON blob. 10 sets per full CDL push (9 SOP + sat). CDL_ENABLE=1 required. 2. **No live 3D LUT upload over RCP2.** `CAMERA_LUT` only selects LUTs already on camera; `MEDIA_LUT_IMPORT_*` pulls from inserted media. So RED live-grade path = **native CDL only**; creative LUT must be pre-loaded to camera or baked into monitor path elsewhere. → capabilities: `supportsNativeCDL=true`, `lut3dSizes=[]`. 3. Gang: for RED slots, only the leading-CDL portion of a node stack is pushable live. Remainder LUT must be identity, else surface a warning state (grade preview ≠ camera monitor). # ASC MHL v2.0 — verified findings Source: `ascmitc/mhl-specification` + reference impl `ascmitc/mhl` (XSD fetched, stored below). Corrections to our v1 MHL writer: - Root: `` - Required: `` (creationdate, hostname, tool) AND `` (process ∈ in-place|transfer|flatten) - Hash entries: `rel/pathhex` — size is an ATTRIBUTE of path, hash algo is element name, action attribute tracks chain state - Folder convention: manifests live in `ascmhl/` subfolder, named `NNNN__.mhl`, plus `ascmhl_chain.xml` - Directory hashes optional (content + structure) XSD: https://raw.githubusercontent.com/ascmitc/mhl/master/xsd/ASCMHL.xsd # Other useful repos found - `ascmitc/mhl` — Python reference impl, good for cross-validation of our manifests - Tangent Hub: no public TIPC repos of note; Tangent's official "Tangent Hub" SDK ships the mapping XML + TIPC docs with the installer (macOS phase task)