Terminale AX25 per RNode TNC

Un client Python leggero per comunicare tramite packet radio AX.25 (sessioni BBS/nodo in modalità connessa, più frame UI/broadcast opzionali come APRS) utilizzando un dispositivo RNode in modalità TNC, attraverso una semplice connessione seriale KISS.

Nessun AGWPE, AXCALL, nessuna scheda audio TNC — solo Python e una porta seriale.

Sono incluse due interfacce:

rnode_ax25_tnc.py  — un semplice prompt dei comandi a riga singola.
rnode_ax25_tnc_ui.py — un terminale a schermo diviso nello stile del classico software per packet radio (Linpac e simili): un riquadro per il traffico in  scorrimento in alto, una barra di stato e la riga di comando in basso.

Entrambe condividono lo stesso motore di protocollo (ax25_core.py) e producono file di log della sessione con timestamp.

Hardware testato

-Heltec WiFi LoRa 32 V3 (ESP32-S3 + Semtech **SX1262**), programmato con firmware RNode, Device mode: TNC, parametri radio (frequenza, larghezza di banda, spreading factor, coding rate, potenza TX) già configurati sul dispositivo.

Dovrebbe funzionare con qualsiasi scheda compatibile con RNode (Heltec, LilyGO T-Beam, RAK, ecc.) che esegue il firmware RNode in modalità TNC, poiché il software si affida solo allo strato standard KISS/AX.25.

Importante: se l’RNode è già in modalità TNC con parametri radio validi, questo strumento non ha bisogno di (e per impostazione predefinita non lo fa) inviare comandi di configurazione radio. Passa `–freq/–bw/–sf/–cr/–power` solo se hai specificamente bisogno di (ri)configurare la radio da questo strumento — RNode riutilizza per la configurazione radio gli stessi byte di comando bassi (0x01–0x06) che i TNC KISS classici usano per TXDELAY/Persistence/SlotTime/ecc. Inviare il valore errato sul byte sbagliato può impostare un parametro fuori intervallo (ad es. un coding rate non valido) e attivare il “radio lock” del firmware, bloccando silenziosamente la trasmissione fino al reset del dispositivo. In caso di dubbio, lascia queste opzioni non impostate.

Caratteristiche

– Sessione completa AX.25 in modalità connessa (`SABM` → `UA`, `I`-frame numerati, conferme `RR`, `DISC` → `UA`) — vere sessioni BBS/nodo in modalità conversativa (“converse mode”), non solo frame UI singoli.
– Frame UI autonomi opzionali (ad es. per traffico in stile APRS).
– Comandi in classico stile TNC: `C NOMEDICHIAMATA` per connettersi, `D` per disconnettersi — la stessa sintassi usata dai terminali BPQ32/AGWPE.
– Decodifica CP437 per banner/menu di nodi che utilizzano ASCII art con caratteri di grafica a blocchi.
– Cronologia dei comandi (freccia su/giù) in entrambe le interfacce.
– File di log con timestamp per ogni sessione.
– Nessuna trasmissione automatica/accidentale: quando non si è connessi, il testo semplice non viene inviato da nessuna parte a meno che non ci si connetta esplicitamente (`C NOMEDICHIAMATA`) o non si utilizzi il comando esplicito di invio UI (`U <testo>`).

Requisiti

– Python 3.8+
– Un dispositivo RNode, in modalità TNC, connesso tramite seriale USB.

Installazione

git clone https://github.com/iz3mez/RNode-AX25-Packet-Terminal.git
cd RNode-AX25-Packet-Terminal
pip install -r requirements.txt

Accedi al Repository in GitHub

Utilizzo

Trova la tua porta seriale

Windows: controlla in Gestione dispositivi (ad es. COM2)
Linux: di solito /dev/ttyUSB0 o /dev/ttyACM0
macOS: di solito /dev/tty.usbserial-XXXX

CLI a riga singola:

python3 rnode_ax25_tnc.py COM2 –mycall CALL-1

UI a schermo diviso (stile Linpac):

python3 rnode_ax25_tnc_ui.py COM2 –mycall CALL-1

Digita “?” per la lista dei comandi

File di log

Ogni esecuzione crea un file chiamato rnode_ax25_AAAAMMGG_HHMMSS.log nella stessa directory degli script, contenente una copia timestampata di tutto ciò che viene mostrato sullo schermo (messaggi di stato e dati ricevuti/inviati) — utile per rivedere le sessioni o gli spot dei DX cluster in un secondo momento.

Limitazioni

Una sola sessione AX.25 alla volta (nessuna connessione multipla).

Modalità connessa semplificata: nessuna ritrasmissione automatica per timeout, nessun SREJ, e le richieste di connessione in entrata (qualcun altro che si connette a te) vengono sempre rifiutate con DM — questo client origina solo connessioni.

Non è uno stack AX.25 generico: niente digipeating, niente AXIP, niente risposta automatica.

I commenti sono chiusi.