Сброс зависшего usb-модема (соединения) 3G/4G

Как выяснилось, зависания модема (или соединения) 3G/4G для версии прошивки 1 «не лечатся» встроенным софтом.

Казалось бы, всё просто - при наличии соединения пингуем какой-либо ресурс с заданной периодичностью и, не получив ответа (например, на два пинга), сбрасываем модем. Однако, это не реализовано разработчиками, хотя в настройках модема можно задать периодический пинг какого-то ресурса (в /bin/autoping.sh из полезного только ping, и ничего более).

Но можно собрать и использовать утилитку usbreset. А ещё проще - имеющуюся «на борту» утилиту usb_modeswitch, ведь в ней предусмотрен reset !

Итак, пишем командный файлик (назовём его usbmcc):

#!/bin/sh

# Vendor:Product for Huawei E392
VENDOR_ID=12d1
PRODUCT_ID=1506

# Ping resource & test
PING_RESOURCE=8.8.8.8
TEST_PING="`ping $PING_RESOURCE -c 2 | grep -o '0 packets received'`"

# Test ppp interface string
TEST_PPP="`ifconfig | grep -o ppp`"

if [ "$TEST_PPP" = "ppp" ]; then
	echo "ppp found"
	if [ "$TEST_PING" != "0 packets received" ]; then
		echo "ping resource $PING_RESOURCE - success"
	else
		echo "ping resource $PING_RESOURCE - unsuccess, reset modem.."
		/bin/usb_modeswitch -v $VENDOR_ID -p $PRODUCT_ID -R
		echo "...reset done, wait 3 minutes for ppp autorestart"
	fi
else
	echo "ppp not found"
fi

ID производителя и продукта (в примере - для Huawei E392) можно узнать при помощи утилиты lsusb, установить её можно так:

opkg install usbutils

Адрес 8.8.8.8 в примере - DNS от Google, но можно любой иной, в котором Вы уверены)

Разместим usbmcc в /media/DISK_A1/system/etc, разрешим выполнение

chmod 755 /media/DISK_A1/system/etc/usbmcc

и добавим задание для cron - /media/DISK_A1/system/etc/crontabs/root (не забудьте перезапустить cron)

*/5 * * * * /media/DISK_A1/system/etc/usbmcc

Выполнять usbmcc чаще, чем раз в 5 минут, не следует, поскольку от сброса модема до его автоматического рестарта проходит обычно 2-3 минуты, лучше задать с запасом, при этом в журнале (если выполнялся сброс) будут примерно такие записи:

20 авг 09:52:49	kernel	usb 1-1.4: reset high speed USB device using dwc_otg and address 30
20 авг 09:54:50	pppd[17825]	No response to 4 echo-requests
20 авг 09:54:50	pppd[17825]	Serial link appears to be disconnected.
20 авг 09:54:50	pppd[17825]	Connect time 1567.7 minutes.
20 авг 09:54:50	pppd[17825]	Sent 110186142 bytes, received 685790327 bytes.
20 авг 09:54:51	dnsmasq[15284]	started, version 2.55 cachesize 150
20 авг 09:54:51	dnsmasq[15284]	reading /etc/resolv.conf
20 авг 09:54:51	dnsmasq[15284]	using nameserver 8.8.4.4#53
20 авг 09:54:51	dnsmasq[15284]	using nameserver 8.8.8.8#53
20 авг 09:54:51	dnsmasq[15284]	read /etc/hosts - 2 addresses
20 авг 09:54:56	pppd[17825]	Connection terminated.
20 авг 09:54:56	pppd[17825]	Modem hangup
20 авг 09:54:56	pppd[17825]	Exit.
20 авг 09:55:01	pppd[15364]	pppd 2.4.4 started by root, uid 0
20 авг 09:55:02	pppd[15364]	Serial connection established.
20 авг 09:55:02	pppd[15364]	Using interface ppp0
20 авг 09:55:02	pppd[15364]	Connect: ppp0 <--> /dev/ttyUSB0
20 авг 09:55:03	pppd[15364]	CHAP authentication succeeded
20 авг 09:55:03	pppd[15364]	CHAP authentication succeeded
20 авг 09:55:03	pppd[15364]	Could not determine remote IP address: defaulting to 10.64.64.64
20 авг 09:55:03	pppd[15364]	local IP address 10.253.255.203
20 авг 09:55:03	pppd[15364]	remote IP address 10.64.64.64
20 авг 09:55:04	dnsmasq[15463]	started, version 2.55 cachesize 150
20 авг 09:55:04	dnsmasq[15463]	reading /etc/resolv.conf
20 авг 09:55:04	dnsmasq[15463]	using nameserver 8.8.4.4#53
20 авг 09:55:04	dnsmasq[15463]	using nameserver 8.8.8.8#53
20 авг 09:55:04	dnsmasq[15463]	using nameserver 8.8.4.4#53
20 авг 09:55:04	dnsmasq[15463]	using nameserver 8.8.8.8#53
20 авг 09:55:04	dnsmasq[15463]	read /etc/hosts - 2 addresses
...

Периодический пинг какого-то ресурса в настройках модема рекомендуется включить (например, тот же 8.8.8.8 каждые 60 секунд).

Однако, и на солнце есть пятна… Порой сервера Гугла не отвечают. Не беда, будем тестировать несколько серверов, для чего модифицируем созданный файл (заодно сделаем его немного «красивее»):

#!/bin/sh

# Vendor:Product for Huawei E392
VENDOR_ID=12d1
PRODUCT_ID=1506

# Ping resources & test packets
PING_RESOURCES="8.8.8.8 8.8.4.4 ya.ru"
TEST_PACKETS=2

# Test interface string
TEST_IFACE="ppp"
TEST_PPP="`ifconfig | grep -o $TEST_IFACE`"

# Temp file
TMP_FILE="/tmp/usbmcc.tmp"

if [ "$TEST_PPP" != "$TEST_IFACE" ]; then
	echo "interface $TEST_IFACE not found"
else
	echo "interface $TEST_IFACE found"
	# Initial success = unsuccess
	local success=0
	# Resources loop
	for resource in $PING_RESOURCES; do
		# Ping
		ping $resource -c $TEST_PACKETS > $TMP_FILE
		# Test for success
		echo "ping resource $resource..."
		if grep -q 'packets received,' $TMP_FILE; then
			if grep -q ', 0 packets received,' $TMP_FILE; then
				echo "...unsuccess, packets not received"
			else
				echo "...success"
				success=1
				break
			fi
		else
			echo "...unsuccess, ping packets not sent"
		fi
	done
	rm -f $TMP_FILE
	if [ $success -eq 0 ]; then
		echo "reset interface $TEST_IFACE equipment..."
		/bin/usb_modeswitch -v $VENDOR_ID -p $PRODUCT_ID -R
		echo "...reset done, wait 3 minutes for $TEST_IFACE autorestart"
	fi
fi

Теперь мы можем задать несколько серверов в PING_RESOURCES (в примере - два DNS от Гугла и поисковик Яндекса).

P.S. Эксперименты проводились на GIGA (первая версия), модем Huawei E392 (от МТС). Полномасштабное тестирование пока не закончено - могут быть глюки, просьба сообщать автору…

P.P.S. Для некоторых модемов сброс может не проходить и приводить к зависаниям модема и т.п. - такая информация найдена в сети.