Files
2026-08-09 12:18:40 +02:00

6.0 KiB

SIP-DMR Radio Gateway

Un gateway bidirezionale scritto in Python che permette di collegare centralini VoIP SIP (come FreePBX) a reti radio DMR (tramite protocollo OpenBridge).

Il sistema gestisce l'handshake SIP, la transcodifica audio in tempo reale tra PCM (G.711a) e AMBE, il controllo PTT tramite toni DTMF e il cambio dinamico del Talkgroup direttamente dal tastierino del telefono, simulando il comportamento di una vera radio.

🚀 Caratteristiche Principali

  • Integrazione Trasparente: Dialoga nativamente con FreePBX gestendo i ping OPTIONS (Trunk PJSIP).
  • Cambio Canale al Volo: Digita il numero del Talkgroup sul telefono e il gateway ti sposterà di stanza senza far cadere la chiamata.
  • Sicurezza IP: Rifiuta nativamente le connessioni SIP da IP non autorizzati.
  • Aggiornamento Display: Usa il protocollo re-INVITE per mostrare Caller ID (DMR ID) e Talkgroup attivi sui telefoni hardware compatibili.
  • Transcoding 100% Software: Nessun hardware dedicato richiesto (es. DVStick). Il sistema usa l'emulatore nativo md380-emu elaborando l'audio crudo (RAW) direttamente tramite CPU.
  • Multi-Tenancy Dinamica: Gestisce chiamate simultanee multiple. Il motore alloca e dealloca dinamicamente le porte UDP instradando gli stream audio in tempo reale sui vocoder liberi.
  • Audio Bidirezionale G.711 / AMBE: Converte al volo i pacchetti SIP A-Law in PCM lineare 16-bit (tramite modulo audioop) per la rete DMR, e viceversa.

🛠️ 1. Prerequisiti di Sistema (Debian / Ubuntu)

Prima di installare il gateway, assicurati di avere gli strumenti di compilazione e l'ambiente Python installati sul server:

sudo apt update && sudo apt upgrade -y
sudo apt install -y git build-essential python3 python3-venv python3-pip

(Nota: su architetture a 64-bit potrebbe essere necessario installare libc6-dev-i386 per compilare correttamente l'emulatore AMBE).


📻 2. Installazione Motore Audio Scalabile (md380-emu)

Il cuore della conversione audio è l'emulatore open-source md380-emu. Va scaricato, compilato e configurato come "template" Systemd per supportare un pool di porte.

# 1. Crea la cartella di destinazione
sudo mkdir -p /opt/md380-emu

# 2. Estrai i binari inclusi nel repository
sudo tar -xzvf bin/md380-emu-bin.tar.gz -C /opt/md380-emu/

# 3. Assicurati che abbiano i permessi di esecuzione
sudo chmod +x /opt/md380-emu/md380-emu /opt/md380-emu/qemu-arm-static

Creazione del demone Systemd Template per le istanze multiple:

Crea il file /etc/systemd/system/md380-emu@.service:

[Unit]
Description=MD380 Emulator Vocoder (Port %i)
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/md380-emu
# Il %i verrà sostituito automaticamente con il numero di porta
ExecStart=/opt/md380-emu/emulator -p %i
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Attivazione delle istanze (es. per 10 canali simultanei):

Ricarica i demoni e avvia il loop di porte (es. dalla 2470 alla 2479):

sudo systemctl daemon-reload
for port in {2470..2479}; do
    sudo systemctl enable --now md380-emu@$port.service
done

(Per aumentare la capacità futura, ti basterà avviare nuovi servizi systemctl ed espandere il range di porte generate in vocoder_engine.py).


💻 3. Installazione del Gateway Python

Clona questo repository e configura l'ambiente virtuale:

cd /opt
git clone git://git.arifvg.it/iv3jdv/sip-dmr-gateway.git
cd sip-dmr-gateway

# Crea e attiva il Virtual Environment
python3 -m venv venv
source venv/bin/activate

# Installa le dipendenze
pip install -r requirements.txt

Copia i file di esempio per creare la tua configurazione reale:

cp config.example.json config.json
cp utenti.example.json utenti.json

Modifica config.json: Inserisci le credenziali del tuo server HBlink/OpenBridge, le porte e, soprattutto, l'IP autorizzato del tuo server FreePBX per la sicurezza.


⚙️ 4. Configurazione FreePBX

Affinché il centralino dialoghi correttamente con il Gateway, crea un Trunk PJSIP con queste regole:

  • Autenticazione: Nessuna (Identity via IP Match). L'IP match deve puntare all'IP del server dove gira questo script Python.
  • Qualify Frequency: Lascialo attivo (es. 60 secondi). Il gateway risponderà regolarmente con 200 OK.
  • Codecs: Disabilita tutto e lascia spuntato SOLO alaw (G.711a).
  • Advanced -> DTMF Mode: Imposta su RFC4733.
  • Advanced -> Trust RPID/PAI: Imposta su Yes.
  • Advanced -> Send RPID/PAI: Imposta su Both.

Crea poi una Rotta in Uscita (Outbound Route) che intercetti un prefisso a tua scelta (es. 99) e che lo strippi (lo elimini), inviando al Trunk solo il numero del Talkgroup.


📞 5. Utilizzo e Comandi DTMF (Tastierino)

Chiama la rotta configurata su FreePBX seguita dal Talkgroup desiderato (es. componi 99 222 per entrare sul TG 222). Una volta in linea, usa il tastierino del telefono per pilotare la radio:

  • Tasto * (Asterisco): Premi per abilitare il PTT e iniziare a trasmettere.
  • Tasto # (Cancelletto): Premi per disabilitare il PTT e tornare in ascolto.
  • Tasti 0-9 (Cambio Canale): Digita il numero di un nuovo Talkgroup (es. 9, 1) e rilascia i tasti. Dopo circa 2,5 secondi il sistema ti sposterà automaticamente sul nuovo TG (verrai avvisato da un aggiornamento sul display del telefono, se supportato).

🔄 6. Esecuzione come Servizio (Produzione)

Per far avviare il Gateway automaticamente al boot, crea il file /etc/systemd/system/sipdmr.service:

[Unit]
Description=Gateway SIP-DMR Core
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/sip-dmr-gateway
ExecStart=/opt/sip-dmr-gateway/venv/bin/python3 /opt/sip-dmr-gateway/core.py
Restart=always
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=sipdmr

[Install]
WantedBy=multi-user.target

Abilita e avvia il gateway:

sudo systemctl enable sipdmr --now

Per visualizzare i log in tempo reale e monitorare il traffico radio:

journalctl -u sipdmr -f