Istovremeni speedtest na više LTE modema

Tijekom karantene predloženo mi je da sudjelujem u razvoju uređaja za mjerenje brzine LTE modema za nekoliko mobilnih operatera.

Istovremeni speedtest na više LTE modema

Naručitelj je želio procijeniti brzinu svih mogućih telekomunikacijskih operatera na različitim geografskim lokacijama, kako bi mogao razumjeti koji je mobilni operater najoptimiziraniji za postavljanje opreme koja koristi LTE vezu, primjerice za video prijenose. Pritom je zadatak trebao biti riješen što jednostavnije i jeftinije, bez skupog uređaja.

Odmah ću reći da zadatak nije najlakši i znanstveno zahtjevan, ispričat ću koje su mi se teškoće pojavile i kako sam ih rješavao. Idemo.

Napomena

Mjerenje brzine LTE veze je vrlo složeno: potrebno je pravilno odabrati opremu i metodu mjerenja, kao i dobro razumjeti topologiju i rad mobilne mreže. Osim toga, brzinu može utjecati nekoliko faktora: broj korisnika na baznoj stanici, vremenske prilike, čak i brzina može drastično varirati između baznih stanica zbog topologije mreže. Ukratko, ova je zadaća puna nepoznanica, a ispravno je može riješiti samo telekomunikacijski operater.

Isprva je naručitelj htio jednostavno slati kurira s telefonima operatera, provoditi mjerenja izravno na telefonu, a zatim zapisivati rezultate mjerenja brzine u bilježnicu. Moje rješenje za mjerenje brzine LTE mreža, iako nije savršeno, rješava postavljeni zadatak.

Zbog nedostatka vremena, donosio sam odluke ne u korist udobnosti ili praktičnosti, nego u korist brzine razvoja. Na primjer, za daljinski pristup podišao sam obratni SSH, umjesto praktičnijeg VPN-a, radi uštede vremena na postavljanju servera i svakog pojedinačnog klijenta.

Tehnička specifikacija

Kao što je navedeno u članku Bez TŠ: zašto klijent ne želi to: Ne radite bez TŠ! Nikada, nigdje!

Tehnička specifikacija bila je dovoljno jednostavna, malo ću je proširiti radi razumijevanja krajnjeg korisnika. Izbor tehničkih rješenja i opreme bio je diktiran od strane naručitelja. Dakle, sama TŠ, nakon svih odobrenja:

Na bazi jednoplatnog računala vim2 napraviti tester brzine LTE veze putem modema Huawei e3372h — 153 nekoliko telekom operatera (od jednog do n). Također je potrebno dobiti koordinate s GPS prijemnika povezanog putem UART-a. Mjerenja brzine provesti uz pomoć servisa www.speedtest.net i svesti ih u tabelu tipa:

Istovremeni speedtest na više LTE modema

Tabela u csv formatu. Nakon toga slati na e-mail svake 6 sati ovu tabelu. U slučaju grešaka trebao bi svetliti LED, koji je povezan na GPIO.

Tehničku specifikaciju sam opisao na slobodan način, nakon više usaglašavanja. Ali smisao zadatka je već vidljiv. Rok za sve je bio postavljen na nedelju dana. No, u stvarnosti se produžio na tri nedelje. Ovo uzimajući u obzir da sam to radio samo nakon glavnog posla i vikendom.

Ovde želim još jednom skrenuti pažnju da je naručitelj unapred dogovorio korišćenje servisa za merenje brzine i hardverske opreme, što je značajno ograničilo moje mogućnosti. Takođe je bio ograničen budžet, tako da nije bilo dodatnih nabavki. Tako da sam morao igrati po ovim pravilima.

Arhitektura i razvoj

Shematski je jednostavna i očigledna. Stoga ću je ostaviti bez dodatnih komentara.

Istovremeni speedtest na više LTE modema

Ceo projekat sam odlučio realizovati na python-u, uprkos tome što nisam imao iskustva u razvoju na ovom jeziku. Izabrao sam ga jer je bilo puno gotovih primera i rešenja koja su mogla ubrzati razvoj. Stoga molim sve profesionalne programere da ne kritikuju moje prvo iskustvo razvoja na python-u, i uvek sam otvoren za konstruktivnu kritiku radi poboljšanja svojih veština.

Takođe, tokom procesa sam otkrio da python ima dve zastupljene verzije 2 i 3, i na kraju sam se zaustavio na trećoj.

Hardverski čvorovi

Jednoplatni računar vim2

