From 8ed2ca2d16b5eea56117c5502cb34c68125a1b1f Mon Sep 17 00:00:00 2001 From: David Bauer Date: Sat, 7 Oct 2023 22:29:06 +0200 Subject: [PATCH] uqmi: add PDP watchdog --- package/network/utils/uqmi/Makefile | 5 +- .../utils/uqmi/files/lib/netifd/proto/qmi.sh | 23 +++++++- .../utils/uqmi/files/lib/uqmi/qmi-watchdog.sh | 58 +++++++++++++++++++ 3 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 package/network/utils/uqmi/files/lib/uqmi/qmi-watchdog.sh diff --git a/package/network/utils/uqmi/Makefile b/package/network/utils/uqmi/Makefile index 26b588c7ef..e6b6ddfe6a 100644 --- a/package/network/utils/uqmi/Makefile +++ b/package/network/utils/uqmi/Makefile @@ -41,9 +41,10 @@ CMAKE_OPTIONS += \ -DDEBUG=1 define Package/uqmi/install - $(INSTALL_DIR) $(1)/sbin + $(INSTALL_DIR) $(1)/sbin $(1)/lib/uqmi $(1)/lib/netifd/proto $(INSTALL_BIN) $(PKG_BUILD_DIR)/uqmi $(1)/sbin/ - $(CP) ./files/* $(1)/ + $(INSTALL_BIN) ./files/lib/uqmi/qmi-watchdog.sh $(1)/lib/uqmi/qmi-watchdog.sh + $(CP) ./files/lib/netifd/proto/qmi.sh $(1)/lib/netifd/proto/qmi.sh endef $(eval $(call BuildPackage,uqmi)) diff --git a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh index f8e655455a..5ccf935b34 100755 --- a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh +++ b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh @@ -27,6 +27,9 @@ proto_qmi_init_config() { proto_config_add_int plmn proto_config_add_int timeout proto_config_add_int mtu + proto_config_add_boolean watchdog_enabled + proto_config_add_int watchdog_interval + proto_config_add_int watchdog_timeout proto_config_add_defaults } @@ -39,10 +42,12 @@ proto_qmi_setup() { local cid_4 pdh_4 cid_6 pdh_6 local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6 local profile_pdptype + local watchdog_enabled watchdog_interval watchdog_timeout json_get_vars device apn v6apn auth username password pincode delay modes json_get_vars pdptype profile v6profile dhcp dhcpv6 autoconnect plmn ip4table - json_get_vars ip6table timeout mtu $PROTO_DEFAULT_OPTIONS + json_get_vars ip6table timeout mtu + json_get_vars watchdog_enabled watchdog_interval watchdog_timeout $PROTO_DEFAULT_OPTIONS [ "$timeout" = "" ] && timeout="10" @@ -484,6 +489,22 @@ proto_qmi_setup() { ubus call network add_dynamic "$(json_dump)" fi } + + local cid_list + if [ -n "$cid_4" -a -n "$cid_6" ]; then + cid_list="$cid_4,$cid_6" + elif [ -n "$cid_4" ]; then + cid_list="$cid_4" + elif [ -n "$cid_6" ]; then + cid_list="$cid_6" + fi + + if [ -n "$watchdog_enabled" -a "$watchdog_enabled" != "0" ]; then + [ -z "$watchdog_interval" ] && watchdog_interval="60" + [ -z "$watchdog_timeout" ] && watchdog_timeout="5" + proto_run_command "$interface" /lib/uqmi/qmi-watchdog.sh "$device" "$watchdog_interval" \ + "$watchdog_timeout" "$cid_list" + fi } qmi_wds_stop() { diff --git a/package/network/utils/uqmi/files/lib/uqmi/qmi-watchdog.sh b/package/network/utils/uqmi/files/lib/uqmi/qmi-watchdog.sh new file mode 100644 index 0000000000..ee625cd457 --- /dev/null +++ b/package/network/utils/uqmi/files/lib/uqmi/qmi-watchdog.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh + +DEVICE_PATH=$1 +CHECK_INTERVAL=$2 +DISCONNECTED_TIMEOUT=$3 +CID_LIST=$4 + +while true; do + oldifs="$IFS" + IFS="," + for cid in $CID_LIST; do + IFS="$oldifs" + + # Reset for every CID + timeout_counter=0 + + while true; do + sleep "$CHECK_INTERVAL" + if [ "$timeout_counter" -gt "$DISCONNECTED_TIMEOUT" ]; then + echo "Data / Network connection error exceeds timeout - restart interface now" + return 1 + fi + + data_status="$(uqmi -t 1000 -s -d "$DEVICE_PATH" --set-client-id wds,$cid --get-data-status)" + registration_status=$(uqmi -s -d "$DEVICE_PATH" --get-serving-system 2>/dev/null | jsonfilter -e "@.registration" 2>/dev/null) + + json_init + json_load "$(uqmi -s -d "$DEVICE_PATH" --uim-get-sim-state)" + json_get_var card_application_state card_application_state + + if [ "$card_application_state" = "illegal" ]; then + # This does not recover. We don't have to wait out the timeout. + echo "SIM card in illegal state - restart interface now" + return 1 + elif [ -z "$card_application_state" ]; then + # No SIM Status. Either the next request succeeds or the SIM card + # potentially needs to be power-cycled + echo "Empty SIM card application status" + let timeout_counter++ + continue + elif [ "$data_status" != "\"connected\"" ]; then + # PDP context might recover in case autoconnect is enabled + # and still working. Give the modem a fair chance to recover. + echo "PDP context not connected for CID $cid" + let timeout_counter++ + continue + elif [ "$registration_status" != "registered" ]; then + # Sometimes Data status reports "connected" although + # we are not registered to a mobile network. + echo "No network registration" + let timeout_counter++ + continue + fi + done + done +done \ No newline at end of file -- 2.30.2