www.439100.ro

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

www.439100.ro
Placa radio nod simplificat

http://www.yo3iti.ro/index.php?title=Nod_RoLink_OPi_complex

www.439100.ro
Placa radio nod complex

Detaliile constructive și nu numai, multe alte lucruri interesante, veti gasi urmărind link-urile de mai sus.

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++-1.2-dev libsigc++-2.0-dev libgsm1-dev libpopt-dev tcl-dev libgcrypt20-dev libspeex-dev libasound2-dev libopus-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=reflector.rolink-net.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=reflector.rolink-net.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 retțaua 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

4 thoughts on “Instalare Sistem pentru RoLink

  1. Interesant.
    In linia urmatoare ceva nu functioneaza.

    apt install g++ cmake make libsigc++-2.0-dev libgsm1-dev libpopt-dev tcl-dev libgcrypt20-dev libspeex-dev libasound2-dev libopus-dev libjsoncpp-dev libcurl4-openssl-dev alsa-utils vorbis-tools curlapt-get install git-core ca-certificates libsigc++-2.0-dev g++ make libsigc++-1.2-dev libgsm1-dev libpopt-dev

    Primesc urmatorul mesaj:
    Note, selecting ‘git’ instead of ‘git-core’
    E: Unable to locate package curlapt-get
    E: Unable to locate package install
    E: Unable to locate package libsigc++-1.2-dev
    E: Couldn’t find any package by glob ‘libsigc++-1.2-dev’
    E: Couldn’t find any package by regex ‘libsigc++-1.2-dev

    ce nu este in regula??

Leave a Comment

Your email address will not be published. Required fields are marked *