Skip to content

mxmgorin/retsend

Repository files navigation

retsend

Wireless file transfer for retro handhelds.

CI Linux ARM Linux Dependencies

retsend (retro + sending) is a Rust LocalSend client for retro handhelds: send and receive files with your phone or PC over Wi-Fi, no cable or SSH. Compatible with the official LocalSend apps.

It targets PortMaster-compatible Linux handhelds (Knulli, muOS, ROCKNIX — Anbernic/TrimUI 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 or setting up SSH/SMB. Phones and desktops already have LocalSend — this is the missing end: a client built for a gamepad and screen, moving files both ways.

Features

  • Discovery — a live radar of nearby devices (LocalSend protocol v2.1).
  • Receive — accept/decline dialog with countdown, speed/ETA, and cancel from either side; quick-save mode auto-accepts.
  • Send — gamepad file browser with multi-select and per-file progress.
  • Save routes — sort received files into folders by extension, e.g. ROMs straight into each console's folder.
  • Encryption — the protocol's HTTPS mode, on by default; works with the official app's default settings both ways.
  • Settings on device — alias, save folder, and port, applied live.
  • Headlessretsend --receive runs with no screen, for SSH and scripting.
  • Small and simple — no async runtime, a minimal HTTP server, system SDL2.

Install (PortMaster devices)

Grab retsend-portmaster.zip from Releases and unpack it into your ports folder (e.g. /roms/ports/).

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 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
  • [transfer] history_limit — max transfers kept in the History tab (default 200)

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