Kao glavnu mašinu dobio sam jednoplatni računar vim2

Istovremeni speedtest na više LTE modema

Odličan, snažan medijski kombinator za pametnu kuću i SMART-TV, ali izuzetno neprikladan za ovu svrhu, ili da tako kažem, slabo prikladan. Na primjer, njegov glavni OS je Android, dok je Linux sekundarnog karaktera, stoga nitko ne jamči kvalitetan rad svih komponenti i upravljačkih programa pod Linuxom. Pretpostavljam da su neki od problema bili povezani s USB upravljačima na ovoj platformi, pa su modemi radili na ovoj ploči drugačije nego što sam očekivao. Također, njegova dokumentacija je vrlo loša i razasuta, zbog čega je svaka operacija zahtijevala dugo kopanje kroz dokumente. Čak je i običan rad s GPIO-om bio prilično mučan. Na primjer, da bih postavio rad sa LED-icom, trebalo mi je nekoliko sati. Ali, da budem objektivan, nije bilo ključno koja je to jednokrilna ploča, glavna stvar je da radi i da postoje USB priključci.

Prvo, trebam instalirati Linux na ovu ploču. Da ne bih lutao po svim dubinama dokumentacije, kao i za one koji će se baviti ovom jednokrilnom pločom, pišem ovo poglavlje.

Postoje dvije opcije za instalaciju Linuxa: na vanjsku SD karticu ili na unutarnju MMC. Uborio sam se s karticom večerima, ali nije mi bilo jasno kako je natjerati da radi, pa sam odlučio instalirati na MMC, iako bi s vanjskom karticom bilo mnogo jednostavnije raditi.

O firmware-u loše je ovdje opisano. Prevodi se s čudnog na hrvatski. Da bih flash-ao ploču, treba mi spojiti fizički UART. Povezao sam ga na sljedeći način.

  • Alat Pin GND: <— Pin17 GPIO-a VIM-a
  • Alat Pin TXD: <— Pin18 GPIO-a VIM-a (Linux_Rx)
  • Alat Pin RXD: <— Pin19 GPIO-a VIM-a (Linux_Tx)
  • Alat Pin VCC: <— Pin20 GPIO-a VIM-a

Istovremeni speedtest na više LTE modema

Nakon toga, preuzeo sam firmware odavde. Konkretna verzija firmware-a VIM1_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.

Da bih učitao ovaj firmware, potrebni su mi odgovarajući alati. Detaljnije o tome je objašnjeno ovdje. Pod Windows-om nisam pokušavao flash-ati, ali trebam reći nekoliko riječi o flashanju pod Linux-om. Prvo ću instalirati alate prema uputama.

git clone https://github.com/khadas/utils
cd /path/to/utils
sudo ./INSTALL

Iii… Ništa ne radi. Potrošio sam nekoliko sati uređujući instalacijske skripte kako bi se sve ispravno instaliralo kod mene. Što sam radio ne sjećam se, ali to je također bio pravi cirkus s konjima. Tako da budite oprezni. Ali bez ovih alata nema smisla dalje mučiti vim2. Bolje se uopće ne zamarati!

Nakon sedam krugova pakla, konfiguracije skripti i instalacije, dobio sam paket funkcionalnih alata. Povezao sam ploču putem USB-a s mojim Linux računalom, a UART je također povezan prema gore navedenoj shemi.
Postavljam svoj omiljeni terminal minicom na brzinu 115200, bez hardverske i softverske kontrole grešaka. I krenimo.

Istovremeni speedtest na više LTE modema

Kada se VIM2 pokrene u UART terminalu, pritisnem neku tipku, na primjer razmaknicu, da zaustavim pokretanje. Nakon što se pojavi redak

kvim2# 

Uzimam komandu:

kvim2# run update

Na domaćinu s kojeg učitavamo, izvršavam:

burn-tool -v aml -b VIM2 -i VIM2_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231.img

Sve, uh. Flashano je, na ploči se nalazi Linux. Login/lozinka khadas:khadas.

Nakon toga, malo osnovne postavke. Za daljnji rad onemogućavam lozinku za sudo (da, nije sigurno, ali je praktično).

sudo visudo

Uređujem redak do oblika i spremam

# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) NOPASSWD: ALL

Nakon toga mijenjam trenutnu lokalizaciju, da bi vreme bilo prema Moskovskom vremenu, inače će biti prema Greenwichu.

sudo timedatectl set-timezone Europe/Moscow

ili

ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime

Ako vam se činilo komplicirano, nemojte koristiti ovu ploču, bolje uzmite Raspberry Pi. Iskreno.

