Skip to content

Repository files navigation

retsend

Wireless file transfer for retro handhelds.

CI Linux ARM Linux Dependencies

retsend (retro + sending) is a LocalSend-protocol file-transfer client written in Rust, using SDL2 for windowing and input and egui for the UI. Receive ROMs from your phone or PC to the device and send saves or screenshots back over wifi — no cable, no SSH. Fully compatible with the official LocalSend apps.

It targets PortMaster-compatible Linux handhelds (Knulli, muOS, ROCKNIX — Anbernic/TrimUI/Miyoo class devices, gamepad-only, no compositor) and runs on regular desktop Linux too.

Why?

Getting files onto a handheld usually means pulling the SD card, plugging in a cable, or setting up SSH/SMB. Meanwhile every phone and desktop can run LocalSend. What's missing is the other end: a client built for a gamepad and a screen with no desktop behind it. This is that client — files move in both directions.

Features

  • Discovery (LocalSend protocol v2.1) — UDP multicast and the TCP /register exchange; a live radar of nearby devices.
  • Receive — accept/decline dialog with a countdown, streaming to .part,
  • sanitized file names, speed/ETA, cancel from either side; a quick-save mode auto-accepts.
  • Send — gamepad file browser with multi-select that survives folder navigation; per-file progress, cancel, partial accepts handled.
  • Encryption — the protocol's https mode, on by default: a persisted self-signed identity, announce fingerprint = its SHA-256. Works with the official app's default settings both ways.
  • Settings on device — alias, save folder picker, port; applied live.
  • Headlessretsend --receive: no screen, auto-accept, progress on stdout. For ssh sessions and scripting.
  • Small and simple — threads instead of an async runtime, a minimal hand-rolled HTTP server, system SDL2; the protocol stack is SDL-free and tested headless over real TCP.

Install (PortMaster devices)

Grab retsend-portmaster.zip from Releases and unpack it into your ports folder (e.g. /roms/ports/). Received files land in the ROMs root by default — change the folder in Settings.

Building & running (desktop)

System SDL2 is the only native dependency. On Debian/Ubuntu:

sudo apt-get install -y build-essential pkg-config libsdl2-dev
cargo run

Files passed as arguments (cargo run -- file1 file2) come pre-selected in the send browser.

Two instances on one machine discover each other (multicast loopback) — handy for trying both sides of a transfer without a second device:

RETSEND_DATA_DIR=/tmp/ls-a cargo run &
RETSEND_DATA_DIR=/tmp/ls-b cargo run

Tests are headless (no SDL, no network setup needed):

cargo test

Controls

Pad Keyboard Action
D-pad / stick Arrows Navigate
A Enter Send to device · select file · accept · type
B Esc Back · decline · cancel · erase (keyboard)
Start F1 Jump to Settings tab · confirm send · OK (keyboard)
Select Tab / F5 Refresh radar · switch roots · layer (keyboard)
L1 / R1 PgUp / PgDn Switch tabs · page the file browser

Configuration

config.toml lives in the data dir (created with defaults on first run) and everything in it is also editable from the Settings screen, except:

  • [network] https = false — fall back to the protocol's plain-http mode
  • [network] announce_interval_secs — multicast announce cadence
  • [transfer] browser_roots — extra mount points for the file browser

Received files land in save_dir by default. [transfer.routes] overrides that per file extension — handy for dropping ROMs straight into each console's folder. Edit it on the device from Settings → Save routes (type the extension, pick the folder), or in the config:

[transfer.routes]
gbc = "gb"                    # relative → <save_dir>/gb
gba = "/roms/gba"             # absolute → used as-is
png = "/roms/screenshots"

Extensions match case-insensitively, folders are created on demand, and anything without a matching route still lands in save_dir.

Environment variables override paths and control logging at launch: RETSEND_DATA_DIR, RETSEND_CONFIG, RETSEND_SAVE_DIR, RETSEND_SCALE, RETSEND_GLES=0|1, RETSEND_LOG_LEVEL, RETSEND_LOG_FILE, RETSEND_PANIC_FILE.

Releases

Contributors

Languages