Types & errors
The Medius* types and MEDIUS_* enumerators from medius.h. Calls are on API index and streams on Streams. What each value means is in the Rust Library and Native API sections.
Enum backing: MediusStatus is int32_t, every other enum uint8_t.
On C23 and C++ the tag carries that underlying type directly (enum MediusButton : uint8_t). On C99 the tag is typedef'd to the integer and you pass the prefixed enumerators (MEDIUS_BUTTON_LEFT).
Structs are plain PODs with no heap allocation: pass by value, read fields directly. Only opaque handles have a *_free.
Variable-length wire data is an inline fixed-size array with a count, never a pointer you own. These layouts are ABI version 10 (MEDIUS_ABI_VERSION in the header). Compare it with medius_abi_version() once at start-up.
Sizing constants Fixed-cap arrays sized to the wire limits
Event, lock and log PODs embed arrays sized to the protocol limits, with a count of live slots. char arrays are NUL-terminated.
| Macro | Value | Caps |
|---|---|---|
MEDIUS_MAX_USAGES | 256 | MediusUsageEvent.usages, MediusClipStatus.held |
MEDIUS_MAX_LOCKS | 256 | MediusLocks.entries |
MEDIUS_MAX_PATH | 512 | MediusPortInfo.path |
MEDIUS_MAX_LOG_TEXT | 512 | MediusLogLine.text |
MEDIUS_MAX_PRODUCT | 128 | MediusDeviceInfo.product |
MEDIUS_MAX_SERIAL | 128 | MediusPortInfo.serial |
MEDIUS_MAX_NAME | 33 | MediusVersion.name |
MEDIUS_CLIP_TRIG_MAX | 8 | MediusClipSettings.triggers |
MEDIUS_CLIP_PKT_TRIG_MAX | 8 | MediusClipSettings.packet_triggers |
MEDIUS_CLIP_PKT_MATCH_POOL | 112 | Match bytes the box holds across every MediusClipPacketTrigger |
MEDIUS_REWRITE_PAYLOAD_POOL | 2048 | Payload bytes the box holds across every MediusRewriteRule |
MEDIUS_MAX_PKT_MATCH | 16 | MediusClipPacketTrigger.match_bytes and .mask |
MEDIUS_CLIP_EDGES_MAX | 8 | Edges in one MediusClipFrame |
MEDIUS_CLIP_RAW_MAX | 8 | Raw reports in one MediusClipFrame |
MEDIUS_CLIP_ENTRY_MAX | 512 | Encoded bytes of one MediusClipFrame: one CLIP_APPEND payload |
MEDIUS_MAX_CATCH_ENTRIES | 32 | MediusCatchState.entries |
MEDIUS_MAX_TRAFFIC_BYTES | 180 | MediusTrafficEvent.bytes |
MEDIUS_MAX_CATCH_ENTRIES is the box's subscription table size, so a MediusCatchState always carries the whole live table.
MEDIUS_MAX_TRAFFIC_BYTES is the largest payload one traffic event carries, so the inline array never truncates. A short len means your capture cut the packet.
Enumsuint8_t-backed selectors (MediusStatus is int32_t)
Each value is a wire byte; meanings are on Enums. The *Kind enums and MediusClass tag which arm is set in a built value (MediusUsage, MediusMotion, MediusCatchEvent).
MediusDeviceKind Cloned device's primary kind
enum MediusDeviceKind : uint8_t
The kind field of a MediusDeviceInfo, from the cloned device's HID report descriptors and Boot declarations. A device carrying both kinds reads keyboard if it has a full key bitmap (unless it declares Boot for both), or if it declares a Boot keyboard and no Boot mouse. Otherwise it reads mouse. medius_device_find_mouse_box / _find_keyboard_box select on this field. See DeviceKind.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_DEVICE_KIND_UNKNOWN | 0 | Nothing cloned, or a clone that is neither a mouse nor a keyboard (a device with no HID interface reads this). medius_device_info_is_cloned tells them apart. |
MEDIUS_DEVICE_KIND_KEYBOARD | 1 | The real device is a keyboard. |
MEDIUS_DEVICE_KIND_MOUSE | 2 | The real device is a mouse. |
MediusButton Mouse button id
enum MediusButton : uint8_t /* values match the firmware button id */
The button an inject call drives. Ids on Usage IDs.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_BUTTON_LEFT | 0 | Left button. |
MEDIUS_BUTTON_RIGHT | 1 | Right button. |
MEDIUS_BUTTON_MIDDLE | 2 | Middle button. |
MEDIUS_BUTTON_SIDE1 | 3 | First thumb button. |
MEDIUS_BUTTON_SIDE2 | 4 | Second thumb button. |
MediusAxis Relative axis id
enum MediusAxis : uint8_t /* values match the wire axis id */
The axis a medius_catch_filter_watch_axis subscribes to: the same ids a catch or lock entry carries on the wire.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_AXIS_X | 0 | Horizontal cursor movement. |
MEDIUS_AXIS_Y | 1 | Vertical cursor movement. |
MEDIUS_AXIS_WHEEL | 2 | The scroll wheel. |
MEDIUS_AXIS_PAN | 3 | AC Pan (horizontal scroll). |
MediusAction Press / release tri-state
enum MediusAction : uint8_t
The override action of inject calls on a button, key, or media usage. See the injection model.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_ACTION_SOFT_RELEASE | 0 | Drop the box's press or force release. A hold on the real device stays down. |
MEDIUS_ACTION_PRESS | 1 | Force the input down. |
MEDIUS_ACTION_FORCE_RELEASE | 2 | Force the input up, masking a hold on the real device. |
MediusClass Which arm of a MediusUsage is set
enum MediusClass : uint8_t
The kind tag of a MediusUsage you build with medius_usage_button/_key/_media.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_CLASS_BUTTON | 0 | id is a mouse button id. |
MEDIUS_CLASS_KEY | 1 | id is a HID keyboard usage. |
MEDIUS_CLASS_MEDIA | 2 | id is a 16-bit Consumer usage. |
MediusMotionKind Which arm of a MediusMotion is set
enum MediusMotionKind : uint8_t
Tags the MediusMotion you build with medius_motion_cursor/_wheel/_pan. See Move.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_MOTION_KIND_CURSOR | 0 | dx/dy apply. |
MEDIUS_MOTION_KIND_WHEEL | 1 | wheel applies. |
MEDIUS_MOTION_KIND_PAN | 2 | pan applies (AC Pan, horizontal scroll). |
MediusLockTargetKind Which input a MediusLockTarget addresses
enum MediusLockTargetKind : uint8_t
The kind of a MediusLockTarget. See Lock.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_LOCK_TARGET_KIND_X | 0 | Horizontal movement. |
MEDIUS_LOCK_TARGET_KIND_Y | 1 | Vertical movement. |
MEDIUS_LOCK_TARGET_KIND_WHEEL | 2 | Scroll wheel. |
MEDIUS_LOCK_TARGET_KIND_PAN | 3 | AC Pan (horizontal scroll). |
MEDIUS_LOCK_TARGET_KIND_USAGE | 4 | A momentary usage (the struct's usage field selects which). |
MediusDirection Axis sign, usage edge, or transfer direction
enum MediusDirection : uint8_t
Its meaning depends on what it is attached to. The transfer direction applies to a MediusCatchFilter naming a byte-oriented catch class. See LOCK and Catch.
| Enumerator | Value | Axis or wheel | Button or key | Traffic-class filter |
|---|---|---|---|---|
MEDIUS_DIRECTION_BOTH | 0 | Both signs. A scale sets the two fixed signs and passes WITH / AGAINST in full. | Press and release. | Both directions. |
MEDIUS_DIRECTION_POSITIVE | 1 | Positive (+). | The press edge. | IN, device to PC. |
MEDIUS_DIRECTION_NEGATIVE | 2 | Negative (-). | The release edge. | OUT, PC to device. |
MEDIUS_DIRECTION_WITH | 3 | The sign the box is injecting. | Refused. | No meaning. |
MEDIUS_DIRECTION_AGAINST | 4 | The sign opposing it. | Refused. | No meaning. |
Only an axis has a bearing, so WITH or AGAINST on a lock of anything else is MEDIUS_STATUS_ERR_RELATIVE_DIRECTION. A media usage has no edges: an edge named on one is sent as MEDIUS_DIRECTION_BOTH, and reads back that way in MediusLocks.
Direction parameters and struct fields are declared uint8_t, so a value no enumerator names can be passed. The library handles it at the boundary; it never reaches the wire.
| Call | Comes back as |
|---|---|
Any call returning a MediusStatus | MEDIUS_STATUS_ERR_INVALID_ARG; no frame is sent. |
medius_locks_scale_of | It names no entry, so MEDIUS_LOCK_SCALE_PASS. |
medius_locks_is_locked | Unlocked, for the same reason. |
medius_catch_filter_with_direction | Stored, then refused at subscribe time, where there is a status to carry it. |
MediusEdge Which edge of a trigger usage fires a clip binding
enum MediusEdge : uint8_t
The edge of a MediusClipTrigger's on usage that runs its action. Same wire values as MediusDirection. See Clip.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_EDGE_BOTH | 0 | Both press and release. |
MEDIUS_EDGE_PRESS | 1 | The press edge only. |
MEDIUS_EDGE_RELEASE | 2 | The release edge only. |
MediusClipAction Engine action a clip trigger drives
enum MediusClipAction : uint8_t
What a bound MediusClipTrigger or MediusClipPacketTrigger does to the clip when it fires. The verbs match the medius_clip_start/_stop/... calls. See Clip.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_CLIP_ACTION_START | 0 | Rewind and play (resume from a pause). |
MEDIUS_CLIP_ACTION_STOP | 1 | Stop and release held input and the auto-lock. |
MEDIUS_CLIP_ACTION_PAUSE | 2 | Halt mid-clip, retaining the cursor and held input. |
MEDIUS_CLIP_ACTION_RESUME | 3 | Continue from the paused cursor. |
MEDIUS_CLIP_ACTION_RESTART | 4 | Force a rewind and play, even mid-playback. |
MEDIUS_CLIP_ACTION_TOGGLE | 5 | Play if idle/paused, stop if playing. |
MediusBlanket Whole-group lock selector
enum MediusBlanket : uint8_t
A whole input group: what medius_device_lock_all/_unlock_all block in one call, and the scope medius_clip_set_autolock locks while a clip plays. See Lock.
The values are ABI-local ordinals (matching the crate's Blanket order), not the CLIP_LOCK_* wire bits.
| Enumerator | Value | Meaning | Direction |
|---|---|---|---|
MEDIUS_BLANKET_AIM | 0 | The X and Y cursor axes. | A sign, on each axis. |
MEDIUS_BLANKET_WHEEL | 1 | The wheel. | A sign. |
MEDIUS_BLANKET_BUTTONS | 2 | Every mouse button. | An edge, on each button. |
MEDIUS_BLANKET_KEYS | 3 | Every keyboard key and modifier. | An edge: POSITIVE blocks presses, NEGATIVE releases, BOTH both. |
MEDIUS_BLANKET_MEDIA | 4 | Every media (Consumer) usage. | Nothing. Media has no edges. |
MediusLedTarget Which chip's status LED to drive
enum MediusLedTarget : uint8_t
See LED.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_LED_TARGET_DEVICE | 0 | The device chip's LED. |
MEDIUS_LED_TARGET_HOST | 1 | The host chip's LED, relayed over the inter-chip link. |
MEDIUS_LED_TARGET_BOTH | 2 | Both LEDs at once. |
MediusLedMode What to drive the LED to
enum MediusLedMode : uint8_t
See LED. Solid / Blink use the command's level.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_LED_MODE_AUTO | 0 | Restore the chip's status display. |
MEDIUS_LED_MODE_OFF | 1 | LED dark. |
MEDIUS_LED_MODE_SOLID | 2 | Lit steadily at level. |
MEDIUS_LED_MODE_BLINK | 3 | Blinks at level. |
MediusRebootTarget Which chip to restart, and how
enum MediusRebootTarget : uint8_t
See Admin.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_REBOOT_TARGET_DEVICE_DOWNLOAD | 0 | Device chip into ROM download mode (flash over the serial link). |
MEDIUS_REBOOT_TARGET_HOST_DOWNLOAD | 1 | Host chip into ROM download mode (flash over USB3). |
MEDIUS_REBOOT_TARGET_DEVICE_RUN | 2 | Restart the device chip and run its firmware. |
MEDIUS_REBOOT_TARGET_HOST_RUN | 3 | Restart the host chip and run its firmware. |
MediusEmitMode What paces injected motion
enum MediusEmitMode : uint8_t
See Options.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_EMIT_MODE_LEARNED | 0 | Pace to the learnt native report rate (the default). |
MEDIUS_EMIT_MODE_INTERVAL | 1 | Pace to the clone's declared poll rate (its bInterval). |
MEDIUS_EMIT_MODE_FIXED | 2 | Pace to a fixed rate in Hz (snapped to 1000/n, capped 1 kHz). |
MediusRenderMode Texture the box renders motion with
enum MediusRenderMode : uint8_t
Passed to medius_device_set_render and returned in MediusRenderStatus. See Options.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_RENDER_MODE_OFF | 0 | Even fill at the paced rate, no model. |
MEDIUS_RENDER_MODE_STOCK | 1 | Render with the bit-exact triangular smoother. |
MEDIUS_RENDER_MODE_DESPIKED | 2 | Render with the smoother's onset ramped rather than stepped. The boot default. |
MEDIUS_RENDER_MODE_UNSMOOTHED | 3 | Render with no smoother; the model receives the raw injection. |
MediusCatchEventKind Which arm of a MediusCatchEvent is set
enum MediusCatchEventKind : uint8_t
Which member of the MediusCatchEvent union to read. The last column lists the MediusCatchClass values that raise each kind. See Catch.
| Enumerator | Value | Read | Raised by |
|---|---|---|---|
MEDIUS_CATCH_EVENT_KIND_MOTION | 0 | data.motion | AXIS |
MEDIUS_CATCH_EVENT_KIND_USAGES | 1 | data.usages | BUTTON, KEY, MEDIA |
MEDIUS_CATCH_EVENT_KIND_TRAFFIC | 2 | data.traffic | HID_IN, HID_OUT, VENDOR_INTERRUPT, VENDOR_BULK, CONTROL, EMIT, BUS, CLIP_TRANSFER |
MediusClockDomain Which chip's clock stamped an event
enum MediusClockDomain : uint8_t
The clock field of a MediusCatchEvent, beside ts_us. Where an event is tapped fixes its domain.
The box is two ESP32-S3s (a device chip and a host chip) that boot independently. A stamp only compares with stamps from the same domain.
| Enumerator | Value | Stamped | Carries |
|---|---|---|---|
MEDIUS_CLOCK_DOMAIN_HOST_CHIP | 0 | In USB interrupt context on the host chip, when the real device's transfer completed. | Motion and usage events, HID_IN, and native IN traffic on VENDOR_INTERRUPT / VENDOR_BULK. |
MEDIUS_CLOCK_DOMAIN_DEVICE_CHIP | 1 | At the tap on the device chip, the side facing the game PC. | HID_OUT, OUT traffic on VENDOR_INTERRUPT / VENDOR_BULK, a raw packet on a vendor IN endpoint, CONTROL, EMIT, BUS, and CLIP_TRANSFER. |
Each clock is a box-local uint32_t of microseconds. It wraps every ~71.6 minutes and returns to zero when its chip reboots. A stamp below the previous one is a wrap, a reboot, or a domain change.
A MediusTimeline puts both on this machine's clock. The clock estimate in MediusCatchState relates the two box domains directly.
MediusInputKind Which arm of a MediusInputEvent is set
enum MediusInputKind : uint8_t
Tags a MediusInputEvent off the decoded-input stream. The box sends held-usage snapshots; the stream diffs them into these edges.
| Enumerator | Value | Read |
|---|---|---|
MEDIUS_INPUT_KIND_PRESS | 0 | usage: a momentary usage went down. |
MEDIUS_INPUT_KIND_RELEASE | 1 | usage: a momentary usage came up. |
MEDIUS_INPUT_KIND_MOTION | 2 | dx / dy / dz: one relative-motion report. |
MediusLogLevel Severity tag on a log line
enum MediusLogLevel : uint8_t
The severity of a MediusLogLine. See Logs & counters.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_LOG_LEVEL_ERROR | 0 | A failure the box couldn't recover from. |
MEDIUS_LOG_LEVEL_WARN | 1 | Something off that the box handled. |
MEDIUS_LOG_LEVEL_INFO | 2 | Normal operational notices. |
MEDIUS_LOG_LEVEL_DEBUG | 3 | Detail for diagnosing a problem. |
MEDIUS_LOG_LEVEL_VERBOSE | 4 | The finest-grained trace output. |
MediusCatchClass What a catch filter addresses
typedef uint8_t MediusCatchClass; /* one MEDIUS_CATCH_CLASS_* value */
The class half of a MediusCatchFilter, and the class_ field of both MediusTrafficEvent and MediusCatchEntry.
Classes 0 to 3 are the same vocabulary Lock uses; the rest address USB interfaces, endpoints and the bus, and arrive as byte-oriented traffic. See Catch.
| Enumerator | Value | id addresses | With MEDIUS_CATCH_ID_ANY |
|---|---|---|---|
MEDIUS_CATCH_CLASS_BTN | 0 | A mouse button id. | Every button. |
MEDIUS_CATCH_CLASS_KEY | 1 | A HID keyboard usage (modifiers are 0xE0 to 0xE7). | Every key and modifier. |
MEDIUS_CATCH_CLASS_MEDIA | 2 | A 16-bit Consumer usage. | Every media usage. |
MEDIUS_CATCH_CLASS_AXIS | 3 | A MediusAxis: X, Y, the wheel, or AC Pan. | Every axis. |
MEDIUS_CATCH_CLASS_HID_IN | 4 | A cloned HID interface number. | Every HID interface. |
MEDIUS_CATCH_CLASS_HID_OUT | 5 | An interrupt-OUT endpoint number. | Every interrupt-OUT endpoint. |
MEDIUS_CATCH_CLASS_VENDOR_INTERRUPT | 6 | A vendor interrupt endpoint number. | Every vendor interrupt endpoint. |
MEDIUS_CATCH_CLASS_VENDOR_BULK | 7 | A vendor bulk endpoint number. | Every vendor bulk endpoint. |
MEDIUS_CATCH_CLASS_CONTROL | 8 | A control endpoint number (0 is EP0; on EP0, the requests the clone relays to the real device). | Every control endpoint. |
MEDIUS_CATCH_CLASS_EMIT | 9 | An emitting endpoint number. | Every emitting endpoint. |
MEDIUS_CATCH_CLASS_BUS | 10 | Nothing; pass MEDIUS_CATCH_ID_ANY. | Every bus event. |
MEDIUS_CATCH_CLASS_CLIP_TRANSFER | 11 | The control endpoint number (0 is EP0) a clip's transfer ran on. | Every control endpoint. |
MEDIUS_CATCH_CLASS_ANY | 0xFF | Nothing; must be MEDIUS_CATCH_ID_ANY. | Every class at once. |
Test one with medius_catch_class_is_input (the four parsed classes, which arrive decoded and carry no packet) or medius_catch_class_is_traffic (the eight byte-oriented ones).
Where each class is tapped, and why a locked input still reports, is on Catch.
MediusCatchFilter One subscription entry: class, id, direction, capture
struct MediusCatchFilter {
MediusCatchClass class_; /* MEDIUS_CATCH_CLASS_* */
uint16_t id; /* class-specific, or MEDIUS_CATCH_ID_ANY */
uint8_t direction; /* MEDIUS_DIRECTION_*: edge, sign, or flow */
uint8_t capture; /* 0 = whole packet; traffic classes only */
};The array passed to medius_device_catch_events or medius_device_input_events. Build each with a medius_catch_filter_* helper and narrow it with a modifier.
Each element becomes one entry in the box's table; read the accepted set back with medius_device_query_catch. The field is class_ because class is a C++ keyword.
| Field | C type | Meaning |
|---|---|---|
class_ | MediusCatchClass | Which address space this entry subscribes in. |
id | uint16_t | The id inside that class, or MEDIUS_CATCH_ID_ANY for every id in it. |
direction | uint8_t, a MEDIUS_DIRECTION_* value | For an input class, the press/release edge, as for a lock. For a traffic class, the transfer direction: POSITIVE is IN (device to PC), NEGATIVE is OUT (PC to device). No class is both, so the byte is unambiguous. |
capture | uint8_t | Bytes kept per event; 0 keeps the whole packet. Traffic classes only: an input class carries no packet, so a non-zero capture on one is refused with MEDIUS_STATUS_ERR_CAPTURE_NOT_APPLICABLE. |
| Macro | Value | Means |
|---|---|---|
MEDIUS_CATCH_ID_ANY | 65535 | Every id in the class, as one table entry rather than one per id, like a blanket lock. |
MEDIUS_CATCH_CLASS_ANY | 255 | Every class. A real id beside it addresses nothing and is refused. |
MEDIUS_MAX_CATCH_ENTRIES | 32 | Entries the box's table holds; more fails the call with MEDIUS_STATUS_ERR_CATCH_TABLE_FULL. |
capture is per entry, not box-wide: keep a 64-byte vendor interrupt report whole, and only 16 bytes of a bulk pipe traced for framing.
The top-ranked matching entry's capture applies, so "everything at 16 bytes, except endpoint 0x83 in full" is two entries. Ranking: The table.
a report arrives on VENDOR_INTERRUPT endpoint 0x83
│
├─ exact { class_ = VENDOR_INTERRUPT, id = 0x0083 } ──▶ resolves first
├─ blanket { class_ = VENDOR_INTERRUPT, id = ID_ANY } ──▶ used if no exact entry
└─ any { class_ = ANY, id = ID_ANY } ──▶ used if neither matched
ties inside one tier go to the earlier entry in your array/* every class and id, first 16 bytes only */
MediusCatchFilter blanket =
medius_catch_filter_with_capture(medius_catch_filter_everything(), 16);
/* except this endpoint's IN traffic, kept whole */
MediusCatchFilter whole = medius_catch_filter_inbound(
medius_catch_filter_traffic(MEDIUS_CATCH_CLASS_VENDOR_INTERRUPT, 0x83));
MediusCatchFilter filters[2] = { blanket, whole };
MediusEventStream *events = NULL;
medius_device_catch_events(dev, filters, 2, &events);A malformed entry fails the whole call with a distinct MediusStatus. medius_catch_filter_same_address tests whether two filters name the same table entry, whatever their captures.
MediusKey HID keyboard/keypad usage
typedef uint8_t MediusKey; /* modifiers are 0xE0 to 0xE7 */
A raw HID keyboard usage for the key calls: any usage byte, or a MEDIUS_KEY_* macro. Full set: Usage IDs.
| Macro group | Example | Usage |
|---|---|---|
| Letters | MEDIUS_KEY_A .. MEDIUS_KEY_Z | 4 to 29 |
| Digits | MEDIUS_KEY_1 .. MEDIUS_KEY_0 | 30 to 39 |
| Function | MEDIUS_KEY_F1 .. MEDIUS_KEY_F12 | 58 to 69 |
| Editing / nav | MEDIUS_KEY_ENTER, _ESCAPE, _TAB, _SPACE, _INSERT, _HOME, _DELETE, arrows | various |
| Modifiers | MEDIUS_KEY_LEFT_CTRL .. MEDIUS_KEY_RIGHT_GUI | 224 to 231 (0xE0 to 0xE7) |
MediusMediaKey 16-bit HID Consumer usage
typedef uint16_t MediusMediaKey;
A raw Consumer usage for the media calls: any 16-bit usage, or a MEDIUS_MEDIA_* macro. Full set: Usage IDs.
| Macro | Usage | Macro | Usage |
|---|---|---|---|
MEDIUS_MEDIA_PLAY_PAUSE | 205 | MEDIUS_MEDIA_MUTE | 226 |
MEDIUS_MEDIA_NEXT_TRACK | 181 | MEDIUS_MEDIA_VOLUME_UP | 233 |
MEDIUS_MEDIA_PREV_TRACK | 182 | MEDIUS_MEDIA_VOLUME_DOWN | 234 |
MEDIUS_MEDIA_STOP | 183 | MEDIUS_MEDIA_PLAY | 176 |
MEDIUS_MEDIA_PAUSE | 177 |
MediusFrameType Wire frame TYPE byte (mock only)
enum MediusFrameType : uint8_t /* always defined; read only by the mock recorder */
The TYPE byte of a wire frame, used with the mock recorder (medius_mock_saw / medius_mock_recorded_frame). See the mock feature.
| Enumerator | Value | Enumerator | Value |
|---|---|---|---|
MEDIUS_FRAME_TYPE_MOVE | 1 | MEDIUS_FRAME_TYPE_LOCK | 10 |
MEDIUS_FRAME_TYPE_INJECT | 3 | MEDIUS_FRAME_TYPE_CATCH | 11 |
MEDIUS_FRAME_TYPE_RESET | 4 | MEDIUS_FRAME_TYPE_MOTION_EVENT | 12 |
MEDIUS_FRAME_TYPE_QUERY | 5 | MEDIUS_FRAME_TYPE_USAGE_EVENT | 15 |
MEDIUS_FRAME_TYPE_RESP | 6 | MEDIUS_FRAME_TYPE_OPTION | 17 |
MEDIUS_FRAME_TYPE_REBOOT_DL | 7 | MEDIUS_FRAME_TYPE_CLIP_APPEND | 18 |
MEDIUS_FRAME_TYPE_LOG | 8 | MEDIUS_FRAME_TYPE_CLIP_CTRL | 19 |
MEDIUS_FRAME_TYPE_LED | 9 | MEDIUS_FRAME_TYPE_CLIP_SET | 20 |
MEDIUS_FRAME_TYPE_TRAFFIC_EVENT | 22 | MEDIUS_FRAME_TYPE_CLIP_TRIGGER | 21 |
Argument structs Tagged values you build, then pass in
Three PODs built with a helper and passed to a call; the medius_*_* constructors set the kind tag and the matching field.
MediusUsage Momentary usage for inject
What medius_device_inject drives. Build with medius_usage_button(...), _key(...), or _media(...); id holds the button id or usage per kind. See Inject.
| Field | C type | Meaning |
|---|---|---|
kind | MediusClass | Which class id names. |
id | uint16_t | Button id, key usage, or media usage. |
MediusMoveTiming When a move is emitted
enum MediusMoveTiming : uint8_t
The timing argument of medius_device_move_axis: follow movement riding or bypass it. See Move.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_MOVE_TIMING_RIDE | 0 | Follow movement riding: while it is on, wait for a native cursor move to carry the delta. |
MEDIUS_MOVE_TIMING_NOW | 1 | Emit on the next mouse report, native or not, whatever movement riding is set to. |
MediusPendingMotion What a move does to held motion
enum MediusPendingMotion : uint8_t
The pending argument of medius_device_move_axis. See Move.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_PENDING_MOTION_KEEP | 0 | Leave motion held by riding as it is. |
MEDIUS_PENDING_MOTION_FLUSH | 1 | Emit held motion now, ignoring the ride window. |
MEDIUS_PENDING_MOTION_DISCARD | 2 | Drop held motion. |
MediusMotion Relative axis for move_axis
What medius_device_move_axis drives. Build with medius_motion_cursor(dx, dy), medius_motion_wheel(delta), or medius_motion_pan(delta). See Move.
| Field | C type | Meaning |
|---|---|---|
kind | MediusMotionKind | Cursor, wheel, or pan. |
dx | int16_t | X movement (Cursor only). |
dy | int16_t | Y movement (Cursor only). |
wheel | int16_t | Scroll delta (Wheel only). |
pan | int16_t | AC Pan delta (Pan only). |
MediusLockTarget What a lock acts on
Passed to medius_device_lock / _unlock. Build it with medius_lock_target_axis or medius_lock_target_usage; usage is read only when kind is USAGE. See Lock.
| Field | C type | Meaning |
|---|---|---|
kind | MediusLockTargetKind | X, Y, Wheel, Pan, or Usage. |
usage | MediusUsage | The button, key, or media usage, when kind == USAGE. |
Query values PODs written through a query's out-param
Each medius_device_query_* / _caps / _counters call fills one of these by value. Canonical field docs are on Structs; query semantics on Requests.
MediusVersion Decoded firmware version and box name
From medius_device_query_version. Set the box's name with medius_device_set_name.
| Field | C type | Meaning |
|---|---|---|
proto_ver | uint8_t | Wire-protocol version the firmware speaks. |
fw_major | uint8_t | Firmware major version. |
fw_minor | uint8_t | Firmware minor version. |
fw_patch | uint8_t | Firmware patch version. |
mac | uint8_t[6] | The device chip's base MAC, a stable per-box id. |
name | char[MEDIUS_MAX_NAME] | The box's human-readable name (NUL-terminated; a synthesised default when unset). |
MediusHealth Box readiness flags (each 0 or 1)
From medius_device_query_health.
| Field | C type | True (1) when |
|---|---|---|
link_up | uint8_t | The link to the host chip is up. |
mouse_attached | uint8_t | A real mouse is plugged in. |
clone_configured | uint8_t | The PC has set up the cloned mouse. |
injection_active | uint8_t | At least one injected button or move is held. |
rate_confident | uint8_t | A mouse is bound and the native-rate estimator window is full. |
lock_on | uint8_t | At least one input is not at a full pass (blocked or weighed). |
catch_on | uint8_t | A catch subscription is streaming. |
kbd_attached | uint8_t | A keyboard is attached, cloned, and injectable. |
rewrite_on | uint8_t | The rewrite-rule table is non-empty (v3.4.0). |
patch_on | uint8_t | A descriptor-patch set is applied to the clone (v3.4.0). |
transform_on | uint8_t | A field transform is active (v3.4.0). |
MediusDeviceInfo Cloned device's USB identity, kind, and product
From medius_device_device_info. All-zero/empty when nothing is cloned, which medius_device_info_is_cloned tests. A clone with no HID interface (n_hid 0) still has its identity filled in. product is NUL-terminated ASCII, with ? for each non-ASCII character.
| Field | C type | Meaning |
|---|---|---|
vid | uint16_t | USB vendor id (idVendor). |
pid | uint16_t | USB product id (idProduct). |
bcd_device | uint16_t | Device release (bcdDevice). |
bcd_usb | uint16_t | USB version (bcdUSB), e.g. 0x0200. |
has_serial | uint8_t | The clone serves a serial string. |
has_bos | uint8_t | The clone serves a BOS descriptor. |
kind | MediusDeviceKind | The real device's primary kind, from its HID report descriptors. |
product | char[MEDIUS_MAX_PRODUCT] | The product string (NUL-terminated; empty when none). |
MediusCaps Whole cloned device's capabilities
From medius_device_caps: a mouse half and a keyboard half plus the per-class change-driven flags. Test it with medius_caps_has_mouse, medius_caps_has_keyboard, medius_caps_is_composite.
| Field | C type | Meaning |
|---|---|---|
mouse | MediusMouseCaps | The mouse half (all-zero when no mouse is bound). |
keyboard | MediusKbdCaps | The keyboard half (all-zero when no keyboard is bound). |
mouse_change_driven | uint8_t | Always 0: mouse motion is continuous, so it has a learned cadence. |
kbd_change_driven | uint8_t | 1 when a keyboard is bound: it reports only on a key change. |
MediusMouseCaps What the cloned mouse can do
The mouse half of MediusCaps; all-zero when no mouse interface is bound.
| Field | C type | Meaning |
|---|---|---|
n_buttons | uint8_t | Buttons the mouse report carries. |
has_x | uint8_t | The report carries an X axis. |
has_y | uint8_t | The report carries a Y axis. |
has_wheel | uint8_t | The report carries a wheel. |
pan | uint8_t | The report carries AC Pan (horizontal scroll). |
has_report_id | uint8_t | The mouse report sits behind a HID report ID. |
n_hid | uint8_t | Cloned HID interfaces; >1 = composite. |
MediusKbdCaps What the cloned keyboard can do
The keyboard half of MediusCaps; all-zero when no keyboard is bound. n_keys == 0xFF signals an NKRO bitmap.
| Field | C type | Meaning |
|---|---|---|
n_keys | uint8_t | Keycode-array slots, or 0xFF for an NKRO bitmap. |
nkro | uint8_t | The keyboard reports an NKRO bitmap. |
has_consumer | uint8_t | A Consumer collection is present (media injectable). |
has_system | uint8_t | A system-control collection is present (relayed only). |
has_report_id | uint8_t | The keyboard report sits behind a HID report ID. |
MediusRate Native report rate and clone poll period
From medius_device_query_rate. Convert to Hz with medius_rate_native_hz(rate, &hz) (returns false when there's no continuous cadence).
| Field | C type | Meaning |
|---|---|---|
native_period_us | uint16_t | Realised native period in µs; 0 = not learned, or change-driven. |
poll_period_us | uint16_t | Poll period of the clone's inject endpoint, in µs. |
confident | uint8_t | The estimator window is full and the value is trustworthy. |
change_driven | uint8_t | The active input is event-driven (keyboard/media), so there is no continuous cadence. |
MediusChipFirmware What one chip is running
One chip's half of medius_device_firmware_info.
| Field | C type | Meaning |
|---|---|---|
major, minor, patch | uint8_t | The firmware version this chip is running. |
slot | uint8_t | Which app slot it booted: 0 or 1. |
state | uint8_t | Image state: 0 new, 1 pending-verify, 2 valid, 3 invalid, 4 aborted, 0xFF unknown. See rollback. |
MediusFirmwareInfo Both chips, and what is staged
From medius_device_firmware_info.
| Field | C type | Meaning |
|---|---|---|
device | MediusChipFirmware | The PC-facing chip. |
host_present | uint8_t | 0 when the host chip has not replied over the inter-chip link; host is then meaningless. |
host | MediusChipFirmware | The chip that reads the real device. |
slot_size | uint32_t | Usable bytes in a spare slot; the same on both chips. |
device_staged | uint8_t | An image is written and waiting to be activated. |
host_staged | uint8_t | The same, for the host chip. |
MediusUpdateError Update op the box refused, and why
From medius_last_error_update after MEDIUS_STATUS_ERR_UPDATE. A confirm that timed out gives op 0 and status 0x1B, the refusal the next update would meet.
| Field | C type | Meaning |
|---|---|---|
op | uint8_t | 0 begin, 1 data, 2 end, 3 abort, 4 activate. |
status | uint8_t | The update status, such as 0x1B for a chip on probation. |
arg | uint32_t | The status argument; what it holds depends on the status. |
MediusStats Box-side delivery / telemetry counters
From medius_device_query_stats. Nonzero tx_drops or tx_wedges: input was lost between the box and the game PC. Nonzero link_rx_drops or host_rx_drops: input was lost between the box's two chips. relay_drops counts relayed traffic and commands that went no further, never lost native input.
| Field | C type | Meaning |
|---|---|---|
inject_emits | uint32_t | Pure-injection reports emitted. |
tx_drops | uint16_t | Reports the clone's IN queue could not hold, so they were never emitted to the game PC (should stay 0). |
tx_merges | uint16_t | Backed-up reports merged instead of queued. |
tx_maxdepth | uint8_t | Deepest the TX queue has reached. |
tx_wedges | uint8_t | Wedged-endpoint recoveries. |
wakeups | uint16_t | Remote wakeups the clone signalled to the game PC, for the real device or an injection. |
reset_count | uint16_t | USB bus resets seen. |
config_count | uint16_t | SET_CONFIGURATION events (re-enumerations). |
link_rx_drops | uint32_t | Input frames the device chip could not take off the link from the host chip (should stay 0). |
host_rx_drops | uint32_t | The same count on the host chip, relayed over the link (should stay 0). |
relay_drops | uint32_t | Relayed traffic and commands that went no further, never native input. One count each for: a vendor IN packet whose endpoint queue was full of the control PC's RAW packets; a native zero-length packet answering a poll the PC never made (the box runs one poll ahead of a suspended PC); an OUT packet with no room in the queue, that failed three times on the real device's bus, or that a bus reset or SET_INTERFACE overtook; a RAW OUT packet with no room to wait; a relayed request the box could not queue; a flagged MOVE the motion batch could not take; a frame other than native input that either chip's link receive ring dropped; a control-PC frame its receive ring had no room for. A control-port UART overrun counts once, however many frames it cost. |
session | uint16_t | Times the box released some or all of the session state a host set. 0 at boot; it wraps, so compare for inequality. The library watches it for session recovery. |
MediusLocks & MediusLockEntry Active scales, as an entry list
From medius_device_query_locks: entries[0..n], one per weighed direction. Read one with medius_locks_scale_of(&locks, target, dir), or test for an outright block with medius_locks_is_locked. Both take a covering whole-class (is_blanket) entry into account. Wire layout on the native LOCKS reply.
Asked with MEDIUS_DIRECTION_BOTH | Reports |
|---|---|
medius_locks_scale_of | The scale of smallest magnitude across every direction, WITH and AGAINST included (a negative one on a tie). A block outranks a reversal of any size; a pass outranks a reversal past -100. A delta meets a different figure: its fixed-sign scale times its relative scale. |
medius_locks_is_locked | The two fixed signs only. Name _WITH or _AGAINST to ask about one of those. |
| Field | C type | Meaning |
|---|---|---|
n | uint16_t | Live entries in entries. |
entries | MediusLockEntry[MEDIUS_MAX_LOCKS] | One per weighed direction of an axis or usage. |
| Macro | Value | Meaning |
|---|---|---|
MEDIUS_LOCK_SCALE_BLOCK | 0 | Keep none of the native value. |
MEDIUS_LOCK_SCALE_PASS | 100 | Keep all of it, untouched. |
MEDIUS_LOCK_SCALE_MAX | 255 | 2.55×, the ceiling. |
MEDIUS_LOCK_SCALE_MIN | -255 | 2.55× reversed, the floor. A negative reverses what it keeps (-100 inverts an axis); axes only. |
| Field | C type | Meaning |
|---|---|---|
target | MediusLockTarget | The weighed axis or usage. |
is_blanket | bool | The entry covers a whole class; target.usage.kind names it and target.usage.id is unused. |
direction | uint8_t, a MEDIUS_DIRECTION_* value | Which direction of the target this entry weighs. |
scale | int16_t | Percent of the native value kept; 0 is blocked and a negative reverses what it keeps. A momentary usage is one bit, so the box stores a block or a pass: never a value between, never negative. |
| Case | Contents |
|---|---|
| A blanket key lock | One entry per blocked edge, never MEDIUS_DIRECTION_BOTH. |
| A media lock, blanket or specific | MEDIUS_DIRECTION_BOTH, always. |
A relative direction under MEDIUS_BEARING_MODE_VECTOR | The effective scale, the lower of X's and Y's, on both axes. |
| The wire cap | One reply carries ≤85 entries, fewer than MEDIUS_MAX_LOCKS. Entries past 85 are left out, and nothing marks the cut. See the native LOCKS budget. |
A direction byte no constant names | The entry is dropped and n excludes it. |
MediusBearing & MediusBearingMode What WITH and AGAINST are measured against
struct MediusBearing {
uint16_t window_ms; /* 0 = off */
MediusBearingMode mode;
};From medius_device_query_bearing, set with medius_device_set_bearing. See the native bearing.
| Field | C type | Meaning |
|---|---|---|
window_ms | uint16_t | How long an axis holds the direction of its last injected delta. 0 is off, leaving WITH and AGAINST inert whatever their scale. |
mode | MediusBearingMode | How the bearing is read; see below. |
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_BEARING_MODE_PER_AXIS | 0 | Each axis compares its sign against its bearing, independently. The default. |
MEDIUS_BEARING_MODE_VECTOR | 1 | The native delta is projected onto the injected XY vector. The relative scale weighs only the part along that vector; the fixed-sign scales still apply to what is left on each axis. One relative scale (the lower of X's and Y's) governs X and Y as one vector, and MediusLocks reports it. |
| Macro | Value | Meaning |
|---|---|---|
MEDIUS_BEARING_WINDOW_DEFAULT_MS | 20 | The factory window; a box that has been set boots at its stored value. |
MediusCatchState & MediusCatchEntry Live subscription table, plus the inter-chip clock estimate
From medius_device_query_catch: a header, then entries[0..n], one per accepted MediusCatchFilter. The inline cap, MEDIUS_MAX_CATCH_ENTRIES (32), is the box's table size, so the reply always carries the whole table.
Entries are in acceptance order, not match order; each event is matched by the ranking.
| Field | C type | Meaning |
|---|---|---|
table_full | uint8_t | 1 when an entry was refused because the table was already full. |
dropped | uint32_t | Events shed under back-pressure, box-wide. |
clock | MediusClockEstimate | The measured difference between the two chips' clocks (below). |
n | uint16_t | Live entries in entries; 0 means nothing is subscribed. |
entries | MediusCatchEntry[MEDIUS_MAX_CATCH_ENTRIES] | One per accepted filter, in insertion order. |
| Field | C type | Meaning |
|---|---|---|
filter | MediusCatchFilter | The accepted subscription: class, id, direction, and the capture that applies when this entry is the match. |
dropped | uint16_t | Events this entry could not queue. |
Delivery is ranked: under a busy mouse, bulk can go completely undrained (queue order: Delivery). The header's dropped says events are being lost; the per-entry one says which subscription loses them.
The box measures the difference with a four-timestamp exchange across the inter-chip link. Each frame is stamped as it reaches the wire, not when queued, because queueing is that link's largest and most variable delay.
| Field | C type | Meaning |
|---|---|---|
offset_us | int32_t | The host chip's clock minus the device chip's. Add it to a DEVICE_CHIP stamp to read that stamp on the HOST_CHIP timeline; subtract to go the other way. |
rate_ppb | int32_t | Relative drift in parts per billion, for extrapolating between exchanges. MEDIUS_CLOCK_RATE_NONE means no drift was fitted, which differs from a fitted 0. |
delay_us | uint16_t | The best round trip measured in the window. The offset is good to ~half of it, which tells you whether a cross-domain comparison is worth making. |
age_ms | uint32_t | How old the estimate is. MEDIUS_CLOCK_AGE_NONE means never measured. Never measured and a measured zero offset both read offset_us == 0; only the measured one is usable. |
MediusImperfectStatus Imperfect-clone state (each 0 or 1)
From medius_device_query_imperfect. See Options.
| Field | C type | True (1) when |
|---|---|---|
allowed | uint8_t | The opt-in toggle; cloning a device the box can't clone faithfully is allowed. |
over_capacity | uint8_t | The real device has >4 IN endpoints live at once (the box has four transmit FIFOs), >6 HID interfaces, or runs at high speed. |
clone_imperfect | uint8_t | The live clone is imperfect: an opted-in device the box can't clone faithfully, a forced rate, or an applied patch set. |
MediusEmitPaceStatus Emit-rate pacing state
From medius_device_query_emit_pace. See Options.
| Field | C type | Meaning |
|---|---|---|
mode | MediusEmitMode | The pace. |
fixed_hz | uint16_t | The rate requested for FIXED (0 otherwise). |
resolved_hz | uint16_t | The ceiling in effect. 0 = learnt/adaptive, or INTERVAL with no device yet; 1000 once the renderer has a profile. |
force_hz | uint16_t | The forced wire rate requested; 0 leaves the native interval. |
advertised_hz | uint16_t | What the clone's input endpoints advertise now, forced or native; 0 = no clone. |
force_active | uint8_t | 1 when a forced interval is written into the descriptor being served. |
MediusRenderStatus Rendering texture
From medius_device_query_render. See Options.
| Field | C type | Meaning |
|---|---|---|
mode | MediusRenderMode | The texture stored on the box. |
full | uint8_t | 1 when native motion is rendered by the model rather than relayed. |
ready | uint8_t | 1 once a profile has armed for the real device. Nothing is rendered until it has. |
MediusSpreadStatus How far an injected delta is spread in time
From medius_device_query_spread. See Options.
| Field | C type | Meaning |
|---|---|---|
percent | uint16_t | Share of the command interval a delta is released across; 0 is the whole delta on the next report. |
span_us | uint32_t | The interval in effect, in microseconds; 0 when nothing is released across an interval. |
MediusCountersSnapshot Host-side always-on link counters
From medius_device_counters. See Logs & counters.
| Field | C type | Meaning |
|---|---|---|
frames_tx | uint64_t | Frames sent to the box. |
frames_rx | uint64_t | Frames received from the box. |
crc_drops | uint64_t | Inbound frames dropped on a bad checksum. |
reconnects | uint64_t | Times the library reopened the port. |
restarts | uint64_t | Device-chip restarts the library recovered from by re-sending the state it holds. A session release (counted in MediusStats.session) does not count here. See session recovery. |
MediusPortInfo Discovered medius serial port
Filled by medius_find_ports. Canonical docs on PortInfo.
| Field | C type | Meaning |
|---|---|---|
path | char[MEDIUS_MAX_PATH] | Serial port path (NUL-terminated). |
vid | uint16_t | USB vendor id (0x1A86). |
pid | uint16_t | USB product id (0x55D3). |
serial | char[MEDIUS_MAX_SERIAL] | The CH343 adapter's serial (NUL-terminated); empty when has_serial == 0. |
has_serial | uint8_t | Whether the adapter serves a serial string. |
MediusBoxInfo One discovered box: port, version, and cloned device
Filled by medius_list: one entry per connected box, each read in turn. See BoxInfo.
| Field | C type | Meaning |
|---|---|---|
port | MediusPortInfo | The box's control port (path + CH343 serial). |
version | MediusVersion | Its firmware version and control protocol, with the box MAC and name. |
device | MediusDeviceInfo | The device it clones; zeroed when has_device is 0. |
has_device | uint8_t | 0 for a box whose version.proto_ver isn't the library's protocol; opening it returns MEDIUS_STATUS_ERR_BAD_PROTO_VER. |
MediusBoxInfo boxes[8];
uintptr_t total = 0;
uintptr_t n = medius_list(boxes, 8, &total);
for (uintptr_t i = 0; i < n; i++) {
const MediusBoxInfo *b = &boxes[i];
if (b->has_device)
printf("%s %04x:%04x %s\n", b->port.path, b->device.vid, b->device.pid, b->device.product);
else
printf("%s protocol %u: update its firmware\n", b->port.path, b->version.proto_ver);
}Event & log types Fixed-size PODs off the streams
Values off the catch and log streams. Semantics on Catch; canonical docs on Structs.
MediusMotionEvent One native relative-axis snapshot
Native motion at the merge point, before locks or injection apply. The Motion arm of a MediusCatchEvent, raised by a MEDIUS_CATCH_CLASS_AXIS subscription.
The enclosing event's ts_us and clock stamp it; for motion the domain is always MEDIUS_CLOCK_DOMAIN_HOST_CHIP.
| Field | C type | Meaning |
|---|---|---|
dx | int16_t | Relative X this report (right positive). |
dy | int16_t | Relative Y this report (down positive). |
dz | int16_t | Wheel delta this report (up positive). |
pan | int16_t | AC Pan (horizontal-scroll) delta this report (right positive). |
MediusUsageEvent One held-usage snapshot for a class
The held usages of one class (button, key, or media) in usages[0..n], one shape for every class. Modifiers are key usages 0xE0 to 0xE7. Test one with medius_usage_event_is_held(&event, usage). Raised by a BTN, KEY, or MEDIA subscription.
Like motion, it is stamped by the enclosing event's ts_us and clock, always MEDIUS_CLOCK_DOMAIN_HOST_CHIP.
| Field | C type | Meaning |
|---|---|---|
class_ | MediusClass | Which class this snapshot is of; carried here because an n == 0 snapshot has no entry to read it from. |
direction | uint8_t, a MEDIUS_DIRECTION_* value | The edge that produced it: the subscribed set grew (POSITIVE) or shrank (NEGATIVE). |
n | uint16_t | Live usages in usages. |
usages | MediusUsage[MEDIUS_MAX_USAGES] | The held MediusUsage usages (button, key, or media). |
The decoded-input stream diffs successive snapshots into press and release edges.
MediusTrafficEvent One captured packet off a traffic class
struct MediusTrafficEvent {
MediusCatchClass class_;
uint16_t id;
uint8_t direction;
uint8_t flags;
uint16_t true_len; /* length before capture truncation */
uint16_t len; /* bytes actually kept */
uint8_t bytes[MEDIUS_MAX_TRAFFIC_BYTES];
};The Traffic arm of a MediusCatchEvent, raised by any of the byte-oriented catch classes.
bytes is an inline array capped at MEDIUS_MAX_TRAFFIC_BYTES (180), so the event is a fixed-size POD to copy, queue, and drop with nothing to free.
| Field | C type | Meaning |
|---|---|---|
class_ | MediusCatchClass | Which class produced the event; it also selects how flags reads. |
id | uint16_t | The endpoint number or interface number, per the class. |
direction | uint8_t, a MEDIUS_DIRECTION_* value | POSITIVE = IN (device to PC), NEGATIVE = OUT (PC to device). |
flags | uint8_t | Class-specific; see the table below. 0 for classes that define none. |
true_len | uint16_t | The packet's length on the bus, before capture cut it. |
len | uint16_t | Bytes actually captured; the live prefix of bytes. |
bytes | uint8_t[MEDIUS_MAX_TRAFFIC_BYTES] | The capture, valid over bytes[0..len]. |
true_len separates a packet cut at your capture from a short one; medius_traffic_event_truncated(&ev) makes that comparison.
| Class | flags reads as | Decode it with |
|---|---|---|
MEDIUS_CATCH_CLASS_HID_IN, _EMIT | Bit 1: a zero-length packet (on a HID endpoint, possibly one that ended the report after the event's bytes). Bit 7: a rewrite rule changed, dropped, answered or refused the packet. | medius_traffic_event_zlp, medius_traffic_event_rule_acted |
MEDIUS_CATCH_CLASS_HID_OUT, _VENDOR_INTERRUPT | Bit 1: a zero-length packet. Bit 7: a rule acted. | medius_traffic_event_zlp, medius_traffic_event_rule_acted |
MEDIUS_CATCH_CLASS_VENDOR_BULK | Bit 0: end of transfer. Bit 1: a zero-length packet. Bit 7: a rule acted. | medius_traffic_event_bulk_end_of_transfer, medius_traffic_event_zlp, medius_traffic_event_rule_acted |
MEDIUS_CATCH_CLASS_CONTROL | Bits 0-1: the handshake the game PC received, below. Bit 7: a rule acted. | medius_traffic_event_control_status, into a MediusControlStatus; medius_traffic_event_rule_acted |
MEDIUS_CATCH_CLASS_CLIP_TRANSFER | How the transfer ended, a MEDIUS_TRANSFER_STATUS_* byte; 0xFE when no reply came. | medius_traffic_event_transfer_status |
MEDIUS_CATCH_CLASS_BUS | The bus event kind (table below). | medius_traffic_event_bus_event, into a MediusBusEvent |
| every other class | 0. | - |
A CONTROL or CLIP_TRANSFER event is one completed transaction. bytes holds the 8-byte SETUP packet, then the data stage (IN data only on CLIP_TRANSFER); direction says which way the data went. Split them with medius_traffic_event_setup and medius_traffic_event_data.
A CONTROL event is the transaction as the game PC received it, on any control endpoint. IN data is the reply the PC received, after any reply rule or ANSWER. OUT data is what the PC sent, before any rule rewrote it. A request the box served from its value cache still produces an event.
MediusControlStatus | Bits 0-1 | PC received |
|---|---|---|
MEDIUS_CONTROL_STATUS_OK | 0 | A completed transaction. |
MEDIUS_CONTROL_STATUS_STALLED | 1 | A STALL from the real device, from a rule that refused the request, or (above endpoint 0) for a failed request. |
MEDIUS_CONTROL_STATUS_NAKED | 2 | NAKs until the PC gave up, on endpoint 0 only. |
MEDIUS_CONTROL_STATUS_OTHER | 3 | A value this build does not know; read flags for it. |
A BUS event puts the kind in flags and up to two operands in bytes. medius_traffic_event_bus_event decodes both into a MediusBusEvent.
MediusBusEventKind | flags | Operands |
|---|---|---|
MEDIUS_BUS_EVENT_KIND_RESET | 0 | none |
MEDIUS_BUS_EVENT_KIND_SUSPEND | 1 | none |
MEDIUS_BUS_EVENT_KIND_RESUME | 2 | none |
MEDIUS_BUS_EVENT_KIND_CONFIGURED | 3 | configuration |
MEDIUS_BUS_EVENT_KIND_DECONFIGURED | 4 | none |
MEDIUS_BUS_EVENT_KIND_SET_INTERFACE | 5 | interface, alt |
MEDIUS_BUS_EVENT_KIND_DEVICE_ATTACHED | 6 | none |
MEDIUS_BUS_EVENT_KIND_DEVICE_DETACHED | 7 | none |
MEDIUS_BUS_EVENT_KIND_CLONE_UP | 8 | none |
MEDIUS_BUS_EVENT_KIND_CLONE_DOWN | 9 | none |
A chip reboot restarts its stamping clock. Call medius_timeline_reset for a chip that restarted; a device-chip restart raises MediusCountersSnapshot.restarts.
MediusCatchEvent One catch-stream event (a tagged union)
struct MediusCatchEvent {
MediusCatchEventKind kind;
uint32_t ts_us;
MediusClockDomain clock;
union MediusCatchEventData {
MediusMotionEvent motion;
MediusUsageEvent usages;
MediusTrafficEvent traffic;
} data;
}Written by medius_event_stream_recv and its variants. Read the union member named by kind. See MediusClockDomain for which class lands in which domain.
| Field | C type | Meaning |
|---|---|---|
kind | MediusCatchEventKind | Which union member is live. |
ts_us | uint32_t | When the report or packet was seen, in box microseconds. Wraps every ~71.6 minutes and restarts at a chip reboot. See Catch timestamps. |
clock | MediusClockDomain | Which chip's clock ts_us came from. Compare stamps only within one domain, or map both onto this machine's clock with a MediusTimeline. |
data.motion | MediusMotionEvent | Read when kind == MOTION. |
data.usages | MediusUsageEvent | Read when kind == USAGES. |
data.traffic | MediusTrafficEvent | Read when kind == TRAFFIC. |
| Part | Bytes | Made of |
|---|---|---|
data.motion | 8 | Four int16_t deltas. |
data.traffic | 190 | 10 bytes of header once padded, plus bytes[180]. |
data.usages | 1028 | class_, direction, n, plus 256 × 4-byte MediusUsage = 1024. |
| the union | 1028 | The largest arm, so usages sets it. |
MediusCatchEvent | 1040 | kind, ts_us, clock, their padding, and the union. |
An event is 1040 bytes whichever arm is live. Padding is the compiler's; use sizeof for the exact number.
MediusLogLine One device log line
Written by medius_log_stream_recv; text is NUL-terminated.
| Field | C type | Meaning |
|---|---|---|
level | MediusLogLevel | Severity tag. |
text | char[MEDIUS_MAX_LOG_TEXT] | The decoded message (NUL-terminated). |
MediusInputEvent One decoded press, release, or motion report
struct MediusInputEvent {
MediusInputKind kind; /* PRESS = 0, RELEASE = 1, MOTION = 2 */
uint32_t ts_us;
MediusClockDomain clock; /* always HOST_CHIP for native input */
MediusUsage usage; /* the edge's usage; zeroed for MOTION */
int16_t dx, dy, dz, pan;
};Written by medius_input_stream_recv and its non-blocking siblings, as edges diffed from the box's held-usage snapshots.
| Field | C type | Meaning |
|---|---|---|
kind | MediusInputKind | Which fields are live. |
ts_us | uint32_t | The report's arrival stamp, in the clock chip's microseconds. |
clock | MediusClockDomain | Always MEDIUS_CLOCK_DOMAIN_HOST_CHIP: native input is stamped on the host chip. |
usage | MediusUsage | The button, key, or media usage that changed; zeroed for MOTION. |
dx, dy, dz, pan | int16_t | Relative X, Y, wheel, and AC Pan this report; zero unless kind is MOTION. |
MediusStamped One event placed on this machine's clock
struct MediusStamped {
uint64_t host_ns; /* on the caller's monotonic scale */
uint64_t box_us; /* unwrapped past the 32-bit rollover */
uint64_t excess_ns; /* jitter above the measured floor */
};Written by medius_timeline_observe. host_ns comes back on the same scale as the now_ns you passed in.
| Field | C type | Meaning |
|---|---|---|
host_ns | uint64_t | When the event happened, on the caller's monotonic clock. |
box_us | uint64_t | The event's stamp, unwrapped: a raw ts_us wraps every ~71.6 minutes. |
excess_ns | uint64_t | How much later than the measured floor this event reached the caller. Jitter, not latency. |
MediusClipTrigger One native-input binding that drives the clip
A managed binding added with medius_clip_bind: when on hits edge, the box runs action on the clip. Build on with the medius_usage_* helpers. See Clip.
| Field | C type | Meaning |
|---|---|---|
on | MediusUsage | The native button, key, or media usage that fires the binding. |
edge | MediusEdge | Which edge of on fires it. |
action | MediusClipAction | What the binding does to the clip. |
consume | uint8_t | 1 hides the input from the game PC; 0 relays it. |
MediusClipPacketTrigger One packet binding that drives the clip
A managed binding added with medius_clip_bind_packet, keyed by (class_, id, direction, match_bytes, mask). When a packet's head matches under the mask, the box runs action on the frame clock's next tick. medius_clip_query_config reads back the same shape, so a trigger read back can be bound again as is. See Clip.
| Field | C type | Meaning |
|---|---|---|
class_ | uint8_t | The surface the packet crosses: MEDIUS_CATCH_CLASS_HID_IN, _HID_OUT, _VENDOR_INTERRUPT, _VENDOR_BULK, _CONTROL or _EMIT. |
id | uint16_t | The interface number for HID_IN, the endpoint number for the rest, or MEDIUS_CATCH_ID_ANY. |
direction | uint8_t | A MEDIUS_DIRECTION_* value: POSITIVE (IN), NEGATIVE (OUT) or BOTH. |
action | uint8_t | A MEDIUS_CLIP_ACTION_* value. |
consume | uint8_t | 1 drops every packet this trigger matches as the top-ranked trigger, before the rewrite table sees it. The box holds a consuming trigger only with the imperfect-clone opt-in on (medius_device_allow_imperfect_clones), and on any class but CONTROL. |
once_per_run | uint8_t | 1 runs action on the first packet of a run of matching packets; 0 runs it on each. A run needs one stream: a class other than CONTROL, a concrete id, and POSITIVE or NEGATIVE. |
selector_len | uint8_t | With once_per_run: how many leading match bytes pick the run's stream within the address (a report ID, for example). The remaining bytes are the condition, so selector_len < match_len. 0 without once_per_run. |
match_len, mask_len | uint16_t | Valid bytes in match_bytes / mask (equal). 0 takes every packet on the address. |
match_bytes, mask | uint8_t[MEDIUS_MAX_PKT_MATCH] | The head compare: a packet matches when head[i] & mask[i] == match_bytes[i] for each byte. |
hits | uint16_t | Packets matched as the top-ranked trigger since the trigger was bound or overwritten (saturating). Filled by medius_clip_query_config and read by medius_mock_set_clip_settings; medius_clip_bind_packet does not send it. |
/* Report ID 7 on interface 2 carries a button in bit 5 of its second byte. Start once per hold. */
MediusClipPacketTrigger held = {
.class_ = MEDIUS_CATCH_CLASS_HID_IN, .id = 2,
.direction = MEDIUS_DIRECTION_POSITIVE,
.action = MEDIUS_CLIP_ACTION_START,
.once_per_run = 1, .selector_len = 1,
.match_len = 2, .mask_len = 2,
.match_bytes = { 0x07, 0x20 }, .mask = { 0xFF, 0x20 },
};
MediusStatus st = medius_clip_bind_packet(clip, &held);
if (st == MEDIUS_STATUS_ERR_CLIP_PACKET_TRIGGER) { /* medius_last_error_message() says why */ }
MediusClipSettings cfg;
medius_clip_query_config(clip, &cfg);
for (uint8_t i = 0; i < cfg.packet_n; i++)
printf("action %u, %u hits\n", cfg.packet_triggers[i].action, cfg.packet_triggers[i].hits);
medius_clip_unbind_packet(clip, &held); /* by key */MediusClipSettings Clip configuration read back from the box
From medius_clip_query_config. See Clip.
| Field | C type | Meaning |
|---|---|---|
autolock_bits | uint8_t | The auto-lock scope as CLIP_LOCK_* wire bits (set with medius_clip_set_autolock). |
loop_ | uint8_t | Playback loops at the clip end (retained mode only). |
retain | uint8_t | The loaded clip is retained so it can rewind and replay (0 = streaming). |
finalized | uint8_t | A retained clip's end is fixed, so it can replay and loop. |
ride | uint8_t | The clip's motion waits for a native move under movement riding. |
triggers | MediusClipTrigger[MEDIUS_CLIP_TRIG_MAX] | The bound input triggers, triggers[0..n]. |
n | uint8_t | Live entries in triggers. |
packet_triggers | MediusClipPacketTrigger[MEDIUS_CLIP_PKT_TRIG_MAX] | The bound packet triggers, packet_triggers[0..packet_n], in the order the box holds them, each with its hits. |
packet_n | uint8_t | Live entries in packet_triggers. |
MediusClipStatus & MediusClipState Buffered-clip ring and playback state
From medius_clip_query_status; state is a MediusClipState. See Clip.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_CLIP_STATE_IDLE | 0 | No clip playing (empty, or a loaded clip parked at its start). |
MEDIUS_CLIP_STATE_PLAYING | 1 | Draining the ring, one entry per native frame. |
MEDIUS_CLIP_STATE_PAUSED | 2 | Halted mid-clip; the cursor and any held usages are retained. |
MEDIUS_CLIP_STATE_FAULTED | 3 | An append was dropped or the ring overflowed; recover with medius_clip_clear. |
| Field | C type | Meaning |
|---|---|---|
state | MediusClipState | The lifecycle state. |
free | uint32_t | Ring bytes free; pace top-ups off this. |
total | uint32_t | Retained: the clip size in bytes. Streaming: the bytes buffered but not yet played. |
played | uint32_t | Bytes played from the clip start (retained progress; ~0 while streaming). |
ticks | uint32_t | Content frames played since the box booted (gap runs are not counted). |
underruns | uint16_t | Empty-ring episodes. |
overruns | uint16_t | Appends dropped because the ring was full. |
seq_gaps | uint16_t | Dropped append frames detected. |
xfers | uint16_t | Clip transfers the real device completed. |
xfer_errs | uint16_t | Clip transfers that ended any other way: a refusal, no reply, no room in the box's queue, or dropped behind a transfer the real device did not reply to. |
gated | uint16_t | Raw reports and transfers the box discarded because the imperfect-clone opt-in was off. |
held_n | uint16_t | Held usages in held. |
held | MediusUsage[MEDIUS_MAX_USAGES] | The buttons, keys, and media the clip is holding down; test one with medius_clip_status_is_held. |
MediusSetup USB control-transfer setup packet
Passed by value to medius_device_transfer and medius_clip_frame_transfer. The eight bytes of a USB §9.3 setup packet, little-endian on the wire. See Control transfers.
| Field | C type | Meaning |
|---|---|---|
request_type | uint8_t | bmRequestType: direction in bit 7 (set = device-to-host). |
request | uint8_t | bRequest. |
value | uint16_t | wValue. |
index | uint16_t | wIndex. |
length | uint16_t | wLength: the data-stage length. |
MediusTransferOutcome Real device's reply to a control transfer
Filled by medius_device_transfer. MEDIUS_STATUS_OK means only that the box replied; status is the transfer's result.
| Field | C type | Meaning |
|---|---|---|
status | uint8_t | A MEDIUS_TRANSFER_STATUS_* value (see below). |
len | uint16_t | Valid bytes in data. |
data | uint8_t[MEDIUS_MAX_DEV_PAYLOAD] | The IN data the real device returned. |
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_TRANSFER_STATUS_OK | 0x00 | Completed; data is in data. |
MEDIUS_TRANSFER_STATUS_REFUSED | 0xFC | The box refused it before it reached the real device: opt-in off, malformed, wLength >504 or OUT data shorter than wLength, or the host chip's control queue full. |
MEDIUS_TRANSFER_STATUS_STALL | 0xFD | The real device STALLed. |
MEDIUS_TRANSFER_STATUS_NAK | 0xFE | One of: the real device did not finish within 500 ms, the transfer failed on the bus, the endpoint is undeclared, no reply crossed the link within 800 ms, or the game PC has suspended the clone (and with it the real device). |
MEDIUS_TRANSFER_STATUS_NO_DEVICE | 0xFF | No real device attached to the host chip. |
MediusRewriteRule One rewrite rule, as set and read back in full
Passed to medius_device_set_rewrite and filled by medius_device_query_rewrite_entry. A rule is keyed by (class_, id, direction, match, mask). See Rewrite rules.
| Field | C type | Meaning |
|---|---|---|
class_ | uint8_t | A MEDIUS_REWRITE_CLASS_* value (see below). |
id | uint16_t | Interface number or endpoint number. |
direction | uint8_t | A MEDIUS_DIRECTION_* value (BOTH/POSITIVE/NEGATIVE). |
action | uint8_t | A MEDIUS_REWRITE_ACTION_* value (see below). |
offset | uint16_t | Where a patching action writes. |
match_len, mask_len | uint16_t | Valid bytes in match_bytes / mask (equal). |
match_bytes, mask, payload | uint8_t[] | The head compare and the action's payload. |
| MediusRewriteClass | Value | MediusRewriteAction | Value |
|---|---|---|---|
_HID_IN | 4 | _PASS | 0 |
_HID_OUT | 5 | _DROP (report only) | 1 |
_VENDOR_INTERRUPT | 6 | _PATCH | 2 |
_VENDOR_BULK | 7 | _REPLACE | 3 |
_CONTROL | 8 | _ANSWER (control) | 4 |
_EMIT | 9 | _STALL / _NAK (control) | 5 / 6 |
_ANY | 0xFF | _REPLY_PATCH / _REPLY_REPLACE (control) | 7 / 8 |
MediusRewriteTable & MediusRewriteEntry Rewrite-table summary
Filled by medius_device_query_rewrite: a full flag, a generation counter, and one MediusRewriteEntry per rule (address, action, match_len, offset, payload_len, and saturating hits) without the bytes.
| Field | C type | Meaning |
|---|---|---|
table_full | uint8_t | The box refused the last new rule or overwrite for lack of room: all 32 entries in use, or the 2048-byte payload pool full. The next change to the table, or a clear, resets it. |
generation | uint8_t | Goes up by one on each change to the table, including a clear or silence that empties it; an identical re-send leaves it unchanged. Reset, detach, link loss, re-clone and opt-in off return it to 0. The keepalive re-sends every held rule whatever generation reads. |
n | uint16_t | Valid entries in entries. |
entries | MediusRewriteEntry[MEDIUS_MAX_REWRITE_ENTRIES] | One row per rule. |
MediusPatch One descriptor patch, as set and read back in full
Passed to medius_device_set_patch and filled by medius_device_query_patch_entry. Keyed by (section, cfg, index, offset); a len of 0 removes the patch at that key. See Descriptor patches.
| Field | C type | Meaning |
|---|---|---|
section | uint8_t | A MEDIUS_PATCH_SECTION_* value: _DEVICE 0, _CONFIG 1, _REPORT 2, _STRING 3, _BOS 4. |
cfg | uint8_t | Configuration index, for Config/Report. 0 is the first configuration, not bConfigurationValue. |
index | uint8_t | Interface or string index, for Report/String. |
offset | uint16_t | Byte offset within the descriptor. |
len | uint16_t | Valid bytes in bytes; 0 removes the patch. |
bytes | uint8_t[MEDIUS_MAX_DEV_PAYLOAD] | The overwrite bytes. |
MediusPatchSet & MediusPatchEntry Stored patch set and its apply state
Filled by medius_device_query_patches: the four apply-state flags and one MediusPatchEntry per patch (section, cfg, index, offset, len) without the bytes.
| Field | C type | Set when |
|---|---|---|
applied | uint8_t | The clone serves a non-empty patched set. A later store leaves the flag as is until the next presentation. |
pending | uint8_t | The stored set differs from the one the clone serves: not applied yet, changed or emptied since, refused, or held back by the opt-in. |
refused | uint8_t | The stored set failed a clone or consistency check when last presented, and hasn't changed since. The clone is presented unpatched; the box log names the check. |
table_full | uint8_t | The box refused the last new patch or overwrite for lack of room: 16 patches, or the 1024-byte pool full. The next change to the set, or a clear, resets it. |
n, entries | uint16_t, MediusPatchEntry[] | The stored patches. |
MediusTransform One field transform
Passed to medius_device_transform and returned in the query table. source and dest are MediusLockTargets, and may not name the same field. To weigh or reverse a field, use medius_device_scale (signed percent). See Transform.
| Field | C type | Meaning |
|---|---|---|
op | uint8_t | A MEDIUS_TRANSFORM_OP_* value: _REMAP 0, _SWAP 1. |
source | MediusLockTarget | The field the transform reads. |
dest | MediusLockTarget | The field it writes. |
MediusTransforms Transform-table summary
Filled by medius_device_query_transforms: a full flag and one MediusTransform per entry, up to MEDIUS_MAX_TRANSFORM_ENTRIES (32).
| Field | C type | Meaning |
|---|---|---|
table_full | uint8_t | A further entry was, or would be, refused. |
n | uint16_t | Valid entries in entries. |
entries | MediusTransform[MEDIUS_MAX_TRANSFORM_ENTRIES] | One entry per transform. |
ErrorsMediusStatus plus a thread-local message
enum MediusStatus : int32_t /* MEDIUS_STATUS_OK == 0; everything else is a failure */
Every fallible call returns a MediusStatus and writes its result through an out-param. On failure the detail is thread-local; read it before the next call on that thread overwrites it. Canonical mapping on Errors.
| Enumerator | Value | Meaning |
|---|---|---|
MEDIUS_STATUS_OK | 0 | Success. |
MEDIUS_STATUS_ERR_IO | 1 | An underlying serial or OS error. |
MEDIUS_STATUS_ERR_NOT_FOUND | 2 | No port has the box's VID/PID, or no box matches the discovery id or kind. |
MEDIUS_STATUS_ERR_NO_REPLY | 3 | The box never replied to the version query during the handshake. |
MEDIUS_STATUS_ERR_BAD_PROTO_VER | 4 | The box replied with an unexpected proto_ver (see medius_last_error_proto_ver), including a box the discovery openers matched. |
MEDIUS_STATUS_ERR_QUERY_TIMEOUT | 5 | A query waited past its timeout with no reply. |
MEDIUS_STATUS_ERR_DISCONNECTED | 6 | The link dropped (also returned by a stream when it closes). |
MEDIUS_STATUS_ERR_FRAME_TOO_LONG | 7 | An outbound frame exceeded the wire limit. |
MEDIUS_STATUS_ERR_UPDATE | 8 | The box refused a firmware update op. |
MEDIUS_STATUS_ERR_INVALID_ARG | 9 | A bad argument (e.g. a null required pointer). |
MEDIUS_STATUS_ERR_PANIC | 10 | A Rust panic was caught at the boundary. |
MEDIUS_STATUS_ERR_UNKNOWN | 11 | An unclassified failure. |
MEDIUS_STATUS_ERR_CATCH_TABLE_FULL | 12 | The subscription needs more entries than the box's table holds. |
MEDIUS_STATUS_ERR_EMPTY_SUBSCRIPTION | 13 | A catch subscription with no filters, which would never yield an event. |
MEDIUS_STATUS_ERR_CAPTURE_NOT_APPLICABLE | 14 | A non-zero capture on an input class, which carries no packet. |
MEDIUS_STATUS_ERR_NOT_AN_INPUT_FILTER | 15 | A traffic class passed to medius_device_input_events, which cannot decode one. |
MEDIUS_STATUS_ERR_WILDCARD_NOT_INPUT | 16 | The everything filter passed to medius_device_input_events; it covers traffic too. |
MEDIUS_STATUS_ERR_HALF_EDGE_INPUT_FILTER | 17 | An input filter narrowed to one edge, which cannot be decoded into press and release. |
MEDIUS_STATUS_ERR_RESERVED_ID | 18 | An exact id equal to the blanket sentinel, which would address the whole class. |
MEDIUS_STATUS_ERR_RELATIVE_DIRECTION | 19 | MEDIUS_DIRECTION_WITH or _AGAINST where only a fixed sign or edge can be addressed. They resolve against the bearing at emit time, after the call. |
MEDIUS_STATUS_ERR_LOCK_SCALE_RANGE | 20 | A lock scale outside MEDIUS_LOCK_SCALE_MIN to MEDIUS_LOCK_SCALE_MAX. |
MEDIUS_STATUS_ERR_LOCK_SCALE_USAGE | 21 | A negative (reversing) lock scale on a button, key or media usage, which carries one bit and has nothing to reverse. |
MEDIUS_STATUS_ERR_IMPERFECT_REQUIRED | 22 | medius_device_set_rewrite or medius_device_apply_patch with the imperfect-clone opt-in off. |
MEDIUS_STATUS_ERR_REWRITE_MASK_LENGTH | 23 | A rewrite rule whose match and mask are different lengths. |
MEDIUS_STATUS_ERR_REWRITE_ACTION_CLASS | 24 | A rewrite action that is not valid for its class. |
MEDIUS_STATUS_ERR_REWRITE_PAYLOAD_TOO_LARGE | 25 | A rewrite payload larger than the head the box holds for its class. |
MEDIUS_STATUS_ERR_REWRITE_TABLE_FULL | 26 | A rewrite rule added to a table that already holds MEDIUS_MAX_REWRITE_ENTRIES. |
MEDIUS_STATUS_ERR_TRANSFORM_OP_FIELDS | 27 | A transform op that cannot address its source/dest pair, or one field named as both. |
MEDIUS_STATUS_ERR_TRANSFORM_TABLE_FULL | 28 | A transform added to a table that already holds MEDIUS_MAX_TRANSFORM_ENTRIES. |
MEDIUS_STATUS_ERR_RAW_DIRECTION | 29 | A raw injection direction other than MEDIUS_DIRECTION_POSITIVE (IN) or MEDIUS_DIRECTION_NEGATIVE (OUT). |
MEDIUS_STATUS_ERR_CLIP_FRAME_COUNT | 30 | A clip frame with more than MEDIUS_CLIP_EDGES_MAX edges or MEDIUS_CLIP_RAW_MAX raw reports. |
MEDIUS_STATUS_ERR_CLIP_FRAME_TOO_LONG | 31 | A clip frame that encodes to more than MEDIUS_CLIP_ENTRY_MAX bytes. |
MEDIUS_STATUS_ERR_CLIP_TRANSFER_DATA | 32 | A clip transfer whose data is not what its setup packet announces: length bytes for an OUT request, none for an IN one. |
MEDIUS_STATUS_ERR_CLIP_PACKET_TRIGGER | 33 | A MediusClipPacketTrigger the box would refuse; medius_last_error_message says why. |
MEDIUS_STATUS_ERR_REWRITE_MATCH_TOO_LONG | 34 | A rewrite rule with more than MEDIUS_MAX_REWRITE_MATCH (16) match bytes. |
MEDIUS_STATUS_ERR_REWRITE_POOL_FULL | 35 | A rewrite payload larger than the room the held rules leave in MEDIUS_REWRITE_PAYLOAD_POOL (2048). An overwrite counts the bytes it replaces as free. |
| Function | Returns | Meaning |
|---|---|---|
medius_last_error_message(char *buf, uintptr_t cap) | uintptr_t | Copies the last error's text (NUL-terminated, truncated to cap); returns the full length, for a retry with a larger buffer. |
medius_last_error_proto_ver(void) | uint8_t | The version byte from a BAD_PROTO_VER error, or 0. |