Instalare Sistem pentru RoLink
Dragi colegi,
Aici o să scriu pașii necesari pentru o instalare de svxlink pe Orange PI Zero denumit în continuare „opi”.
Pentru ca articolul este destul de stufos, pun aici un fel de cuprins prin care sa accesati rapid sectiunile.
Configurarea modulului SA818/DRA818.
Calibrarea receptorului
Configurare network pentru autoconectare la ethernet/wifi/usb/modem
Administrare online
Reflectorul și un exemplu de configurare
Ca și echipament hardware este necesar un micro-computer OrangePi Zero
Pe partea hardware, poate fi la latitudinea fiecăruia ce alege pentru inter-gate-area cu radioul, însă două proiecte interesante ni le prezintă colegul nostru, Miron – YO3ITI:
http://www.yo3iti.ro/index.php?title=RoLink_OPi_Simplificat
http://www.yo3iti.ro/index.php?title=Nod_RoLink_OPi_complex
Detaliile constructive și nu numai, multe alte lucruri interesante, veti gasi urmărind link-urile de mai sus.
Pentru cei ce nu se pot descurca cu ce se prezinta mai jos, am pregatit o imagine gata configurata cu sistemul instalat si care se conecteaza la un reflector de test, pe care se pot face reglajele de modulatie.
Imaginea este disponibila aici: https://bastus.go.ro/imagini/portabil.img
Se acceseaza prin ssh pe portul 22, cu userul root si parola: qweasd..!
Se recomanda schimbarea parolei. Sistemul este configurat pentru conectare la retea prin cablu ethernet si prin wifi la o retea folosita de obicei de catre hotspoturile facute prin telefoanele mobile Android. Reteaua este cea cu ssid=”AndroidAP” prezenta in exemplul de mai jos. O alta retea se poate adauga urmarind exemplul. ATENTIE! Imaginea este default Read-Only, pentru a fi protejat sd-cardul. Inainte de a se face orice modificare, se va da comanda “rw” (fara ghilimele) . Totodata, imaginea fiind comprimata, se va da apoi comanda:
/usr/lib/armbian/armbian-resize-filesystem start
Se asteapta aprox un minut dupa care se da reboot. Pentru conectarea la retea, se va completa ce este necesar in fisierul /opt/rolink/conf/svxlink.conf, adica credentialele primite la inregistrarea nodului.
Cei ce vor sa puna mana sa isi construiasca sistemul singuri, pot citi in continuare.
Se download-ează armbian de aici.
Imaginea se dezarhivează, rezultă un fișier cu extensia „img”.
Se download-ează de aici Balena Etcher, cu care se scrie fișierul img pe sd-card.
Recomand sd-card minim 4G, maxim 8G. Nu știu dacă se mai gaseste de 4G, dar de 8G este destul de răspandit și ieftin. De asemenea, să luați clasa „10”, deoarece au accesul mai rapid. Scrie pe card „Class 10”. Și să fie produs de o firmă cunoscută. Nu vă zgârciți.
După ce se scrie imaginea, se bagă în opi, se alimentează, se conectează la internet/rețeaua locală prin placa de rețea integrată și în câteva momente ar trebui să vă conectați prin ssh la sistem, pe adresa locală. Adresa o aflați din router, sistemul e configurat să își ia adresa prin dhcp.
Inițial vă conectați ca root, cu parola 1234; sistemul vă va cere să schimbați parola inițială într-una mai complexă și de asemenea, să creați un user cu care vă veți conecta de acum înainte.
Pentru următoarea conectare și rularea comenzilor uzuale, monitorizare etc, veți folosi user-ul respectiv, iar comenzile care necesită drepturi de root vor fi precedate de comanda sudo. Comanda sudo (substitute user do) permite rularea unor comenzi cu privilegiile de acces ale unui alt utilizator, de obicei root.
În materialul de față, pentru simplitatea editării, eu voi rula comenzile direct ca și root. Acest lucru se face prin comanda sudo su – după introducerea parolei, user-ul se va transforma în root, acest lucru se vede și în caracterul din stânga prompterului, care s-a transformat din $ în #. În continuare să dau următoarele comenzi:
apt update apt upgrade
apt install g++ cmake make libsigc++-2.0-dev libgsm1-dev libpopt-dev tcl-dev libgcrypt20-dev libspeex-dev libasound2-dev libopus-dev libogg-dev libjsoncpp-dev libcurl4-openssl-dev alsa-utils vorbis-tools curl git-core ca-certificates
Instalarea de față, după o idee a lui Adrian – YO8RXT, nu va fi una standard, ci se va face în directorul rolink din /opt; aceasta va simplifica configurarea și monitorizarea programului svxlink.
cd /opt
git clone https://github.com/sm0svx/svxlink
cd svxlink cd src mkdir build cd build
cmake -DUSE_QT=OFF -DCMAKE_INSTALL_PREFIX=/opt/rolink \ -DSYSCONF_INSTALL_DIR=/opt/rolink/etc \ -DSVX_SYSCONF_INSTALL_DIR=/opt/rolink/conf \ -DSHARE_INSTALL_PREFIX=/opt/rolink/share \ -DSVX_SHARE_INSTALL_DIR=/opt/rolink/share \ -DSVX_MODULE_INSTALL_DIR=/opt/rolink/lib/modules \ -DLOCAL_STATE_DIR=/opt/rolink/var \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_FLAGS="-march=armv7 -mtune=generic-armv7-a" \ -DCMAKE_CXX_FLAGS="-march=armv7 -mtune=generic-armv7-a" ..
groupadd svxlink useradd -r -g daemon svxlink make; make install
Diferind de instalarea standard, librăriile necesare rulării programului nu se mai găsesc unde trebuie așa că va trebui să îi spunem sistemului unde se află acestea:
touch /etc/ld.so.conf.d/svxlink.libs.conf
echo "/opt/rolink/lib" > /etc/ld.so.conf.d/svxlink.libs.conf
ldconfig -v
ultima comandă ne arată că sistemul le găseste unde trebuie:
/opt/rolink/lib:
libasynccpp.so.1.6 -> libasynccpp.so.1.6.0.99.4
libasyncaudio.so.1.6 -> libasyncaudio.so.1.6.0.99.4
libasynccore.so.1.6 -> libasynccore.so.1.6.0.99.4
libecholib.so.1.3 -> libecholib.so.1.3.3
Dacă nu au apărut erori pe parcurs (și nu trebuie… dacă s-au respectat instrucțiunile) svxlink este instalat în acest moment.
Acum ne ocupăm de placa de sunet. Ultimul kernel vine cu placa de sunet cu microfinul dezactivat, așa că trebuie să îl activăm:
alsamixer store
se apasă o data TAB ca sa ne pozitionam pe Capture, selectam MIC1 (cu săgețile stânga-dreapta) și, când e selectat, se apasă tasta SPACE.
Trebuie să arate ca în poză:
Urmează să edităm fișierele de configurare. Pentru asta trebuie să ne aflăm în directorul /opt/rolink/conf și să edităm fișierul svxlink.conf.
Acesta ar trebui să arate ca aici
[GLOBAL] MODULE_PATH=/opt/rolink/lib/modules LOGICS=SimplexLogic,ReflectorLogic CFG_DIR=/opt/rolink/conf/svxlink.d TIMESTAMP_FORMAT="%Y-%m-%d %H:%M:%S" CARD_SAMPLE_RATE=48000 LINKS=ReflectorUpLink [ReflectorUpLink] CONNECT_LOGICS=SimplexLogic:99:R,ReflectorLogic DEFAULT_ACTIVE=1 TIMEOUT=10 [SimplexLogic] TYPE=Simplex RX=LocalVoter TX=Tx1 CALLSIGN=yo0xxx SHORT_IDENT_INTERVAL=10 LONG_IDENT_INTERVAL=30 EVENT_HANDLER=/opt/rolink/share/events.tcl DEFAULT_LANG=en_US RGR_SOUND_DELAY=0 RGR_SOUND_ALWAYS=1 FX_GAIN_NORMAL=-5 FX_GAIN_LOW=-12 [ReflectorLogic] TYPE=Reflector HOST=bastus.go.ro #HOST=svx.439100.ro PORT=5300 CALLSIGN="nod_nou" AUTH_KEY="qawsed" JITTER_BUFFER_DELAY=250 DEFAULT_TG=226 MONITOR_TGS=226 TG_SELECT_TIMEOUT=99999 ANNOUNCE_REMOTE_MIN_INTERVAL=10 EVENT_HANDLER=/opt/rolink/share/events.tcl [LocalVoter] TYPE=Voter RECEIVERS=Rx1 VOTING_DELAY=100 BUFFER_LENGTH=100 COMMAND_PTY=/dev/shm/voter_ctrl [Rx1] TYPE=Local AUDIO_DEV=alsa:plughw:0 AUDIO_CHANNEL=0 SQL_DET=GPIO SQL_START_DELAY=0 SQL_DELAY=250 SQL_HANGTIME=0 SQL_TIMEOUT=180 GPIO_SQL_PIN=gpio10 SIGLEV_SLOPE=1 SIGLEV_OFFSET=0 SIGLEV_OPEN_THRESH=30 SIGLEV_CLOSE_THRESH=10 DEEMPHASIS=0 PEAK_METER=0 DTMF_DEC_TYPE=INTERNAL DTMF_MUTING=1 DTMF_HANGTIME=40 DTMF_SERIAL=/dev/ttyS0 ##compression - recomandat activ RxComp=1 RxCompThreshold=-30 RxCompRatio=0.5 RxCompAttack=50 RxCompDecay=5000 [Tx1] TYPE=Local TX_ID=T AUDIO_DEV=alsa:plughw:0 AUDIO_CHANNEL=0 PTT_TYPE=GPIO PTT_PIN=gpio7 TIMEOUT=300 TX_DELAY=100 PREEMPHASIS=0 DTMF_TONE_LENGTH=100 DTMF_TONE_SPACING=50 DTMF_DIGIT_PWR=-15 ##compression - recomandat activ pe portabile TxLimit=1 TxComp=1 TxCompThreshold=-90 TxCompRatio=0.5 TxCompAttack=10 TxCompDecay=5000
Svxlink trebuie pornit automat la pornirea sistemului, așa ca în directorul rolink creăm următorul fișier, numit rolink-cron.d, în care vom pune comenzile de mai jos:
* * * * * root /opt/rolink/scripts/checkalive.sh * * * * * root /opt/rolink/scripts/network.sh * * * * * root /opt/rolink/scripts/reflector-test.sh 17 3 * * * root /opt/rolink/scripts/rolink-re-start.sh
Îi vom face link către directorul demonului cron:
ln -v -s /opt/rolink/rolink-cron.d /etc/cron.d/rolink
Scripturile la care se face referire mai sus, va trebui să le creăm, ca tot ansamblul să funcționeze. Așadar:
md scripts cd scripts nano checkalive.sh
și aici punem:
#!/bin/bash if [ "$(pgrep -c svxlink)" != "1" ]; then echo "re-start svxlink" /opt/rolink/scripts/rolink-start.sh fi exit 0
Salvăm, ieșim și creăm urmatorul fișier: rolink-start.sh
#!/bin/sh . /opt/rolink/scripts/gpio-up.sh export LD_LIBRARY_PATH="/opt/rolink/lib" [ "$(pidof svxlink)" != "" ] && killall -v svxlink /opt/rolink/bin/svxlink --daemon --config=/opt/rolink/conf/svxlink.conf --logfile=/tmp/svxlink.log --runasuser=root --pidfile=/var/run/svxlink.pid echo heartbeat > /sys/class/leds/orangepi:red:status/trigger #
gpio-up.sh:
#! /bin/sh useradd -M -N -G daemon,audio svxlink GPIO_USER=root GPIO_GROUP=daemon GPIO_MODE=664 GPIO_PATH=/sys/class/gpio ##function gpio IN pin gpioin() { N=$1 [ ! -d ${GPIO_PATH}/gpio${N} ] && [ -n "$N" ] && echo ${N} > ${GPIO_PATH}/export echo "in" > ${GPIO_PATH}/gpio${N}/direction [ -n "$GPIO_USER" ] && chown "$GPIO_USER" ${GPIO_PATH}/gpio${N}/value [ -n "$GPIO_GROUP" ] && chgrp "$GPIO_GROUP" ${GPIO_PATH}/gpio${N}/value [ -n "$GPIO_MODE" ] && chmod "$GPIO_MODE" ${GPIO_PATH}/gpio${N}/value } ##function gpio OUT pin state gpioout() { N=$1 V=$2 [ ! -d ${GPIO_PATH}/gpio${N} ] && [ -n "$N" ] && echo ${N} > ${GPIO_PATH}/export echo "out" > ${GPIO_PATH}/gpio${N}/direction [ -n "$V" ] && echo ${V} > ${GPIO_PATH}/gpio${N}/value [ -n "$GPIO_USER" ] && chown "$GPIO_USER" ${GPIO_PATH}/gpio${N}/value [ -n "$GPIO_GROUP" ] && chgrp "$GPIO_GROUP" ${GPIO_PATH}/gpio${N}/value [ -n "$GPIO_MODE" ] && chmod "$GPIO_MODE" ${GPIO_PATH}/gpio${N}/value } echo '### SQL - set PA20|gpio20/gpio26 in' gpioin 10 echo '### PTT - set PA10|gpio10/gpio19 out high' gpioout 7 0 gpioout 6 0 ls -1d ${GPIO_PATH}/gpio* cat /sys/kernel/debug/gpio #
network.sh:
#!/bin/bash # RoLink PAT='-p 526F4C696E6B' echo 0 > /sys/class/leds/orangepi:red:status/brightness ping reflector/vpn ping -q -A -c 3 -W 10 $PAT reflector.rolink-net.ro > /dev/null 2>&1 if [ $? -ne "0" ]; then echo heartbeat > /sys/class/leds/orangepi:red:status/trigger # ping internet - google-public-dns-b.google.com [8.8.4.4] ping -q -A -c 3 -W 10 $PAT google-public-dns-b.google.com > /dev/null 2>&1 if [ $? -ne "0" ]; then systemctl daemon-reload sleep 3 systemctl restart networking fi fi echo 255 > /sys/class/leds/orangepi:red:status/brightness exit 0 #
Orangepi zero are două led-uri, pe cel verde îl lăsăm în pace, când este aprins ne indică faptul că hardware sistemul este ok, cel roșu e folosit pentru statusul sistemului svxlink. Astfel, când programul este funcțional, led-ul va lumina intermitent, iar când este conectat în Rețeaua RoLink led-ul va fi aprins permanent.
reflector-test.sh
#!/bin/bash LOG=/tmp/svxlink.log INF=/tmp/reflector.test REFOF=$( tail -50 $LOG | grep -ia 'ReflectorLogic: Disconnected from' | tail -1 ) REFON=$( tail -50 $LOG | grep -ia 'ReflectorLogic: Using audio codec' | tail -1 ) REFDEC=$( echo -e "${REFOF}\n${REFON}" | sort -n | tail -1 | grep -ia 'ReflectorLogic: Disconnected from' ) if [ "$REFDEC" != "" ]; then echo 'FAIL' > ${INF} exit 1 else rm -f ${INF} fi exit 0
Va trebui să dăm drept de execuție pe fișierele create:
chmod 755 *.sh
și să facem un simlink către rolink-restart.sh
ln -s rolink-start.sh rolink-re-start.sh
În momentul de față sistemul este pregătit de conectare. Cu configurația actuală, se va conecta la un reflector de test configurat în mod papagal, care vă va ajuta la testele de modulație. Pentru conectarea la rețea, în svxlink.conf vor trebui modificate aceste linii (trebuie să arate ca mai jos):
#HOST=bastus.go.ro HOST=svx.439100.ro
iar aici:
CALLSIGN="nod_nou" AUTH_KEY="qawsed"
va trebui introdus user-ul și parola pe care ar trebui sa le primiți în prealabil de la administratorii Retelei RoLink.
Mai jos urmează configurarea modulului SA818/DRA818.
Modulul comunică pe interfața serială cu sistemul. Interfața este folosită doar pentru programarea acestuia, nu are alt rol în comunicație. De obicei armbian vine cu interfețele de comunicație serială neconfigurate, așa că va trebui să verificăm în /boot/armbianEnv.txt existența următoarei linii, care va trebui să arate ca mai jos (dacă nu, se editează):
overlays=usbhost1 usbhost2 analog-codec uart1 uart2
Va trebui să adaugăm un script care ne va ajuta în programarea modulului. Deci:
nano /opt/rolink/scripts/orangeserial.py
import time
import serial
ser = serial.Serial(
port='/dev/ttyS1',
baudrate=9600
)
ser.isOpen()
print 'Enter your commands below.\r\nInsert "exit" to leave the application.'
input=1
while 1 :
# get keyboard input
input = raw_input(">> ")
# Python 3 users
# input = input(">> ")
if input == 'exit':
ser.close()
exit()
else:
# send the character to the device
# (note that I happend a \r\n carriage return and line feed to the characters - this is requested by my device)
ser.write(input + '\r\n')
out = ''
# let's wait one second before reading output (let's give device time to answer)
time.sleep(1)
while ser.inWaiting() > 0:
out += ser.read(1)
if out != '': print ">>" + out
Scriptul de programare este făcut în Python. Vor trebui date urmatoarele comenzi, că sa meargă:
apt install python-pip
pip install pyserial
Pornim scriptul cu:
python orangeserial.py
după care dăm următoarele comenzi:
AT+DMOCONNECT
Dacă totul este în regulă, modulul va raspunde cu:
+DMOCONNECT:0
Deci, programăm frecvența:
AT+DMOSETGROUP=1,432.5500,432.5500,0013,4,0013
Ultimele 3 grupe reprezintă tonul ctcss la emisie și recepție (13->103.5) și nivelul de squelch (4).
și nivelul audio la ieșire din modul:
AT+DMOSETVOLUME=2
Ieșim scriind: exit
Configurare network pentru autoconectare la ethernet/wifi/usb/modem
By default armbian vine cu network-manager instalat. Îl dezinstalăm:
apt remove --purge network-manager
Mergem în /etc/network/interfaces și punem aceasta:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
wireless-mode Managed
wireless-power off
Salvăm, apoi:
nano /etc/wpa_supplicant/wpa_supplicant.conf
în care punem de exemplu:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
#ap_scan=0
update_config=1
network={
ssid="AndroidAP"
psk="123456789"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
group=CCMP
auth_alg=OPEN
}
network={
ssid="acme"
psk="123456789"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
group=CCMP
auth_alg=OPEN
}
Aici avem configurate două rețele, prima e un hotspot din telefon și a doua este rețeaua de acasă, de exemplu.
Administrare online
Daca ați observat în svxlink.conf o chestie numită “[LocalVoter]” , aici este cazul să explicăm la ce se folosește. Din documentație, aflăm că svxlink știe să lucreze cu receptoare multiple, nu este cazul aici, însă pentru gestionarea acestora, s-au introdus niște comenzi: Rx(x)Enable/Disable. În configurația cu un singur receptor, acestea nu funcționează, de aceea am recurs la acest artificiu, și anume receptorul introdus prin voter. Asta face ca într-o situație reală și anume paraziși pe recepție, cu o comandă, să putem opri recepția nodului fără a interveni fizic asupra acestuia sau a streamului din rețea, și să-l repornim când este cazul sau după un anumit interval de timp.
Deci: cd /opt/rolink/scripts
și mai adaugăm un fișier de stare:
touch t_rx
și trei scripturi:
rx_on.sh
#!/bin/bash
echo "ENABLE Rx1" > /dev/shm/voter_ctrl
echo -n "1" > /opt/rolink/scripts/t_rx
rx_off.sh
#!/bin/bash
echo "DISABLE Rx1" > /dev/shm/voter_ctrl
echo -n "0" > /opt/rolink/scripts/t_rx
rx.sh
#!/bin/bash
exec=$(</opt/rolink/scripts/t_rx)
if [ "$exec" == "1" ]; then
echo "ENABLE Rx1" > /dev/shm/voter_ctrl
else
echo "DISABLE Rx1" > /dev/shm/voter_ctrl
fi
exit 0
Acesta din urmă se ocupă de verificarea ultimei stări a receptorului, în caz de restart de exemplu. Pentru asta va trebui să-l adaugăm în fișierul rolink-cron.d din directorul rolink.
* * * * * root /opt/rolink/scripts/rx.sh
Atenție să fie executabile scripturile, deci:
chmod 755 rx*.sh
Următorul lucru este să instalăm soluția client/server oferită de Răzvan – YO6NAM de aici:
https://github.com/yo6nam/phpKontrol
Dacă nu suntem dispuși să instalăm server, instalăm doar clientul și apelăm la bunăvoința lui Răzvan pentru o pagină de administrare de pe binecunoscutul server XPANDER
Configul ‘launcher.conf’ pentru scripturile de mai sus arată asa:
logfile = '/var/log/phpKontrol'
mqtt_broker = 'ex_host.ro' # default: 'localhost'
mqtt_port = 1883 # default: 1883
mqtt_clientid = 'client_789' # must be unique!
mqtt_username = 'gigi'
mqtt_password = 'bestialu'
mqtt_tls = None # default: No TLS
topiclist = {
"devices/cmd" : {
'client_789_on' : [ 'bash', '/opt/rolink/scripts/rx_on.sh' ],
'client_789_off' : [ 'bash', '/opt/rolink/scripts/rx_off.sh' ],
},
}
Parametrii mqtt îi completăm cu ce primim de la Răzvan.
Interfața de administrare de pe mobil arată asa:
Ce este reflectorul și un exemplu de configurare
Reflectorul, parte a pachetului svxlink de ceva vreme, este un mic program care asigură interconectarea nodurilor. Configurarea sa este simplă și intuitivă și nu are nevoie de multe resurse; poate rula pe același sistem ca și clientul svxlink.
Exemplu de svxreflector.conf:
###################################################################
#
# Configuration file for the SvxReflector SvxLink conference node
#
###################################################################
[GLOBAL]
#CFG_DIR=svxreflector.d
TIMESTAMP_FORMAT="%c"
LISTEN_PORT=5300
#SQL_TIMEOUT=600
#SQL_TIMEOUT_BLOCKTIME=60
#CODECS=OPUS
TG_FOR_V1_CLIENTS=9
#RANDOM_QSY_RANGE=12399:100
HTTP_SRV_PORT=8090
[USERS]
YO7GQZ-1=MyNodes
YO7GQZ-2=MyNodes
PITESTI=MyNodes
CLIENT_NOU=Teste
#SM3XYZ=SM3XYZ
[PASSWORDS]
MyNodes="qweasdf"
Teste="123456"
Acesta este un exemplu de reflector ce funcționează la Pitești. Nodurile sunt cele cu denumirea din secțiunea [ReflectorLogic] a clientului.
Trebuie avut în vedere ca portul 5300 să fie accesibil extern pentru clienții din exterior. Clientul local se poate conecta la localhost.
Scripturile de pornire și verificare:
reflector-start.sh
#!/bin/sh
[ "$(pidof svxreflector)" != "" ] && killall -v svxreflector
/opt/rolink/bin/svxreflector --daemon --config=/opt/rolink/conf/svxreflector.conf --logfile=/tmp/svxreflector.log --runasuser=root --pidfile=/var/run/svxreflector.pid
#
Și mai adaugăm în scriptul checkalive.sh și verificarea de reflector:
if [ "$(pgrep -c svxreflector)" != "1" ]; then
echo "re-start reflector"
/opt/rolink/scripts/reflector-start.sh
fi
Atenție! Inaintea liniei “exit 0” se adaugă cele de mai sus.
Va urma:
-legarea mai multor noduri la un reflector și un exemplu de mini-rețea
-configurare modem 3G/4G
-qso recorder
-configurare voce, alta decât cea standard
-anunțuri personalizate
-monitor de propagare
-imagine gata configurată
’73
Cătălin – YO7GQZ