<!-- Source: https://medius.k4tech.net/native/quickstart -->
# Quickstart

_Plug in and send your first command_

A Medius box sits inline between a USB device and a PC. The real device passes through, and your program sends input of its own (cursor and buttons for a mouse, keys and media for a keyboard) over a USB-serial link. Below: wire it, open the link, send one movement command. Every step is byte-exact firmware behavior.

The box talks in [frames](/native/frame.md), small fixed-shape packets that each carry one command. Most are [fire-and-forget](/native/injection.md#fire-and-forget): you send and move on with no reply. The exception is [`QUERY`](/native/commands/requests.md#requests), which gets one answer back.

## Wire it up

_The safe 3-port layout_

-   `USB1` ([clone](/native/hardware.md)) → game PC
-   `USB2` (control) → control PC
-   `USB3` (mouse) → real mouse

The clone copies the real mouse's USB identity, so the game PC sees the same device it would if the mouse were plugged in directly.

> **Danger**
>
> Never connect `USB1` and `USB3` to the same machine. The `USB3` 5V rail can't be pulled low in firmware, so wiring both to one machine back-feeds power and can force a shutdown and drain the battery. One game PC, one control PC, never the same machine.

Full port map and hazard detail on [Hardware](/native/hardware.md).

## Open the link

_Open at the fixed baud, speak binary_

Open `/dev/ttyACM0` (Linux) or `COMx` (Windows) at `4,000,000` baud, `8N1`, and speak binary immediately. There's no `115200` handshake and no baud-switch frame.

[`RESP`](/native/commands/requests.md#resp) is the box's reply to a question. To learn the protocol version:

1.  On first contact the box sends one [`RESP(VERSION)`](/native/commands/requests.md#version) on its own, with [`SEQ`](/native/frame.md#seq) `0`, your ready signal. Or send [`QUERY(VERSION)`](/native/commands/requests.md#version) yourself.
2.  Read `proto_ver` from the `VERSION` payload, the one-byte protocol version the firmware speaks.
3.  Check `proto_ver == 3` before trusting the commands here. This documents version `3`.

Serial framing detail on [Transport](/native/transport.md#serial); handshake and presence detail on [Connection](/native/connection.md).

## Send a MOVE

_Relative cursor movement_

[`MOVE`](/native/commands/move.md#move) nudges the cursor on the PC. Its frame has the standard shape, laid out byte-by-byte below.

-   [`SEQ`](/native/frame.md#seq) is a number you pick and increment per frame. For a [`QUERY`](/native/commands/requests.md#requests) the box echoes it in the matching [`RESP`](/native/commands/requests.md#resp) so you can pair reply to request; here `0`.
-   `CRC16` lets the box reject a corrupted frame. It is [CRC16-CCITT](https://en.wikipedia.org/wiki/Cyclic_redundancy_check) (polynomial `0x1021`, initial value `0xFFFF`) over `TYPE | SEQ | LEN | PAYLOAD`, stored little-endian.

```python
import struct

def crc16_ccitt(data):
    crc = 0xFFFF
    for b in data:
        crc ^= b << 8
        for _ in range(8):
            crc = (crc << 1) ^ 0x1021 if crc & 0x8000 else crc << 1
            crc &= 0xFFFF
    return crc

def encode(type, seq, payload):
    head = bytes([type, seq]) + struct.pack('<H', len(payload)) + payload
    return bytes([0xA5]) + head + struct.pack('<H', crc16_ccitt(head))

frame = encode(0x01, 0, struct.pack('<Bhh', 0, 100, 0))
port.write(frame)
```

[`MOVE`](/native/commands/move.md#move) has opcode `0x01`. Its payload is a `motion` byte (`0` = cursor) then two signed 16-bit deltas, `dx` then `dy`. `+x` is right, `+y` is down. The example moves 100 right, 0 down.

That builds the bytes `A5 01 00 05 00 00 64 00 00 00 <crc>`: start byte, opcode `0x01`, sequence, length, the `motion`/`dx`/`dy` payload, then the checksum. The byte-by-byte breakdown is on [`MOVE`](/native/commands/move.md#move), the frame format on [Frame Format](/native/frame.md).

## Confirm

_Check the chain before relying on injection_

[Injection](/native/injection.md) is the input your program sends on top of the real mouse's passthrough. Confirm the chain (real mouse → box → PC) is live before you rely on it: send [`QUERY(HEALTH)`](/native/commands/requests.md#health), read the `flags` byte from the [`RESP`](/native/commands/requests.md#resp), and check these bits are set.

| Flag | Mask | Means |
| --- | --- | --- |
| `LINK_UP` | `0x01` | The link to the host chip is up. |
| `MOUSE_ATTACHED` | `0x02` | A mouse is on `USB3`. |
| `CLONE_CONFIGURED` | `0x04` | The game PC has enumerated the clone. |

A flag is set when `(flags & mask)` is non-zero. With all three set, your [`MOVE`](/native/commands/move.md#move) reaches the game PC. The full byte is on [HEALTH](/native/commands/requests.md#health).

## Skip the framing

For a ready-made client, `cargo add medius`. See the [library](/library.md).