Modem Huawei e3372h — 153

Ovaj modem mi je zadavao mnoge brige, i zapravo je postao najslabija karika cijelog projekta. Uzgred, naziv “modem” za ova uređaja potpuno ne odražava suštinu rada: to je moćna mašina, taj uređaj ima složeni sklop koji se pretvara u CD-ROM za instalaciju drajvera, a zatim prelazi u način rada mrežne kartice.

Arhitektonski, s gledišta Linux korisnika nakon svih postavki, izgleda ovako: nakon povezivanja modema, pojavljuje se mrežni interfejs eth*, koji putem DHCP-a dobija IP adresu 192.168.8.100, a zadani gateway 192.168.8.1.

I najvažnija stvar! Ova verzija modema ne može raditi u modemu režimu upravljanom AT komandama.Sve bi bilo mnogo jednostavnije stvoriti ppp veze za svaki modem i zatim raditi s njima. Ali u mom slučaju „sama” (preciznije drajveri Linux prema pravilima udev), stvara eth interfejs i putem DHCP-a mu dodeljuje IP adresu.

Da se više ne zbunjujemo, predlažem da zaboravimo riječ „modem” i govorimo mrežna kartica i gateway, jer zapravo se radi o povezivanju nove mrežne kartice s gateway-em.
Kada je jedan modem, to ne uzrokuje velike probleme, ali kada ih je više od jednog, a posebno n komada, tada nastaje sljedeća slika mreže.

Istovremeni speedtest na više LTE modema

Dakle, n broj mrežnih kartica s jednom IP adresom, svaka od njih ima istu zadanju mrežnu adresu. No, zapravo, svaka od njih je povezana sa svojim operaterom.

Prvotno sam imao jednostavno rješenje: pomoću naredbe ifconfig ili ip isključiti sve sučelje i jednostavno ih redom uključivati i testirati. Rješenje je funkcioniralo, osim što tijekom prebacivanja nisam imao mogućnost povezivanja na uređaj. A s obzirom na to da je prebacivanje često i brzo, zapravo nisam imao mogućnost povezivanja uopće.

Stoga sam izabrao put ručne promjene IP adresa modema i nastavak usmjeravanja prometa pomoću postavki usmjeravanja.

Istovremeni speedtest na više LTE modema

Na tome se moji problemi s modemima nisu završili: u slučaju problema s napajanjem, isključivali su se, pa je bila potrebna dobra stabilna opskrba iz USB hub-a. Ovaj problem sam riješio čvrstim lemljenjem napajanja direktno na hub. Drugi problem s kojim sam se suočio i koji je uništio cijeli projekt: nakon ponovnog pokretanja ili hladnog starta, nisu se svi modemi uvijek prepoznavali, a nisam mogao ustanoviti zašto se to događa i po kojem algoritmu. No, o svemu po redu.

Za ispravno funkcioniranje modema, instalirao sam paket usb-modeswitch.

sudo apt update
sudo apt install -y usb-modeswitch

Nakon toga, modem će biti ispravno prepoznat i konfiguriran od strane udev pod-sustava. Provjeravam, jednostavno povezujem modem i uvjeravam se da je mreža dostupna.
Još jedan problem koji nisam mogao riješiti: kako iz ovog modema dobiti ime operatera s kojim radimo? Ime operatera je sadržano u web sučelju modema na adresi 192.168.8.1. To je dinamička web stranica koja dobiva podatke putem ajax zahtjeva, pa jednostavno preuzimanje stranice putem wget-a i parsiranje imena ne bi uspjelo. Stoga sam počeo razmišljati kako obraditi web stranicu itd., i shvatio da radim neku glupost. U konačnici, odustao sam i počeo dobivati operatera putem API-ja samog Speedtesta.

Mnogo bi jednostavnije bilo da modem ima pristup putem AT naredbi. Mogao bi se ponovno konfigurirati, kreirati ppp vezu, dodijeliti IP, dobiti ime operatera itd. Ali nažalost, radim s onim što sam dobio.

GPS

GPS prijemnik koji su mi dali imao je UART sučelje i napajanje. Nije bio najbolje rješenje, ali opet je bio funkcionalan i jednostavan. Prijemnik je otprilike ovako izgledao.

Istovremeni speedtest na više LTE modema

Iskreno, prvi put radim s GPS prijemnikom, ali kao što sam i pretpostavio, sve je već odavno smišljeno. Tako da jednostavno koristimo gotova rješenja.

