Install
python3 -m venv .venv source .venv/bin/activate python -m pip install -U pip # from this site tree python -m pip install downloads/mosaic_hf-0.1.0a7-py3-none-any.whl # or from a source checkout python -m pip install . # optional HF sound-card path python -m pip install "mosaic-hf[audio]" python -c "import mosaic_hf; print(mosaic_hf.__version__)" mosaic-hf --help
Try the complete console without a radio
Start here. Practice mode opens the real operator console with simulated spectrum, traffic, replies, adaptive-rate controls, and a local KISS socket. It cannot open radio hardware or transmit RF.
mosaic-modem demo # The command prints: # operator UI: http://127.0.0.1:8088/ # KISS TCP: 127.0.0.1:8001
If either port is already in use, choose free ones with --ui-port 8188 --kiss-port 8101.
In the browser, enable simulated TX, select VA6DEMO-2, open a QSO, exchange text, send 73, close the QSO, and inhibit TX. To try a KISS client, keep practice mode running and use mosaic-console --port 8001.
For a smaller waveform-only check:
mosaic-hf packet-produce --output hello.wav --payload-hex 48656c6c6f --signature 1234 mosaic-hf packet-consume --input hello.wav --signature 1234
The second command should report "crc_valid": true and payload hex 48656c6c6f ("Hello").
UHF operator station (recommended)
Primary entry point: mosaic-modem. Live receive starts with --execute. Transmit stays inhibited until you arm it in the UI or with /tx on.
# List SDRs mosaic-modem devices # Station with realtime operator console at http://127.0.0.1:8088/ mosaic-modem \ --callsign VE6SLP --ssid 1 \ --peer VA6GA-2 \ --radio bladerf-hackrf \ --profile uhf-live \ --frequency-hz 431200000 \ --fpga hostedx115-latest.rbf \ --txvga2-db 10 \ --execute --ui-port 8088 --human-events
Open the printed operator console URL. Receive is immediate; TX remains inhibited. Select a decoded callsign, open the QSO, then click TX INHIBITED and confirm only when you intend to radiate. Send 73, close the QSO, and return TX to inhibited when finished.
Keyboard without the browser
mosaic-modem ... --execute --operator-stdin --human-events --ui-port 0 # then type: /help /to VA6GA-2 /tx on CQ CQ DE VE6SLP-1 /tx off
Or attach a KISS console to TCP port 8001: mosaic-console --port 8001. Inside each KISS frame, the protocol port-number field is 0 and the command is Data. Client payloads are UTF-8 application text; the modem adds station addressing and the radio frame.
HF audio path (transceiver)
mosaic-hf-audio devices mosaic-hf-audio loopback --device <index> --text "VE6SLP TEST" mosaic-hf-audio qso \ --callsign VE6SLP --peer VA6GA-2 \ --input-device <index> --output-device <index>
That is the normal HF station command. It opens the same browser console on 127.0.0.1:8088 and KISS TCP on 127.0.0.1:8001. Receive starts immediately. PTT and audio output remain off until TX is armed in the console. Optionally add --first-contact for a PTT-free local converter-loopback check before serving; it verifies the audio path only and cannot transmit RF. Add --ptt-port /dev/ttyUSB0 only when your interface needs serial PTT; repeat --peer for each expected station. Set --ui-port 0 for a headless KISS-only service.
Add station creates a session-only receiver watch entry: it neither opens a QSO nor arms TX, and it is used on the next receive window (not a capture already in progress). Open RF details and receiver diagnostics for receiver health, counts, spectrum/waterfall, and the front-end IQ cloud. The shared channel is half duplex: each turn receives, then sends at most one queued logical message; further messages wait for the next receive window.
Use the HF audio profile for rig sound cards. Drive stays capped so SSB ALC does not splatter. No on-air HF QSO is claimed. Multi-user operation under fading is proven only in simulation with the congested stack.
Safety
- TX is fail-closed until explicitly armed.
- bladeRF on-air requires the pinned FPGA bitstream and modest
txvga2(≤10 in this lab programme). - Never direct-connect TX to RX without attenuation.
- HF multi-user under ionospheric fading is a simulation result only — not an on-air claim yet.
- Packet airtime sets the QSO floor (~2.6 s UHF, ~40 s HF), even when the demod keeps up with the RF stream.