# LLUAV WebSocket Protocol Specification

This document describes the wire protocol used by the LLUAV drone firmware's built-in WebSocket server and consumed by the SDK clients.

## Transport

- **Protocol**: WebSocket (RFC 6455)
- **Default Port**: `53001`
- **Text Frames Only**: All commands and responses are exchanged as UTF-8 text frames.

## Connection Lifecycle

1. Client opens a WebSocket connection to `ws://<host>:53001`.
2. If password protection is enabled, the client **must** send `login <password>` before any other command.
3. The server processes commands in the order received and replies with one JSON response per command.
4. The server does **not** push unsolicited messages; every response is triggered by a client command.

## Request Format

A request is a single text frame containing a command name optionally followed by arguments:

```
cmd [args]
```

- `cmd`: The command string (e.g., `takeoff`, `state`, `set_param`).
- `args`: Command-specific arguments separated from `cmd` by a single space.
  - Scalar values are passed as-is: `ledon`, `takeoff`.
  - Compound arguments use colons (`:`) for ordered fields:
    - `set_sp_ned 1.0:2.0:-3.0:0.5`
    - `test_wp 10.0:5.0:-2.0`
  - Waypoint IDs or height lists use commas (`,`):
    - `zyhk 1.5,2.0,2.5`
    - `mw_exec 1001:1,2,3,5`
  - JSON payloads are sent as raw strings when the command detects leading `{`/`[`:
    - `mission 1001:{"waypoints":[...]}`

### Authentication

```
login <password>
```

Special passwords:
- `"1025"` → grants admin privileges.
- Any other matching password → standard user.
- `"0315"` → explicitly logs the session out.

## Response Format

Every command produces exactly one JSON response:

```json
{
  "ret": 0,
  "cmd": 52,
  "ts": 1714233600000,
  ...
}
```

| Field | Type | Description |
|-------|------|-------------|
| `ret` | `int` | Return code. `0` = success. Negative values indicate errors. |
| `cmd` | `int` | Internal command enum ID (useful for correlation). |
| `ts`  | `int64` | Response timestamp in milliseconds (Unix epoch). |

On success, additional command-specific fields are included (see Command Reference below).

On failure:

```json
{
  "ret": -1,
  "cmd": 52,
  "ts": 1714233600000,
  "msg": "Not allow when vehicle is ARMED!"
}
```

### Special Error Codes

| Code | Meaning |
|------|---------|
| `0` | Success |
| `-1` | General failure (see `msg` for details) |
| `-2` | Invalid arguments / unsupported command |
| `-3` | External system call failed (e.g., `sysinfo()`, disk I/O) |
| `-100` | Unhandled exception during command processing |

## State & Permission Checks

The server enforces two gate checks before executing a command:

1. **Login Gate**: If a password is configured and the session is not logged in, all commands except `login` return `{"ret":-1,"msg":"Login first!"}`.
2. **Armed Gate**: If the vehicle is armed, commands marked `runOnArm=false` return `{"ret":-1,"msg":"Not allow when vehicle is ARMED!"}`.
3. **Lock Gate**: If `lockMode=true` and the user is not admin, commands marked `runInLock=false` return `{"ret":-1,"msg":"CMD not permitted to run in LOCK mode!"}`.

## Command Reference

### State & Telemetry

| Command | Args | Response Fields |
|---------|------|-----------------|
| `state` | — | `state`: full FSM state JSON |
| `param` | — | `param`: all parameters JSON |
| `get_param` | `name` | `param`: single parameter JSON |
| `ver` | — | `version`: version info JSON |
| `sysinfo` | — | `sysinfo`: uptime, RAM, loads |
| `diskusage` | — | `available_MB`: free space |
| `statics` | — | `comm`, `rosrecord`, `stat`, `node_boot_sec` |
| `machineid` | — | `did`: unique hardware ID |
| `hud1` | — | `kfs`, `uav_pos_enu`, `extra` |
| `lidarpose` | — | `lidar_pose`: `{x,y,z,yaw,roll,pitch,frame,usec}` |
| `apron_state` | — | `apron_status`, `apron_comm` |
| `mavlink_msgs` | — | `mav_msgs`: message name → count map |
| `get_submap_info` | — | `kfs`: map ID and keyframe count |
| `show_sp` | — | Current setpoint data |
| `show_apguid2` | — | `guid2` |
| `showmsg` | `[count]` | `msgs`: recent log messages |

### Flight Control

| Command | Args | Description |
|---------|------|-------------|
| `takeoff` | — | Initiate takeoff |
| `land` | — | Emergency land |
| `rtl` | — | Return to launch |
| `mrtl` | — | Mission RTL |
| `tether_land` | — | Tethered landing |
| `set_sp_ned` | `x:y:z:yaw` | Set NED setpoint (meters, radians) |
| `tunnelfly` | `0` or `1` | Enable/disable tunnel fly mode |
| `disarm` | — | Force disarm |
| `sleep` | — | Enter sleep mode |
| `wakeup` | — | Wake from sleep |
| `autosleep_enable` | `0` or `1` | Enable auto-sleep |
| `zyhk` | `h1,h2,... [lx,ly,lyaw]` | Multi-height hover then land |
| `relocate_pos` | `x,y,z,yaw` | Relocate position (requires map_locate enabled) |