Za početak uključujem uart_AO_B (UART_RX_AO_B, UART_TX_AO_B) za povezivanje GPS-a.

khadas@Khadas:~$ sudo fdtput -t s /dtb.img /serial@c81004e0 status okay

Nakon toga provjeravam uspješnost operacije.

khadas@Khadas:~$ fdtget /dtb.img /serial@c81004e0 status
okay

Ova naredba, sudeći prema svemu, uređuje devtree u hodu, što je prilično praktično.

Nakon uspjeha ove operacije, ponovno se pokrećemo i instaliramo gps demon.

khadas@Khadas:~$ sudo reboot

Instalacija gps demona. Instaliram sve i odmah ga isključujem za daljnju konfiguraciju.

sudo apt install gpsd gpsd-clients -y
sudo killall gpsd
 

/* Zaustavi/isključi GPS demon */
sudo systemctl stop gpsd.socket
sudo systemctl disable gpsd.socket

Uređujem datoteku postavki.

sudo vim /etc/default/gpsd

Postavljam UART na kojem će raditi GPS.

DEVICES="/dev/ttyS4"

I nakon toga uključujemo sve i pokrećemo.

/* GPS daemon enable/start */
sudo systemctl enable gpsd.socket
sudo systemctl start gpsd.socket

Nakon toga, povezujem GPS.

Istovremeni speedtest na više LTE modema

U rukama imam GPS kabel, pod prstima su vidljivi UART žice za debagiranje.

Ponovno se pokrećem i provjeravam rad GPS-a pomoću programa gpsmon.

Istovremeni speedtest na više LTE modema

Na ovoj snimci nema vidljivih satelita, ali se može vidjeti komunikacija s GPS prijemnikom, što znači da je sve u redu.

Na Pythonu sam isprobao mnoge varijante rada s ovim demon, ali sam se odlučio za onu koja ispravno radi s Python 3.

Instaliram potrebnu biblioteku.

sudo -H pip3 install gps3 

I pišem kod za rad.

from gps3.agps3threaded import AGPS3mechanism
...
def getPositionData(agps_thread):
	counter = 0;
	while True:
		longitude = agps_thread.data_stream.lon
		latitude = agps_thread.data_stream.lat
		if latitude != 'n/a' and longitude != 'n/a':
			return '{}' .format(longitude), '{}' .format(latitude)
		counter = counter + 1
		print ("Čekanje gps broja = %d" % counter)
		if counter == 10:
			ErrorMessage("Greška GPS prijemnika!!!")
			return "NA", "NA"
		time.sleep(1.0)
...
f __name__ == '__main__':
...
	#gps
	agps_thread = AGPS3mechanism()  # Instanciraj AGPS3 Mehanizme
	agps_thread.stream_data()  # Iz localhosta (), ili drugih hostova, primjerice, (host='gps.ddns.net')
	agps_thread.run_thread()  # Vrijeme throttlinga za spavanje nakon praznog pretraživanja, po defaultu '()' 0.2 dvije desetinke sekunde

Ako mi trebaju koordinate, to se radi sljedećim pozivom:

longitude, latitude = getPositionData(agps_thread)

I u razdoblju od 1-10 sekundi ili ću dobiti koordinate ili ne. Da, imao sam deset pokušaja da dobijem koordinate. Nije optimalno, nije savršeno, ali radi. Odlučio sam to učiniti jer GPS može slabo hvatanje i ne dobiva uvijek podatke. Ako čekam na dobivanje podataka, program će se zaglaviti na tom mjestu ako radi u zatvorenoj prostoriji. Zato sam implementirao ovakav, ne baš elegantan način.

U principu, da je bilo više vremena, moglo bi se direktno putem UART-a dobijati podatke s GPS-a, parsirati ih u posebnom niti i raditi s njima. Ali vremena nije bilo, otuda i grdi, loš kod. I da, nije me sram.

LED

S povezivanjem LED-a sve je bilo jednostavno i složeno u isto vrijeme. Glavna teškoća je u tome što se broj pina u sustavu ne poklapa s brojem pina na ploči i što je dokumentacija napisana loše. Da bih povezao broj hardverskog pina i broj pina u OS-u, trebam izvršiti komandu:

gpio readall

Bit će prikazana tablica korespondencije pina u sustavu i na ploči. Nakon toga već mogu upravljati pinom u samom OS-u. U mom slučaju, LED je povezan na GPIOH_5.

Istovremeni speedtest na više LTE modema

Prebacujem pin GPIO u način rada izlaza.

