summaryrefslogtreecommitdiff
path: root/recipes-core/multitech/config/chat_wrapper
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-core/multitech/config/chat_wrapper')
-rwxr-xr-xrecipes-core/multitech/config/chat_wrapper182
1 files changed, 158 insertions, 24 deletions
diff --git a/recipes-core/multitech/config/chat_wrapper b/recipes-core/multitech/config/chat_wrapper
index f1fd30c..b0bf9e5 100755
--- a/recipes-core/multitech/config/chat_wrapper
+++ b/recipes-core/multitech/config/chat_wrapper
@@ -18,30 +18,117 @@
# If there are not #MT AT+CGDCONT= lines, then any line without
# a comment chararacter before AT+CGDONT= is accepted, but only the
# last one in the file.
+#
+# On entry to this script, file descriptor 0 is the modem.
+# For ppp to work, stty must work on file descriptor 0.
+# If stty fails, so will ppp.
NAME=chat_wrapper
CONFIG=/etc/default/${NAME}
+CHAT_WRAPPER_RECURSION=/run/chat_wrapper_recursion
+
function finish
{
${LOG} "Launch:" "$@"
- exec "$@"
+ exec "$@"
# NOTREACHED
}
+# This function is used to determine if the modem and serial driver
+# are working. In testing, the driver has gotten into states where
+# stty fails. Before the chat script is started, the ioctl TCGETS is
+# performed, and will fail if the driver is hung. This same function
+# is called by stty. The modem port used by pppd is STDIN. Cases
+# have been observed on the H5 where radio-cmd works, but stty does
+# not, resulting in pppd failing. When this happens, radio-reset is
+# the best thing to try.
+function sanity
+{
+ if ! log=$(stty 2>&1) || ! [[ $(radio-cmd -t10000 'AT') =~ ^OK ]]; then
+ ${LOG} "Modem has issues, so see if we can try again"
+ ${LOG} "stty error: $(log)"
+ array=( )
+ # our parent is PPID, which is pppd. Get the pppd
+ # parameter list.
+ while IFS= read -r -d '' eparm; do
+ execarg+=( "$eparm" )
+ done < <(cat /proc/$PPID/cmdline)
+ i=0
+ ${LOG} "List parameters"
+ while ((i < ${#execarg[@]})) ; do
+ ${LOG} "$i: ${execarg[$i]}"
+ ((i++))
+ done
+ if [[ ${execarg[0]} == "pppd" ]] ; then
+ execarg[0]=/usr/sbin/pppd
+ fi
+
+ # Break any recursion loop.
+ if [[ -f ${CHAT_WRAPPER_RECURSION} ]] ; then
+ ${LOG} "Failure: modem is still unresponsive after reset"
+ rm -f ${CHAT_WRAPPER_RECURSION}
+ exit 1
+ fi
+ touch ${CHAT_WRAPPER_RECURSION}
+ ${LOG} "Bad TTY, possibly due to modem in bad state"
+ ${LOG} "Reset modem, and we relaunch pppd"
+ # Our terminal is the modem. When we reset the modem,
+ # we will be sent a SIGHUP. Ignore it (:).
+ trap : SIGHUP
+ /usr/sbin/mts-io-sysfs store radio-reset 0
+ sleep 5
+ count=0
+ while ((count < 60)) ; do
+ # Wait for radio-reset to get the modem responding
+ if [[ $(radio-cmd -t10000 'AT') =~ ^OK ]]; then
+ # parent is dying, so remove the pppd locks for the new pppd.
+ for f in /run/lock/LCK..modem_at0 /run/lock/LCK..modem_at1 ; do
+ if [[ -f $f ]] ; then
+ mypid=$(cat $f)
+ ${LOG} "PPID is $PPID, pid is $mypid"
+ # Remove the lock, if it belongs to our parent, pppd
+ if [ $mypid = $PPID ] ; then
+ ${LOG} "match $mypid $PPID"
+ sleep 60
+ rm -f $f
+ else
+ ${LOG} "mismatch |$mypid| |$PPID|"
+ fi
+ fi
+ done
+ # Locks gone, so start new pppd
+ nohup "${execarg[@]}" >/dev/null 2>&1 &
+ # Tell our parent we failed, which causes our pppd to terminate.
+ exit 1
+ else
+ sleep 5
+ fi
+ done
+ ${LOG} "ERROR: After five minutes the modem is still not ready"
+ exit 1
+ fi
+ return 0
+} # End of sanity function
+
+# If > 0, need to wait because we were not registered.
+WAITREG=0
+
[[ -f $CONFIG ]] || exit 1
. ${CONFIG}
: ${REGWAITTIME:=300}
: ${FINALWAIT:=5}
+: ${COPSWAIT:=10}
+: ${CFUNWAIT:=10}
: ${LOG:="/usr/bin/logger -t ${NAME} -p daemon.notice"}
${LOG} Timeout is $REGWAITTIME, execute "$@"
((i=$#))
chatscript="${!i}"
-${LOG} Parsing chat script "$chatscript"
+${LOG} Parsing chat script "$chatscript"
# CONTEXT is last context string in chat script
CONTEXT=$(egrep "^#MT[[:space:]]+(AT\+CGDCONT=.*)" ${chatscript} | tail -1)
if ((${#CONTEXT} == 0)) ; then
@@ -60,9 +147,25 @@ if ((${#CONTEXT} == 0)) ; then
fi
((CONTEXTNUM=${BASH_REMATCH[2]}))
+# Make sure CFUN=1, in case the last pppd was aborted with it set to 0.
+${LOG} "Verify CFUN=1"
+cfun=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+CFUN?')
+result1=$?
+if ((result1 != 0)) || ((${#cfun} == 0)) ; then
+ ${LOG} "Is modem in bad state -- \"CFUN?\" is broken?"
+ sanity
+ ((WAITREG++))
+fi
+if ! [[ $cfun =~ ^\+CFUN:\ 1[,[:space:]] ]] ; then
+ /usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+CFUN=1'
+ ${LOG} "Just set CFUN=1 so wait ${CFUNWAIT} seconds"
+ sleep ${CFUNWAIT}
+ ((WAITREG++))
+fi
${LOG} "Using Context ${CONTEXTNUM} based on chat script: ${CONTEXT}"
+
# At this point if there is no context number, we can skip everything else.
# Get Modem's context settings
@@ -137,7 +240,15 @@ if [[ $MPDP != $PDP ]] || [[ $MAPN != $APN ]] || \
${LOG} "$MCONTEXT"
${LOG} "Dropping registration with carrier to set context"
# Need to deregister
+ ((WAITREG++))
/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+COPS=2'
+
+ count=10
+ while ((count > 0)) && ! [[ $(/usr/bin/radio-query ${RADIOOPTION} --netreg) =~ ^NOT\ REGISTERED$ ]] ; do
+ sleep 2
+ ((count--))
+ done
+
# H5 radios do not like addresses that are empty with ""
if ((${#ADDR} == 0)) ; then
CMDSTR="AT+CGDCONT=${CONTEXTNUM},\"${PDP}\",\"${APN}\",,$DCOMP,${HCOMP}${FULLBOAT}"
@@ -154,7 +265,7 @@ if [[ $MPDP != $PDP ]] || [[ $MAPN != $APN ]] || \
((count--)) || true
LOGMSG=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 "${CMDSTR}" 2>&1)
result=$?
- ${LOG} "Result ${result}, Got response ${LOGMSG}"
+ ${LOG} "Setting context: Result ${result}, Got response ${LOGMSG}"
if [[ $LOGMSG =~ ERROR ]] ; then
result=1
fi
@@ -163,13 +274,16 @@ if [[ $MPDP != $PDP ]] || [[ $MAPN != $APN ]] || \
# re-enable the modem to defaults.
/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+COPS=0'
- sleep 1
# Some older modems will not re-register after the COPS
# command if you do not reset them using CFUN.
/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+CFUN=0'
+ ${LOG} "Set COPS=0, CFUN=1, so wait ${CFUNWAIT} seconds"
+ sleep ${CFUNWAIT}
/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+CFUN=1'
+ sleep ${CFUNWAIT}
+
# Abort PPP if the Context is not correct. We don't want
# to cause the carrier to disable the account by dialing
# out with a bad APN.
@@ -179,27 +293,47 @@ if [[ $MPDP != $PDP ]] || [[ $MAPN != $APN ]] || \
fi
sleep 1
${LOG} "New context is set. Wait up to $REGWAITTIME seconds to register"
- # Wait for registration
- uptime=$(cat /proc/uptime)
- [[ $uptime =~ ^([^\.]*) ]]
- t0=${BASH_REMATCH[1]}
- while ! [[ $(/usr/bin/radio-query ${RADIOOPTION} --netreg) =~ ^REGISTERED$ ]] ; do
- sleep 5
- uptime=$(cat /proc/uptime)
- [[ $uptime =~ ^([^\.]*) ]]
- t1=${BASH_REMATCH[1]}
- if ((t1-t0 > REGWAITTIME)) ; then
- ${LOG} "$((t1-t0)) seconds has expired"
- exit 1
- fi
- done
- uptime=$(cat /proc/uptime)
- [[ $uptime =~ ^([^\.]*) ]]
- t1=${BASH_REMATCH[1]}
- ${LOG} "Re-registered in $((t1-t0)) seconds -- wait ${FINALWAIT} more seconds"
- sleep $FINALWAIT
else
- ${LOG} "Context $CONTEXTNUM matches and nothing to do."
+ ${LOG} "Context $CONTEXTNUM matches verify COPS, then wait for registration."
+ # Check and set COPS and CFUN to be sure we were not interrupted at some point
+ # in the past.
+ cops=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+COPS?')
+ result0=$?
+
+ if ((result0 != 0)) || ! [[ $cops =~ ^\+COPS:\ 0, ]] ; then
+ /usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+COPS=0'
+ ((WAITREG++))
+ ${LOG} "Just set COPS=0 so wait ${COPSWAIT} seconds"
+ sleep ${COPSWAIT}
+ fi
+
+fi
+# Wait for registration
+uptime=$(cat /proc/uptime)
+[[ $uptime =~ ^([^\.]*) ]]
+t0=${BASH_REMATCH[1]}
+while ! [[ $(/usr/bin/radio-query ${RADIOOPTION} --netreg) =~ ^REGISTERED$ ]] ; do
+ sleep 5
+ ((WAITREG++))
+ uptime=$(cat /proc/uptime)
+ [[ $uptime =~ ^([^\.]*) ]]
+ t1=${BASH_REMATCH[1]}
+ if ((t1-t0 > REGWAITTIME)) ; then
+ ${LOG} "$((t1-t0)) seconds has expired without registration"
+ sanity
+ fi
+done
+uptime=$(cat /proc/uptime)
+[[ $uptime =~ ^([^\.]*) ]]
+t1=${BASH_REMATCH[1]}
+${LOG} "Re-registered in $((t1-t0)) seconds"
+if ((WAITREG > 0)) ; then
+ ${LOG} "Wait ${FINALWAIT} more seconds"
+ sleep $FINALWAIT
fi
+sanity
+
+rm -f ${CHAT_WRAPPER_RECURSION}
finish "$@"
+
# NOTREACHED