### Mission Management

| Command | Args | Description |
|---------|------|-------------|
| `mission` | `ext_id:path_or_json` | Submit a mission |
| `plan` | `plan_string` | Start a flight plan |
| `unlock_plan` | — | Clear plan execution lock |
| `mw_list` | — | List mission waypoints |
| `mw_exec` | `ext_id:wp_ids` | Execute waypoint IDs (comma-separated) |
| `ai1_mission` | `task_id:mission_file` | Submit AI1 mission |
| `obs_mission` | `0` or `1` | Toggle obstacle mission live mode |
| `dump_missionresult` | `[ext_id]` | Dump mission result |
| `dump_missionlist` | — | Dump short mission request list |
| `abort_report` | `[abort_id]` | Abort/finish mission report |
| `set_taskname` | `name` | Set current task name |

### Map Management

| Command | Args | Description |
|---------|------|-------------|
| `savemap` | `path` | Save current map |
| `set_maplocate` | `0` or `1` | Enable/disable map localization |
| `set_mappath` | `path` | Set localization map path |
| `list_maps` | — | List saved maps |
| `rm_map` | `name` | Remove a saved map |

### Camera & Recording

| Command | Args | Description |
|---------|------|-------------|
| `capture` | — | Capture RGB + infrared photo |
| `snapshot` | — | System snapshot |
| `record` | — | Toggle video recording |
| `savebag` | `0` or `1` | Start/stop ROS bag recording |
| `siyi_reboot` | — | Reboot SIYI camera/gimbal |
| `siyi_format` | — | Format SIYI SD card |
| `siyi_center` | — | Center SIYI gimbal |
| `siyi_init` | — | Initialize SIYI (close HDMI) |
| `siyi_downvideo` | `[vid]` | Download latest video |
| `siyi_sync` | — | Trigger SIYI sync |

### LED Control

| Command | Args | Description |
|---------|------|-------------|
| `ledon` | — | Turn LED on |
| `ledoff` | — | Turn LED off |
| `ledenable` | — | Enable LED control |
| `leddisable` | — | Disable LED control |
| `ledpwm` | `pwm` | Set LED PWM value |
| `led_blink` | — | Start LED blinking |

### Parameter Management

| Command | Args | Description |
|---------|------|-------------|
| `set_param` | `name:value` | Set parameter |
| `get_param` | `name` | Get single parameter |
| `reset_param` | — | Reset all to defaults |
| `save_param` | `0` or `1` | Save parameters persistently |
| `passwd` | `new_password` | Change WS login password |

### Apron (Charging Pad)

| Command | Args | Description |
|---------|------|-------------|
| `apron_vol` | `voltage` | Set charging voltage |
| `apron_amp` | `amperage` | Set charging amperage |

### System Management

| Command | Args | Description |
|---------|------|-------------|
| `reboot_node` | — | Reboot flight control node |
| `reboot_ap` | — | Reboot autopilot |
| `reboot_system` | — | Reboot onboard computer |
| `poweroff_system` | — | Power off onboard computer |
| `prepare_poweroff` | — | Flush logs before poweroff |
| `reboot_dlo` | — | Reboot DLO |
| `restart_dlo` | — | Restart DLO pipeline |
| `kill_livox` | `[script]` | Kill Livox driver |

### Lidar & Perception

| Command | Args | Description |
|---------|------|-------------|
| `lidaronoff` | `0` or `1` | Turn lidar on/off |
| `lidarwarn` | — | Get lidar warning zones |
| `utg_get` | — | Trigger UTG thickness read |
| `utg_set` | `speed` | Set UTG sonic speed |

### Other

| Command | Args | Description |
|---------|------|-------------|
| `grabber_ctrl` | `pwm` | Control grabber PWM |
| `ara8_center` | — | Set ARA8 to center mode |
| `ara8_pitch` | `angle` | Set ARA8 pitch (-90..90) |
| `cv_test` | — | Trigger CV server test |
| `preflight_check` | — | Run preflight checks |
| `preflight_enable` | `0` or `1` | Enable preflight before takeoff |
| `clear_bags` | `[min_gb]` | Clear old bag files |
| `clear_images` | `[min_gb]` | Clear old images |
| `list_imagedir` | `[size]` | List image directories |
| `rm_imagedir` | `name` | Remove image directory |
| `test_wp` | `x:y:z` | Test waypoint reachability |
| `test_listwp` | `file_path` | Test waypoint list from file |
| `test_notif` | — | Test notification server |
| `savemsg` | — | Save messages to log |
| `bms_setpower` | `0` or `1` | Set BMS power output |
| `bms_setcharge` | `0` or `1` | Set BMS charge state |
| `help` | — | List available commands |
| `admin_lock` | — | Enable admin lock (admin only) |
| `admin_unlock` | — | Disable admin lock (admin only) |