gpio -g mode 421 out

Postavljam nulu.

gpio -g write 421 0

Postavljam jedinicu.

gpio -g write 421 1

Istovremeni speedtest na više LTE modema
Sve svijetli nakon zapisa "1"

#gpio subsistem
def gpio_init():
	os.system("gpio -g mode 421 out")
	os.system("gpio -g write 421 1")

def gpio_set(val):
	os.system("gpio -g write 421 %d" % val)
	
def error_blink():
	gpio_set(0)
	time.sleep(0.1)
	gpio_set(1)
	time.sleep(0.1)
	gpio_set(0)
	time.sleep(0.1)
	gpio_set(1)
	time.sleep(0.1)
	gpio_set(0)
	time.sleep(1.0)
	gpio_set(1)

def good_blink():
	gpio_set(1)

Sada, u slučaju grešaka, pozivam error_blink() i LED lijepo svijetli.

Softverski moduli

Speedtest API

Velika sreća što usluga speedtest.net ima svoj vlastiti python-API, možete pogledati na Github.

Dobro je što postoje izvorni kodovi koje također možete pogledati. Kako raditi s ovim API-jem (najjednostavniji primjeri) možete pogledati na odgovarajućem odjeljku.

Instaliram python biblioteku sljedećom komandom.

sudo -H pip3 install speedtest-cli

Za primjer, možete potpuno instalirati speedtest na Ubuntu direktno iz repozitorija. To je također isto python-aplikacija koja se kasnije može pokrenuti iz konzole.

sudo apt install speedtest-cli -y

I izvršiti mjerenja brzine vašeg interneta.

speedtest-cli
Preuzimanje konfiguracije speedtest.net...
Testiranje iz B***** (*.*.*.*)...
Preuzimanje liste servera speedtest.net...
Odabir najboljeg servera na temelju pinga...
Domaćin MTS (Moskva) [0.12 km]: 11.8 ms
Testiranje brzine preuzimanja................................................................................
Preuzimanje: 7.10 Mbit/s
Testiranje brzine otpremanja......................................................................................................
Otpremanje: 3.86 Mbit/s

Kao rezultati, kako sam to učinio. Morao sam zagaziti u izvorne kodove ovog speedtesta kako bih ih bolje integrirao u svoj projekt. Jedan od najvažnijih zadataka je dobiti ime operatera mobilne mreže, kako bih ga uveo u tablicu.

import speedtest
from datetime import datetime
...
#Određujemo određeni server za test
#6053) MaximaTelecom (Moskva, Ruska Federacija)
servers = ["6053"]
# Ako želite koristiti jednoprocesorski test
threads = None
s = speedtest.Speedtest()
#dobivamo ime mobilnog operatera
opos = '%(isp)s' % s.config['client']
s.get_servers(servers)
#dobivamo tekstualni niz s parametrima servera
testserver = '%(sponsor)s (%(name)s) [%(d)0.2f km]: %(latency)s ms' % s.results.server
#test preuzimanja
s.download(threads=threads)
#test slanja
s.upload(threads=threads)
#dobivamo rezultate
s.results.share()

#Nakon toga se formira niz za zapis u csv datoteku.
#dobivamo GPS poziciju
longitude, latitude = getPositionData(agps_thread)
#vrijeme i datum
curdata = datetime.now().strftime('%d.%m.%Y')
curtime = datetime.now().strftime('%H:%M:%S')
delimiter = ';'
result_string = opos + delimiter + str(curpos) + delimiter + 
	curdata + delimiter + curtime + delimiter + longitude + ', ' + latitude + delimiter + 
	str(s.results.download/1000.0/1000.0) + delimiter + str(s.results.upload / 1000.0 / 1000.0) + 
	delimiter + str(s.results.ping) + delimiter + testserver + "n"
#ovdje ide zapis u log datoteku

I ovdje se pokazalo da nije baš sve tako jednostavno, iako bi se moglo činiti. Isprva je parametar servers bio postavljen na [], molim te izaberi najbolji server. Kao rezultat toga imao sam nasumične servere, i kao što se može naslutiti, fluktuirajuću brzinu. To je prilično složena tema, koristiti fiksni server, ako da, je li statički ili dinamički, zahtijeva istraživanje. No evo primjera grafikona mjerenja brzine mobilnog operatera Beelinea pri dinamičkom odabiru testnog servera i statički fiksiranog.

Istovremeni speedtest na više LTE modema
Rezultat mjerenja brzine pri odabiru dinamičkog servera.

