Борьба с зависанием МТС 3G модема ZTE MF192+ на Zyxel Keenetic giga
Развитие постепенно идёт и вроде как у нас теперь везде есть мега стабильный и быстрый интернет =)
Решил себе на даче создать свою сеть. Для чего решил использовать Zyxel keenetic giga и 3G модем от МТС. Качество связи, её надёжность, задержки и т. д. конечно ужасные, но и речь идёт не о ближнем подмосковье. В принципе всё можно стерпеть, но хардварные зависания модема совсем добили. Если модем зависает, то всё что может помочь это сброс питания на шине USB. Теоретически это можно реализовать на том же C, но важно, чтобы аппаратная начинка это поддерживала.
В моём случае единственным вариантом было просто отправлять роутер Keenetic в рестарт. Для проверки работоспособности модема было решено написать код на C, который бы, используя libusb, помог послать в модем AT команды и проверить отвечает ли он. На данный подход меня вдохновило обсуждение на сайте Gentoo вот тут. Этот подход мог не требовал остановки процесса pppd, который лочил файл устройства модема /dev/ttyACM0. Однако, тут уже нужно было общаться с устройством не через его файл, а через usb endpoint.
Тестировать программу решил на Gentoo box amd64, а потом уже собрать под Keenetic, благо вот тут есть шикарная инструкция по этому поводу. Но как я ни старался, ничего хорошего не вышло. Подробности и код можно посмотреть здесь.
Однако, позже я узнал, что в данной аппаратной ревизии кинетика нет полноценной реализации USB, и мой план так и так был обречён на провал.
Поэтому пришлось пойти по другому пути - останавливать pppd процесс, который лочил файл устройства /dev/ttyACM0 и потом уже отсылать нужные команды. Собственно скрипт с комментариями, который получился у меня приведён ниже.
#!/bin/sh
#Vars init
addr=ya.ru #change to your another address you like
timestoping=50 #how many times we want to ping (remember 3G is very poor as a network connection :( )
pathtolog=/media/DISK_A1/system/root/mts_modem_log
logfile=`date +%y_%m_%d.log`
timestamp=`date +%H-%M-%S`
############################################
# Script checks MTS USB modem status
# If it hangs or stuck we need to reset power on usb port
# So have to do a reboot of the operating system
# Useful data saved in log files
############################################
#if log path doesn't exit, so create it
if [[ ! -d "$pathtolog" ]]
then
mkdir -p $pathtolog
fi
#First check if we have internet connection and are on-line now
packets=`ping -c ${timestoping} ${addr} | grep -o "\([0-9]\{1,\} packets received\)" | grep -o "\([0-9]\{1,\}\)"`
if [[ $packets -ge 1 ]]
then
echo -e "\n${timestamp}\nPing to ${addr} was ok, recivied ${packets}" >> $pathtolog/$logfile
#we recivied at least one packet! Cool, now we can exit, because everything is fine
exit 1
else
#Something went wrong and we did't get a reply from the external server
#have to do some additional checks
echo -e "\n${timestamp}\nThere were no responces from ${addr}, recivied zero packets" >> $pathtolog/$logfile
(pidof pppd) && (echo -e "Stopping pppd to unlock modem" >> $pathtolog/$logfile; /bin/sh /bin/pppd.sh disconnect) #if pppd is running, so stop it
sleep 10 #Wait 10 seconds for pppd daemon stops
#Send basic AT command to modem. If it's OK and didn't hang, so there is nothing left to do and we may start pppd and exit
echo "Sending AT to modem" >> $pathtolog/$logfile
echo "AT" > /dev/ttyACM0
if [[ `head -n 4 /dev/ttyACM0 | grep OK` ]]
then
echo -e "Recivied OK from modem\nTrying to raise pppd up again..." >> $pathtolog/$logfile
#we recivied an answer from our modem, so just raise up a pppd deamon again
/bin/sh /bin/pppd.sh connect
sleep 10 #wait for pppd daemon to be 100 percent sure it was started up successfully
#check for pppd is up, if it didn't, so modem hanging with "initializing..." glitch so reboot
(pidof pppd) || (echo "Couldn't start pppd, modem hanging up, rebooting" >> $pathtolog/$logfile; reboot)
else
#we are here now, so our modem state isn't satisfing, we have to reboot router
echo "Modem didn't answer AT command, rebooting..." >> $pathtolog/$logfile
reboot
fi
fi
Помещаем наш скрипт по адресу /media/DISK_A1/system/bin/modemcheck.sh, после чего даём права на исполнение ему
Далее устанавливаем выполнение скрипта по крону 1 раз в 15 минут.
#-----------------------MTS-3G-Modem-Check-------------------
*/15 * * * * /media/DISK_A1/system/bin/modemcheck.sh > /dev/null 2>&1
Теперь осталось добавить крон в автозапуск, если это ещё не было сделано