複数のLTEモデムでの同時速度テスト

検疫では、いくつかの携帯電話会社のLTEモデムの速度を測定するデバイスの開発に参加するように勧められました。







顧客は、さまざまな地理的位置にあるあらゆる種類の通信事業者の速度を評価して、ビデオブロードキャストなどのLTE接続を使用して機器を設置するときに、どの携帯事業者が最適かを理解したいと考えていました。同時に、高価な設備を使わずに、タスクをできるだけ簡単かつ安価に解決する必要がありました。



このタスクは最も単純で最も知識集約的ではないことをすぐに言っておく必要があります。私はどのような問題が発生し、どのように解決したかを説明します。じゃ、行こう。



注意



LTE接続の速度を測定することは非常に難しい問題です:適切な機器と測定方法を選択する必要があり、セルラーネットワークのトポロジーと運用についても十分に理解している必要があります。さらに、速度はいくつかの要因によって影響を受ける可能性があります。セルごとの加入者数、気象条件、さらにはセルごとに、ネットワークトポロジによって速度が著しく異なる場合があります。一般に、これは未知数が非常に多い問題であり、通信事業者だけが正しく解決できます。



当初、顧客はオペレーターの電話で宅配便を運転し、電話で直接測定を行い、速度測定結果をノートブックに書き留めたいと考えていました。 lteネットワークの速度を測定するための私のソリューションは、理想的ではありませんが、問題を解決します。



時間がないため、利便性や実用性を優先するのではなく、開発のスピードを優先して決定しました。たとえば、リモートアクセスの場合、サーバーと個々のクライアントをセットアップする時間を節約するために、より実用的なvpnではなく、リバースSSHが発生しました。



技術的なタスク



記事で述べたようにTKがなけれ:クライアントが望んでいない理由TKなくてはならない仕事!決して、どこにも!



技術的な割り当ては非常に単純でした。エンドユーザーを理解するために少し拡張します。技術的なソリューションと機器の選択は、お客様によって決定されました。それで、すべての承認後のTK自体:



vim2 lte- Huawei e3372h — 153 ( n). GPS-, UART. www.speedtest.net :







csv. - 6 . , GPIO.


多くの承認を得た後、TKを自由形式で説明しました。しかし、タスクの意味はすでに見えています。すべての締め切りは一週間でした。しかし、実際には3週間続きました。これは、本業を終えて週末にしかやっていなかったことを踏まえたものです。



ここで、お客様が以前に速度測定サービスとハードウェアを使用することに同意していたため、私の能力が大幅に制限されていたことに注目してください。予算も限られていたので、追加購入はありませんでした。だから私はこれらのルールを守らなければならなかった。



アーキテクチャと開発



スキームはシンプルで簡単です。したがって、特別なコメントは省きます。







私はこの言語での開発経験がまったくなかったにもかかわらず、Pythonでプロジェクト全体を実装することにしました。開発をスピードアップできる既製の例やソリューションがたくさんあったので、私はそれを選びました。したがって、私はすべてのプロのプログラマーに、Python開発の最初の経験を叱らないようにお願いします。また、私のスキルを向上させるための建設的な批判を聞いていつも満足しています。



また、その過程で、pythonに2つのバージョン2と3が実行されていることがわかり、その結果、3番目のバージョンで停止しました。



ハードウェアノード



シングルボードvim2



メインマシンとして、シングルボードvim2が与えられました







スマートホームとSMART-TVには優れた強力なメディアが組み合わされていますが、このタスクには非常に適していません。たとえば、メインのOSはAndroidで、Linuxは合格OSであるため、Linuxですべてのノードとドライバーの高品質な動作を保証するものはありません。また、問題の一部はこのプラットフォームのUSBドライバーに関連していると考えられるため、このボードではモデムが期待どおりに動作しませんでした。彼はまた、非常に貧弱で散在したドキュメントを持っているので、各操作はドックを掘るのに多くの時間を要しました。 GPIOでの通常の作業でさえ、大量の血を飲みました。たとえば、LEDを使用した作業をセットアップするのに数時間かかりました。しかし、客観的に言うと、どのようなシングルボードデバイスであるかは基本的に重要ではありませんでした。主なことは、デバイスが機能し、USBポートを備えていることです。



まず、このボードにLinuxをインストールする必要があります。誰もがこのシングルボードデバイスを扱う人のために、ドキュメントのジャングルを掘り下げないようにするために、この章を書いています。