Istovremeni speedtest na više LTE modema
Rezultat testiranja brzine, pri strogo odabranom jednom serveru.

„Krutost“ pri testiranju postoji i tu i tamo, i treba ju ukloniti matematičkim metodama. Međutim, pri fiksnom serveru nje je nešto manje, a amplituda je stabilnija.
Uopće, to je mjesto velikih istraživanja. I provodio bih mjerenja brzine prema svom serveru, putem alata iperf. No, pridržavamo se od TŽ.

Slanje e-pošte i pogreške

Za slanje e-pošte isprobao sam nekoliko desetaka različitih opcija, ali na kraju sam se odlučio na sljedeće. Registrirao sam elektroničku poštu na yandex i zatim uzeo ovaj primjer slanja e-pošte. Provjerio sam ga i uveo u program. U ovom primjeru razrađuju se različite opcije, uključujući slanje s gmailom itd. Nije mi se željelo bakći s podizanjem vlastitog poštanskog servera i nisam imao vremena za to, ali kako se kasnije ispostavilo, također uzalud.

Slanje logova obavljao sam putem planer, uz dostupnu vezu, svakih 6 sati: u 00 sati, 06 ujutro, 12 popodne i 18 navečer. Slanje je obavljeno na sljedeći način.

from send_email import *
...
message_log = "Logovi testiranja ploče br. 1"
EmailForSend = ["dlinyj@trololo.ru", "pupkin@trololo.ru"]
files = ["/home/khadas/modems_speedtest/csv"]
...
def sendLogs():
	global EmailForSend
	curdata = datetime.now().strftime('%d.%m.%Y')
	сurtime = datetime.now().strftime('%H:%M:%S')
	try:
		for addr_to in EmailForSend:
			send_email(addr_to, message_log, "Logovi za " + curdata + " " + сurtime, files)
	except:
		print("Problemi s mrežom pri slanju maila")
		return False
	return True

Greške su također inicijalno slane. Isprva su se nakupljale u listi, a zatim su se slale također putem planera, uz dostupnu vezu. Međutim, kasnije su se pojavili problemi s tim da Yandex ima ograničenje na broj poslanih poruka dnevno (to je bol, žalost i poniženje). S obzirom da je grešaka moglo biti ogromna količina, morali smo odustati od slanja grešaka putem maila. Zato imajte na umu, prilikom automatskog slanja putem Yandex servisa o ovom problemu.

Server povratnih informacija

Da bih imao pristup udaljenoj opremi i mogućnost dodatnog podešavanja i rekonstrukcije, potreban mi je bio vanjski server. Uistinu, ispravno bi bilo sve podatke slati na server i u web sučelju izraditi lijepe grafikone. No, ne možemo sve odjednom.

Kao VPS izabrao sam ruvds.com. Mogao sam uzeti najjednostavniji server. I općenito bi to bilo dovoljno za moje ciljeve. No, s obzirom da nisam plaćao server iz vlastitog džepa, odlučio sam uzeti s malim viškom, da bude dovoljno ako budemo razvijali web sučelje, vlastiti SMTP server, VPN itd. Plus imati mogućnost podešavanja Telegram bota i nemati problema s njegovim blokadama. Zato sam odabrao Amsterdam i sljedeće parametre.

Istovremeni speedtest na više LTE modema

Kao način povezivanja s opremom vim2 odabrao sam povratnu SSH vezu i kako se pokazalo u praksi — nije baš najbolja opcija. Pri prekidu veze, server zadržava port i nije moguće povezati se određeno vrijeme. Zato je ipak bolje koristiti druge načine povezivanja, kao što je VPN. U budućnosti sam želio preći na VPN, ali nisam imao vremena.

Neću ulaziti u detalje postavki vatrozida, ograničavanja prava, isključivanja ssh veze root i druge očigledne postavke VPS-a. Nadam se da sve to već znate. Za udaljenu vezu, kreiram novog korisnika na serveru.

adduser vimssh

Na našem serveru generiram ssh ključeve za vezu.

ssh-keygen

I kopiram ih na naš server.

ssh-copy-id vimssh@host.com

Na našem serveru postavljam automatsku vezu obrnjenog ssh-a pri svakom pokretanju.

[Unit]
Opis=Auto Reverse SSH
Zahteva=systemd-networkd-wait-online.service
Nakon=systemd-networkd-wait-online.service
[Service]
Korisnik=khadas
ExecStart=\/usr\/bin\/ssh -NT -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -CD 8080 -R 8083:localhost:22 vimssh@host.com
RestartSec=5
Restart=uvijek
[Install]
WantedBy=multi-user.target

