#!/bin/sh # SPDX-License-Identifier: MIT LANG=C PING_COUNT=2 FORCE_RECONNECT_PING_NG_COUNT=2 FORCE_REBOOT_PING_NG_COUNT=$((FORCE_RECONNECT_PING_NG_COUNT+2)) CONFIG_FILE_EXT=_connection-recover.conf NEW_CONFIG_FILE=/etc/atmark/connection-recover.conf OLD_CONFIG_FILE_DIR=/etc/atmark/connection-recover/ NMCLI_UP_TIMEOUT_SEC=150 RESTART_SIM_NOT_FOUND_COUNT=2 EX_FORCE_RECONNECT_PING_NG_COUNT=6 active_connection_exists() { if nmcli -f NAME connection | sed -e 's/ *$//' | grep -x -q "${CONNECTION}"; then return 0 fi return 1 } get_connection_status() { nmcli -f DEVICE,STATE device | grep "$DEVICE" } reconnect() { logger -t connection-recover "$DEVICE reconnect start... " nmcli connection down "${CONNECTION}" > /dev/null 2>&1 sleep 5 timeout -sKILL ${NMCLI_UP_TIMEOUT_SEC} nmcli connection up "${CONNECTION}" > /dev/null 2>&1 result=$? if [ ${result} -eq 0 ]; then logger -t connection-recover "$DEVICE reconnect success" else logger -t connection-recover "$DEVICE reconnect fail: ${result}" return 1 fi return 0 } is_connected() { if ping -s 1 -c "${PING_COUNT}" -I "${NETWORK_IF}" "${PING_DEST_IP}" > /dev/null 2>&1; then return 0 else logger -t connection-recover "$DEVICE ping fail" fi return 1 } clear_config() { PRODUCT_NAME="" CHECK_INTERVAL_SEC=120 PING_DEST_IP="" DEVICE="" TYPE="" NETWORK_IF="" WWAN_FORCE_RESTART_COUNT=10 REBOOT_IF_SIM_NOT_FOUND="" } set_default_config() { PRODUCT_NAME=$(cat /proc/device-tree/model) CHECK_INTERVAL_SEC=120 PING_DEST_IP="8.8.8.8" DEVICE="ttyCommModem" TYPE="gsm" if echo "$PRODUCT_NAME" | grep -q "A6E Cat.1 Board"; then NETWORK_IF="usb0" else NETWORK_IF="ppp0" fi FORCE_REBOOT=FALSE REBOOT_IF_SIM_NOT_FOUND=FALSE WWAN_FORCE_RESTART_COUNT=10 } read_config_file() { if [ ! -e "$CONFIG_FILE" ]; then return 1 fi . "${CONFIG_FILE}" if [ -z "$PING_DEST_IP" ]; then logger -t connection-recover "$CONFIG_FILE is PING_DEST_IP not set" exit 1 fi if [ -z "$FORCE_REBOOT" ]; then logger -t connection-recover "$CONFIG_FILE is FORCE_REBOOT not set" exit 1 fi if [ -z "$CHECK_INTERVAL_SEC" ]; then logger -t connection-recover "$CONFIG_FILE is CHECK_INTERVAL_SEC not set" exit 1 fi return 0 } read_old_config_file() { if [ ! -e "$CONFIG_FILE" ]; then return 1 fi . "${CONFIG_FILE}" local CHECK_PRODUCT_FLG=1 local IFS="," for CHECK_PRODUCT in $PRODUCT_NAME; do if grep "${CHECK_PRODUCT}" /proc/device-tree/model -q -w; then CHECK_PRODUCT_FLG=0 break fi done if [ ${CHECK_PRODUCT_FLG} -ne 0 ]; then return 1 fi if ! read_config_file; then exit 1 fi if [ -z "$DEVICE" ]; then logger -t connection-recover "$CONFIG_FILE is DEVICE not set" exit 1 fi if [ -z "$TYPE" ]; then logger -t connection-recover "$CONFIG_FILE is TYPE not set" exit 1 fi if [ -z "$NETWORK_IF" ]; then logger -t connection-recover "$CONFIG_FILE is NETWORK_IF not set" exit 1 fi return 0 } load_config() { local IFS=" " # use old conf file first if [ -d $OLD_CONFIG_FILE_DIR ]; then for CONFIG_FILE in "$OLD_CONFIG_FILE_DIR/"*"$CONFIG_FILE_EXT"; do clear_config if read_old_config_file; then return fi done fi set_default_config # use "/etc/atmark/connection-recover.conf" CONFIG_FILE=$NEW_CONFIG_FILE if read_config_file; then return fi set_default_config } load_config PING_NG_COUNT=0 SIM_NOT_FOUND_COUNT=0 WWAN_RESTART_COUNT=0 if [ -z "$WWAN_FORCE_RESTART_COUNT" ]; then WWAN_FORCE_RESTART_COUNT=1 fi while true; do sleep ${CHECK_INTERVAL_SEC} CONNECTION="${TYPE}-${DEVICE}" if active_connection_exists; then PING_STATUS=1 STATUS=$(get_connection_status) case ${STATUS} in *disconnected*|*failed*|*unknown*) # *failed* inclueded "connection failed" SIM_NOT_FOUND_COUNT=0 if reconnect; then continue fi ;; *connected*) SIM_NOT_FOUND_COUNT=0 is_connected PING_STATUS=$? if [ $PING_STATUS -ne 0 ]; then # if reboot or restart wwan, do not reconnect PING_NG_COUNT_TMP=$((PING_NG_COUNT+1)) if [ $PING_NG_COUNT_TMP -lt $EX_FORCE_RECONNECT_PING_NG_COUNT ]; then reconnect fi else WWAN_RESTART_COUNT=0 fi ;; *deactivating*|*unmanaged*|*connecting*) SIM_NOT_FOUND_COUNT=0 continue ;; *unavailable*|*) if [ "$REBOOT_IF_SIM_NOT_FOUND" != "TRUE" ] ; then continue fi SIM_NOT_FOUND_COUNT=$((SIM_NOT_FOUND_COUNT+1)) logger -t connection-recover "sim not found. status: ${STATUS}" if [ $SIM_NOT_FOUND_COUNT -ge $RESTART_SIM_NOT_FOUND_COUNT ] ; then logger -t connection-recover "exec system reboot cause sim not found" reboot fi esac if [ $PING_STATUS -ne 0 ]; then PING_NG_COUNT=$((PING_NG_COUNT+1)) if [ "$FORCE_REBOOT" = "TRUE" ]; then if [ $PING_NG_COUNT -ge $FORCE_REBOOT_PING_NG_COUNT ]; then logger -t connection-recover "exec system reboot" reboot fi fi if [ $PING_NG_COUNT -ge $FORCE_RECONNECT_PING_NG_COUNT ]; then WWAN_RESTART_COUNT=$((WWAN_RESTART_COUNT+1)) if [ $WWAN_RESTART_COUNT -ge $WWAN_FORCE_RESTART_COUNT ]; then logger -t connection-recover "exec wwan-force-restart" wwan-force-restart "$CONNECTION" WWAN_RESTART_COUNT=0 else logger -t connection-recover "exec wwan-restart" wwan-force-restart "$CONNECTION" airplane fi fi else PING_NG_COUNT=0 fi fi done