Linuxのインストールには、外部SDカードまたは内部MMCの2つのオプションがあります。私は夕方にカードと格闘し、それを動作させる方法がわからなかったので、MMCにインストールすることにしましたが、間違いなく外部カードを使用する方がはるかに簡単です。



ファームウェアはここ曲がって説明されています私は奇妙なものからロシア語に翻訳しています。ボードをフラッシュするには、ハードウェアUARTを接続する必要があります。以下のように接続しました。



  • ツールピンGND:<—> VIMのGPIOのピン17
  • ツールピンTXD:<—> VIMのGPIOのピン18(Linux_Rx)
  • ツールピンRXD:<—> VIMのGPIOのPin19(Linux_Tx)
  • ツールピンVCC:<—> VIMのGPIOのPin20






その後、こちらからファームウェアをダウンロードしました特定のファームウェアバージョンはVIM1_Ubuntu-server-bionic_Linux-4.9_arm64_EMMC_V20191231です。



このファームウェアをアップロードするには、特定のユーティリティが必要です。詳しくはこちらをご覧くださいWindowsではフラッシュを試していませんが、Linuxファームウェアについて簡単に説明します。最初に、指示に従ってユーティリティをインストールします。



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


Iii ...何も機能しません。すべてが正しくインストールされるように、私は数時間かけてインストールスクリプトを編集しました。私がそこで何をしたか覚えていませんが、馬とのサーカスもしました。ので注意してください。しかし、これらのユーティリティがなければ、vim2をさらに拷問する意味はありません。彼をいじらないでください!



地獄、スクリプトの構成、およびインストールの7つの円の後で、動作するユーティリティのパッケージを入手しました。ボードをLinuxコンピューターにUSB経由で接続し、UARTも上の図に従って接続されています。

お気に入りのminicom端末を115200に設定しています。ハードウェアまたはソフトウェアのエラー制御はありません。それでは始めましょう。







UARTターミナルでVIM2を起動するときに、スペースバーなどの任意のキーを押して起動を停止します。行が表示された後



kvim2# 


次のコマンドを入力します。



kvim2# run update


ダウンロード元のホストで、次のコマンドを実行します。



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


みなさん、ふw。私は尋ねました、ボードにはLinuxがあります。ログイン/パスワードkhadas:khadas。



その後、小さな初期設定。今後の作業のために、sudoのパスワードを無効にします(はい、安全ではありませんが、便利です)。



sudo visudo


行をビ​​ューに編集して保存します



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


次に、現在のロケールを変更して、時刻がモスクワになるようにします。それ以外の場合は、GMTになります。



sudo timedatectl set-timezone Europe/Moscow


または



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


難しいと感じる場合は、このボードを使用しないでください。RaspberryPiが最適です。フェア。



モデムHuawei e3372h-153



このモデムは私の血をよく飲み、そして実際、それはプロジェクト全体のボトルネックになりました。一般に、これらのデバイスの「モデム」という名前は、作業の本質をまったく反映していません。これは強力な組み合わせであり、このハードウェアの一部には、ドライバーをインストールするためにCD-ROMのふりをして、ネットワークカードモードに入る複合デバイスがあります。



構造的には、Linuxユーザーの観点から見ると、すべての設定を終えると、次のようになります。モデムを接続すると、dhcpを介してIPアドレス192.168.8.100を受信するeth *ネットワークインターフェイスと、デフォルトゲートウェイ192.168.8.1を取得します。



そして最も重要なポイント!このモデムモデルは、ATコマンドによって制御されるモデムモードで動作する方法を認識していません...すべてがはるかに簡単になり、モデムごとにppp接続を作成して、それらを操作します。しかし、私の場合、「自分」(正確にはudevルールによるLinuxダイバー)がethインターフェースを作成し、dhcpを介してそれにipアドレスを割り当てます。



さらに混乱しないように、「モデム」という言葉を忘れて、ネットワークカードとゲートウェイを言うことをお勧めします。実際、これは新しいネットワークカードをゲートウェイに接続するようなものです。

モデムが1台の場合、これは特別な問題の原因にはなりませんが、モデムが複数、つまりn個の場合は、次のネットワークの図が表示されます。







つまり、n個のネットワークカードで、IPアドレスが同じで、それぞれがデフォルトゲートウェイが同じです。しかし、実際には、それぞれが独自のオペレーターに接続されています。



最初は簡単な解決策がありました。ifconfigまたはipコマンドを使用してすべてのインターフェイスを消し、1つずつ順番にオンにしてテストしました。ソリューションは、切り替えの瞬間にデバイスに接続できなかったことを除いて、すべての人に適していました。また、切り替えが頻繁かつ高速であるため、実際には接続する機会がまったくありませんでした。



したがって、モデムのIPアドレスを「手動で」変更し、ルーティング設定を使用してトラフィックを駆動し続ける方法を選択しました。







これは私のモデムの問題の終わりではありませんでした:電源の問題が発生した場合、それらは落ち、USBハブへの適切な安定した電源が必要でした。この問題は、電源をハブに直接ハードはんだ付けすることで解決しました。私が直面し、プロジェクト全体を台無しにした別の問題:デバイスの再起動またはコールドスタートの後、すべてのモデムが検出されたわけではなく、常に検出されたわけではありません。これが発生した理由と、インストールできなかったアルゴリズム。しかし、まず最初に。



モデムが正しく機能するように、usb-modeswitchパッケージをインストールしました。



sudo apt update
sudo apt install -y usb-modeswitch


その後、接続後のモデムはudevサブシステムによって正しく検出および構成されます。モデムを接続して、ネットワークが稼働していることを確認します。

私が解決できなかったもう1つの問題:このモデムから、操作するオペレーターの名前を取得する方法は?オペレーターの名前は、モデムのWebインターフェースの192.168.8.1に含まれています。これはajaxリクエストを介してデータを受信する動的なWebページなので、ページを取得して名前を解析することはできません。それで、Webページの作り方などを検討し始めて、なんかナンセンスなことをやっていることに気づきました。その結果、彼は唾を吐き、Speedtest自体のAPIを使用してオペレーターを受け入れ始めました。



ATコマンドを介してモデムにアクセスできれば、多くのことが簡単になります。再構成、ppp接続の作成、IPの割り当て、キャリアの取得などが可能です。しかし、悲しいかな、私は自分が与えたもので作業します。



GPS



私に与えられたGPS受信機は、UARTインターフェースと電源を備えていました。それは最善の解決策ではありませんでしたが、それでも機能し、シンプルでした。受信機はこんな感じでした。







正直なところ、これは初めてGPSレシーバーを使用した作業ですが、予想どおり、すべてがずっと前に発明されました。つまり、既製のソリューションを使用するだけです。



まず、UART_AO_B(UART_RX_AO_B、UART_TX_AO_B)をオンにしてGPSを接続します。



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


次に、操作の成功を確認します。



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


このコマンドは明らかに、その場でdevtreeを編集するため、非常に便利です。



この操作が成功したら、再起動してgpsデーモンをインストールします。



khadas@Khadas:~$ sudo reboot


gpsデーモンのインストール。すべてをインストールし、すぐにそれを切り取って、さらに構成します。



sudo apt install gpsd gpsd-clients -y
sudo killall gpsd
 
/* GPS daemon stop/disable */
sudo systemctl stop gpsd.socket
sudo systemctl disable gpsd.socket


設定ファイルの編集。



sudo vim /etc/default/gpsd


GPSがハングするUARTをインストールします。



DEVICES="/dev/ttyS4"


そして、すべてをオンにして開始します。



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


その後、GPSを接続します。







GPSワイヤーは手の中にあり、デバッガーのUARTワイヤーは指の下に見えます。



再起動してgpsmonプログラムを使用してGPSを確認します。







このスクリーンショットでは、衛星は見えませんが、GPS受信機との通信を見ることができます。これは、すべてが正常であることを示しています。



Pythonでは、このデーモンを操作するために多くのオプションを試しましたが、Python 3で正しく機能するオプションを選択しました



。必要なライブラリをインストールします。



sudo -H pip3 install gps3 


そして、私は仕事のコードを作ります。



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 ("Wait gps counter = %d" % counter)
		if counter == 10:
			ErrorMessage(" GPS !!!")
			return "NA", "NA"
		time.sleep(1.0)
...
f __name__ == '__main__':
...
	#gps
	agps_thread = AGPS3mechanism()  # Instantiate AGPS3 Mechanisms
	agps_thread.stream_data()  # From localhost (), or other hosts, by example, (host='gps.ddns.net')
	agps_thread.run_thread()  # Throttle time to sleep after an empty lookup, default '()' 0.2 two tenths of a second


座標を取得する必要がある場合、これは次の呼び出しによって行われます。



longitude, latitude = getPositionData(agps_thread)


そして、1-10秒以内に、座標を取得するかどうかを決定します。はい、座標を取得するために10回試行しました。最適ではなく、曲がっており、斜めですが、機能します。GPSが十分に捕捉できず、常にデータを受信できるわけではないため、これを行うことにしました。データが受信されるのを待っている場合、リモートルームで作業していると、プログラムはこの場所でフリーズします。したがって、私はそのようなエレガントではないオプションを実装しました。



原則として、もっと時間があり、UARTを介してGPSから直接データを受信し、別のストリームでそれらを解析して、それらを操作することが可能です。しかし、まったく時間がなかったため、非常に醜いコードです。そして、はい、私は恥じていません。



発光ダイオード



LEDの接続は、すべてシンプルかつ複雑でした。主な問題は、システムのピン番号がボードのピン番号に対応していないことと、ドキュメントが左ヒールで書かれているためです。ハードウェアのピン番号とOSのピン番号を一致させるには、次のコマンドを実行する必要があります。



gpio readall


システムとボード上のピンの対応表が表示されます。その後、OS自体で既にピンを操作できます。私の場合、LEDはGPIOH_5に接続されています







GPIOピンを出力モードに転送します。



gpio -g mode 421 out


ゼロを書き留めます。



gpio -g write 421 0


1つ書き留めます。



gpio -g write 421 1




「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)


エラーが発生した場合は、error_blink()を呼び出すと、LEDが適切に点滅します。



ソフトウェアノード



Speedtest API



それはspeedtest.netサービスは、独自のpython-APIを持っている、あなたは上でそれを見ることができるという大きな喜びだのGithub



良いニュースは、表示できるソースコードがあることです。このAPIの操作方法(最も単純な例)は、対応するセクションにあります。



次のコマンドでpythonライブラリをインストールします。



sudo -H pip3 install speedtest-cli


たとえば、担当者から直接Ubuntuにスピードテスターをインストールすることもできます。これは、コンソールから直接実行できるのと同じPythonアプリケーションです。



sudo apt install speedtest-cli -y


そして、あなたのインターネットの速度を測定します。 その結果、私がしたように。私のプロジェクトにそれらをより完全に実装するために、このスピードテストのソースコードを掘り下げる必要がありました。最も重要なタスクの1つは、通信事業者の名前を取得して、プレートで置き換えることです。



speedtest-cli

Retrieving speedtest.net configuration...

Testing from B***** (*.*.*.*)...

Retrieving speedtest.net server list...

Selecting best server based on ping...

Hosted by MTS (Moscow) [0.12 km]: 11.8 ms

Testing download speed................................................................................

Download: 7.10 Mbit/s

Testing upload speed......................................................................................................

Upload: 3.86 Mbit/s








import speedtest
from datetime import datetime
...
#    
#6053) MaximaTelecom (Moscow, Russian Federation)
servers = ["6053"]
# If you want to use a single threaded test
threads = None
s = speedtest.Speedtest()
#    
opos = '%(isp)s' % s.config['client']
s.get_servers(servers)
#     
testserver = '%(sponsor)s (%(name)s) [%(d)0.2f km]: %(latency)s ms' % s.results.server
# 
s.download(threads=threads)
# 
s.upload(threads=threads)
# 
s.results.share()

#       csv-.
#  GPS
longitude, latitude = getPositionData(agps_thread)
#  
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"
#     


ここでも、すべてがそれほど単純ではないことがわかりましたが、はるかに簡単に思えます。最初は、serversパラメータは[]でした、と彼らは言います。その結果、ランダムなサーバーがあり、ご想像のとおり、浮動速度でした。これはかなり複雑なトピックであり、固定サーバーを使用している場合、静的または動的の場合、調査が必要です。しかし、これは、テストサーバーと静的に固定されたサーバーを動的に選択して、Beelineオペレーターの速度を測定するためのグラフの例です。





動的サーバーを選択するときに速度を測定した結果。





厳密に選択された1つのサーバーを使用した速度テストの結果。



テスト中の「ウール」はあちこちにあり、数学的な方法で取り除く必要があります。しかし、固定サーバーでは、それはわずかに少なくなり、振幅はより安定します。

一般的に、これは素晴らしい研究の場所です。そして、iperfユーティリティを使用してサーバーへの速度を測定します。しかし、TKに固執します。



メールの送信とエラー



私はメールを送信するために数十の異なるオプションを試してみましたが、その結果、私は以下に落ち着きました。私はyandexにメールボックスを登録してから、このメール送信の例を取り上げました。私はそれをチェックし、プログラムに実装しました。この例では、Gmailからの送信など、さまざまなオプションについて説明します。私はメールサーバーを増やすことに煩わされたくなかったし、これを行う時間もありませんでしたが、後で判明したように、それも無駄でした。



ログは、スケジューラーに従って、接続があった場合、6時間ごとに送信されました:00時間、午前6時、正午、午後18時。以下のように送りました。



from send_email import *
...
message_log = "   №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, "  " + curdata + " " + urtime, files)
	except:
		print("Network problem for send mail")
		return False
	return True


エラーも最初に送信されました。まず、それらはリストに蓄積され、接続がある場合はスケジューラを使用して送信しました。しかし、その後、ヤンデックスが1日に送信するメッセージの数に制限があるという問題がありました(これは、痛み、悲しみ、屈辱です)。1分でも膨大な数のエラーが発生する可能性があるため、メールによるエラーの送信を拒否する必要がありました。そのため、そのような問題についてYandexサービスを自動的に送信する場合は注意してください。



フィードバックサーバー



リモートのハードウェアにアクセスし、調整して再構成できるようにするには、外部サーバーが必要でした。一般的に、公平を期して、すべてのデータをサーバーに送信し、Webインターフェースですべての美しいグラフを作成するのが正しいでしょう。しかし、一度にすべてではありません。



VPSにはruvds.comを選びました。最も単純なサーバーを使用できます。そして、一般的に、私の目的では、これで十分です。しかし、私はサーバーの代金を払う必要がなかったので、少し余裕を持ってそれを採用することにしました。そのため、Webインターフェイス、SMTPサーバー、vpnなどを展開するだけで十分です。さらに、Telegramボットをセットアップして、それをブロックする問題がないようにすることができます。したがって、アムステルダムと以下のパラメーターを選択しました。







ハードウェアの一部と通信する方法として、vim2はリバースssh接続を選択しましたが、実際に示されているように、それは最善ではありません。接続が切断された場合、サーバーはポートを保持しており、しばらくの間それを介して接続することは不可能です。したがって、vpnなどの他の通信方法を使用することをお勧めします。将来はvpnに切り替えたかったのですが、時間がありませんでした。



ファイアウォールの設定、権限の制限、SSHルート接続の無効化、およびVPS設定のその他の一般的な真実の詳細には触れません。私はあなたがすでにすべてを知っていると信じたいと思います。リモート接続の場合、サーバーに新しいユーザーを作成します。



adduser vimssh


私たちのハードウェアでは、ssh接続キーを生成します。



ssh-keygen


そして、それらをサーバーにコピーします。



ssh-copy-id vimssh@host.com


私たちのハードウェアでは、起動のたびにリバースSSHの自動接続を作成します。 ポート8083に注意してください。リバースSSHを介して接続するポートを決定します。スタートアップに追加して開始します。



[Unit]

Description=Auto Reverse SSH

Requires=systemd-networkd-wait-online.service

After=systemd-networkd-wait-online.service

[Service]

User=khadas

ExecStart=/usr/bin/ssh -NT -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -CD 8080 -R 8083:localhost:22 vimssh@host.com

RestartSec=5

Restart=always

[Install]

WantedBy=multi-user.target








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


ステータスも確認できます。



sudo systemctl status autossh.service


次に、VPSサーバーで、次のコマンドを実行した場合:



ssh -p 8083 khadas@localhost


それから私は私のテストピースに行きます。そして、鉄片から、ログとすべてのデータをssh経由でサーバーに送信することもできます。これは非常に便利です。



すべてを一緒に入れて





オンにすると、



Fuhの開発とデバッグを開始します。まあ、すべてがすべてのノードを記述しているようです。すべてをまとめる時が来ました。コードはここで見ることができます



コードの重要なポイント:この「vlob」のようなこのプロジェクトは、特定のアーキテクチャーの特定のタスクで強化されたため、開始されない可能性があります。私はソースコードを提供しますが、ここでもテキストで最も価値のあるものを分析します。それ以外の場合は、完全に理解できません。



最初は、gps、gpioの初期化と、別のスケジューラスレッドの起動があります。



#  
pShedulerThread = threading.Thread(target=ShedulerThread, args=(1,))
pShedulerThread.start()


スケジューラーは非常に単純です。メッセージを送信する時期が来たかどうか、および現在のエラー状況を確認します。エラーフラグがある場合は、LEDを点滅させます。



#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)


このプロジェクトの最も難しい部分は、すべてのテストでリバースSSH接続を維持することです。各テストでは、デフォルトゲートウェイとDNSサーバーが再構成されます。とにかく誰も読んでいないので、電車は木製のレールで転がらないことに注意してください。イースターエッグを見つけた人は誰でも甘党になります。



これを行うには、別のルーティングテーブル--set-mark 0x2とトラフィックをリダイレクトするルールを作成します。



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")


このしくみの詳細については、この記事をご覧ください



次に、接続されたモデムのリストを取得するたびに(ネットワーク構成が変更されたかどうかを確認するため)、無限ループに入ります。



network_list = getNetworklist()


ネットワークインターフェイスのリストを取得するのはかなり簡単です。



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


リストを受け取った後、モデムに関する章の図で示したように、すべてのインターフェイスにIPアドレスを割り当てます。



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")


次に、各インターフェイスをループで処理します。そして、各インターフェースを設定します。



	for iface in network_list:
		ConfigNetwork(iface)


def ConfigNetwork(iface):
#  
		cmd_run("sudo ip route flush all")
#   
		cmd_run("sudo route add default gw 192.168.8.1 " + iface)
# dns- (    speedtest)
		cmd_run ("sudo bash -c 'echo nameserver 8.8.8.8 > /etc/resolv.conf'")


インターフェイスの操作性をチェックし、ネットワークがない場合はエラーを生成します。ネットワークがあれば、行動する時が来ました!



ここで、このインターフェースへのsshルーティングを設定し(完了していない場合)、サーバーにエラーを送信し、時間が経過した場合はログを送信し、最後にspeedtestを実行してログをcsvファイルに保存します。



if not NetworkAvalible():
....
#   
....
else: # , , !
#    ,   ssh,   
  if (sshint == lastbanint or sshint =="free"):
    print("********** Setup SSH ********************")
    if sshint !="free":
      md_run("sudo ip route del default via 192.168.8.1 dev " + sshint +" table 102")
    SetupReverseSSH(iface)
    sshint = iface
#  ,     !!!
    if ready_to_send:
      print ("**** Ready to send!!!")
        if sendLogs():
          ready_to_send = False
        if error_status:
          SendErrors()
#      . 


逆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")


そしてもちろん、このすべての美しさをスタートアップに追加する必要があります。これを行うには、ファイルを作成します。



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


そして私はそれに書き込みます: 私はオートロードをオンにして開始します!



[Unit]

Description=Modem Speed Test

Requires=systemd-networkd-wait-online.service

After=systemd-networkd-wait-online.service

[Service]

User=khadas

ExecStart=/usr/bin/python3.6 /home/khadas/modems_speedtest/networks.py

RestartSec=5

Restart=always

[Install]

WantedBy=multi-user.target








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


これで、次のコマンドを使用して、何が起こっているかのログを見ることができます。



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


結果



さて、今最も重要なことは、結果として何が起こったのですか?以下は、開発およびデバッグプロセス中にキャプチャしたグラフです。グラフは、次のスクリプトでgnuplotを使用して作成されました。



#! /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"


最初の経験は私が数日間過ごしたオペレーターTele2でした。







ここでは動的計測サーバーを使用しました。速度測定は機能しますが、非常に変動しますが、一部の平均値は表示されたままであり、たとえば移動平均でデータをフィルタリングすることで取得できます。



その後、他の通信事業者のために一連のグラフを作成しました。この場合、すでに1つのテストサーバーがあり、結果も非常に興味深いものです。



















ご覧のように、このトピックはこのデータの調査と処理に非常に広範囲であり、明らかに数週間の作業が続くわけではありません。だが…



仕事の結果



私の手に負えない状況のため、作業は突然完了しました。このプロジェクトの弱点の1つは、私の主観的な意見では、モデムでした。モデムは、他のモデムと同時には動作したくなく、起動するたびにそのようなトリックを作りました。これらの目的のために、非常に多くの他のモデルのモデムがあり、通常、それらはすでにMini PCI-eフォーマットを備えており、デバイス内にインストールされ、構成がはるかに簡単です。しかし、それはまったく別の話です。このプロジェクトは面白かったし、なんとか参加できてよかった。






All Articles