Obratite pažnju na port 8083: on određuje preko kojeg porta će se uspostaviti veza putem obrnutog ssh-a. Dodajemo u autostart i pokrećemo.

sudo systemctl enable autossh.service
sudo systemctl start autossh.service

Možete čak provjeriti status:

sudo systemctl status autossh.service

Sada, na našem VPS serveru, ako izvršim:

ssh -p 8083 khadas@localhost

Dolazim do svoje testne mašine. I s mašine također mogu slati logove i sve podatke putem ssh-a na moj server, što je vrlo praktično.

Svi su objedinjeni

Istovremeni speedtest na više LTE modema
Pokretanje, prelazimo na razvoj i debagiranje

Uf, čini se da sam sve opisao. Sada je vreme da sve to skupim na jedno mesto. Kod možete pogledati ovdje.

Važna stvar s kodom: Ovaj projekt se ovako direktno ne može pokrenuti, jer je prilagođen određenom zadatku i određenoj arhitekturi. Iako pružam izvorne kodove, sve najvrednije ću razjasniti ovde u tekstu, inače nije potpuno jasno.

Na početku imam inicijalizaciju gps-a, gpio i pokretanje posebne niti planera.

#запуск потока планировщика
pShedulerThread = threading.Thread(target=ShedulerThread, args=(1,))
pShedulerThread.start()

Planer je prilično jednostavan: prati nije li vrijeme za slanje poruka i koja je trenutno stanje grešaka. Ako postoji oznaka greške, trepće LED diodom.

#sheduler
def ShedulerThread(name):
	global ready_to_send
	while True:
		d = datetime.today()
		time_x = d.strftime('%H:%M')
		if time_x in time_send_csv:
			ready_to_send = True
		if error_status:
			error_blink()
		else:
			good_blink()
		time.sleep(1)

Najteži trenutak u ovom projektu je očuvanje obrnute ssh veze pri svakom testu. U svakom testu ponovo se postavlja podrazumevani gateway i dns server. Pošto niko uopšte ne čita, znajte da voz ne ide po drvenim šinama. Tko pronađe uskršnju jaje, dobijat će bombon.

Za ovo kreiram posebnu tabelu usmjeravanja —set-mark 0x2 i pravilo za preusmjeravanje prometa.

def InitRouteForSSH():
	cmd_run("sudo iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 22 -j MARK --set-mark 0x2")
	cmd_run("sudo ip rule add fwmark 0x2/0x2 lookup 102")

Više o tome kako to funkcioniše možete pročitati u ovom članku.

Nakon toga prelazim u beskonačnu petlju, gdje svaki put dobivamo popis povezanih modema (kako bismo saznali je li se mrežna konfiguracija promijenila).

network_list = getNetworklist()

Dobivanje popisa mrežnih sučelja prilično je jednostavno.

def getNetworklist():
	full_networklist = os.listdir('\/sys\/class\/net\/')
	network_list = [x for x in full_networklist if "eth" in x and x != "eth0"]
	return network_list

Nakon dobivanja popisa, postavljam IP adrese svim sučeljima, kao što sam prikazao na slici u poglavlju o modemima.

SetIpAllNetwork(network_list)

def SetIpAllNetwork(network_list):
	for iface in network_list:
		lastip = "%d" % (3 + network_list.index(iface))
		cmd_run ("sudo ifconfig " + iface + " 192.168.8." + lastip +" up")

Zatim jednostavno prolazim kroz svaki interfejs u petlji. I konfiguriram svako sučelje.

	for iface in network_list:
		ConfigNetwork(iface)

def ConfigNetwork(iface):
#resetujemo sve postavke
		cmd_run("sudo ip route flush all")
#Postavljamo podrazumijevani prolaz
		cmd_run("sudo route add default gw 192.168.8.1 " + iface)
#postavljamo dns server (to je potrebno za rad speedtest)
		cmd_run ("sudo bash -c 'echo nameserver 8.8.8.8 > \/etc\/resolv.conf'")

Provjeravam sučelje na funkcionalnost, ako nema mreže, formiram greške. Ako mreža postoji, vrijeme je za akciju!

Ovdje postavljam ssh rutiranje na to sučelje (ako to nije bilo učinjeno), šaljem greške na server, ako je vrijeme došlo, šaljem logove i na kraju provodim speedtest i sprema logove u csv datoteku.

if not NetworkAvalible():
....
#Ovdje formiramo greške
....
else: #Ima mreže, ura, radimo!
#Ako imamo problematično sučelje, na kojem je ssh, onda ga mijenjamo
  if (sshint == lastbanint or sshint =="free"):
    print("********** Postavljanje SSH ********************")
    if sshint !="free":
      cmd_run("sudo ip route del default via 192.168.8.1 dev " + sshint +" table 102")
    SetupReverseSSH(iface)
    sshint = iface
#s obzirom na to da mreža radi, onda brzo pošaljimo sve!!!
    if ready_to_send:
      print ("**** Spremni za slanje!!!")
        if sendLogs():
          ready_to_send = False
        if error_status:
          SendErrors()
#i dalje testiramo brzinu i spremamo logove. 

Ipak, potrebno je spomenuti funkciju za postavljanje obratnog ssh.

def SetupReverseSSH(iface):
	cmd_run("sudo systemctl stop autossh.service")
	cmd_run("sudo ip route add default via 192.168.8.1 dev " + iface +" table 102")
	cmd_run("sudo systemctl start autossh.service")

Naravno, potrebno je dodati svu ovu ljepotu u automatsko pokretanje. Za to kreiram datoteku:

sudo vim \/etc\/systemd\/system\/modems_speedtest.service

I zapisujem u nju:

[Unit]
Opis=Test brzine modema
Zahteva=systemd-networkd-wait-online.service
Nakon=systemd-networkd-wait-online.service
[Service]
Korisnik=khadas
ExecStart=\/usr\/bin\/python3.6 \/home\/khadas\/modems_speedtest\/networks.py
RestartSec=5
Restart=uvijek
[Install]
WantedBy=multi-user.target

Uključujem automatsko pokretanje i započinjem!

sudo systemctl enable modems_speedtest.service
sudo systemctl start modems_speedtest.service

Sada mogu gledati logove onoga što se događa pomoću komande:

journalctl -u modems_speedtest.service --no-pager -f

Rezultati

Pa sada, najvažnije, što smo postigli kao rezultat? Navest ću nekoliko grafikona koje sam uspio zabilježiti tijekom razvoja i ispravljanja grešaka. Grafikoni su izrađeni pomoću gnuplot uz sljedeći skript.

#! /usr/bin/gnuplot -persist
set terminal postscript eps enhanced color solid
set output "Rostelecom.ps"
 
#set terminal png size 1024, 768
#set output "Rostelecom.png"
 
set datafile separator ';'
set grid xtics ytics
set xdata time
set ylabel "Speed Mb/s"
set xlabel 'Time'
set timefmt '%d.%m.%Y;%H:%M:%S'
set title "Rostelecom Speed"

plot "Rostelecom.csv" using 3:6 with lines title "Download", '' using 3:7 with lines title "Upload"
 
set title "Rostelecom 2 Ping"
set ylabel "Ping ms"
plot "Rostelecom.csv" using 3:8 with lines title "Ping"

Prvo iskustvo bilo je s operatorom Tele2, kojeg sam provodio nekoliko dana.

Istovremeni speedtest na više LTE modema

Ovdje sam koristio dinamički mjerni server. Mjerenja brzine funkcioniraju, ali su jako promjenjiva, no i dalje se može primijetiti neka prosječna vrijednost, a može se dobiti filtriranjem podataka, na primjer, pomoću pomičnog prosjeka.

Kasnije sam izgradio još nekoliko grafikona za druge telekomunikacijske operatore. Testni server u ovom slučaju već je bio jedan, a rezultati su također vrlo zanimljivi.

Istovremeni speedtest na više LTE modema

Istovremeni speedtest na više LTE modema

Istovremeni speedtest na više LTE modema

Istovremeni speedtest na više LTE modema

Kao što se može vidjeti, tema je vrlo opsežna za istraživanje i obradu tih podataka, i očito ne može stati u samo par tjedana rada. No...

Zaključak rada

Rad je naglo prekinut zbog okolnosti na koje nisam mogao utjecati. Jedna od slabih točaka ovog projekta, po mom subjektivnom mišljenju, bio je modem, koji nije želio raditi istovremeno s drugim modemima, i pri svakom pokretanju je pravio takve probleme. Za te svrhe postoji ogroman broj drugih modela modema, obično već imaju format Mini PCI-e i stavljaju se unutar uređaja, a mnogo ih je lakše konfigurirati. No, to je već posve druga priča. Projekt je bio zanimljiv, i bio sam vrlo sretan što sam mogao sudjelovati.

Istovremeni speedtest na više LTE modema

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster