diff options
Diffstat (limited to 'recipes-core/multitech/config/chat_wrapper')
-rwxr-xr-x | recipes-core/multitech/config/chat_wrapper | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/recipes-core/multitech/config/chat_wrapper b/recipes-core/multitech/config/chat_wrapper new file mode 100755 index 0000000..f1fd30c --- /dev/null +++ b/recipes-core/multitech/config/chat_wrapper @@ -0,0 +1,205 @@ +#!/bin/bash + +# Rules for chat scripts +# No comments allowed at the end of AT+CGDCONT in chat script +# The last AT+CGDCONT= must use the same context as the dialer. +# If desired, The AT+CGDCONT may be prefixed by #MT[[:space:]]+ +# Example: +#MT AT+CGDCONT="IPV6","data","192.168.2.1",0,1,"EXTRA" +# +# If you do not use a comment, the entire AT+CGDCONT command +# must be surrounded by apostrophes. This command will be executed +# twice, once in the chat wrapper, and a 2nd time in the chat +# itself. +# +# The space after "#MT" may be any number including tabs. +# If #MT AT+CGDCONT= is found, only the last one is chosen. +# Any uncommented AT+CGDCONT= is then ignored. +# 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. + +NAME=chat_wrapper +CONFIG=/etc/default/${NAME} +function finish +{ + ${LOG} "Launch:" "$@" + exec "$@" + # NOTREACHED +} + +[[ -f $CONFIG ]] || exit 1 + +. ${CONFIG} + +: ${REGWAITTIME:=300} +: ${FINALWAIT:=5} + +: ${LOG:="/usr/bin/logger -t ${NAME} -p daemon.notice"} + +${LOG} Timeout is $REGWAITTIME, execute "$@" +((i=$#)) +chatscript="${!i}" +${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 + CONTEXT=$(egrep "^[^#]+AT\+CGDCONT=" ${chatscript} | tail -1) + [[ $CONTEXT =~ \'(AT\+CGDCONT=([0-9]+)[^$\']+) ]] +else + [[ $CONTEXT =~ (AT\+CGDCONT=([0-9]+).*)$ ]] +fi + +# CONTEXTNUM is the context number that is configured in the dialer. +CONTEXT="${BASH_REMATCH[1]}" +if ((${#CONTEXT} == 0)) ; then + ${LOG} No context specifiction in the chat script + finish "$@" + # NOTREACHED +fi +((CONTEXTNUM=${BASH_REMATCH[2]})) + + +${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 +MCONTEXT=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+CGDCONT?' 2>&1 | tr -d '\r') +if [[ $MCONTEXT =~ [Ee][Rr][Rr][Oo][Rr] ]] ; then + RADIOOPTION="${RADIOOPTION2}" + MCONTEXT=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+CGDCONT?' 2>&1 | tr -d '\r') +fi + +if ! [[ $MCONTEXT =~ \+CGDCONT:[[:space:]]+${CONTEXTNUM},\"([^\"]*)\",\"([^\"]*)\",\"([^\"]*)\",([0-9]+),([0-9]+)([^$'\n']*) ]] ; then + logger -s -p daemon.error "No valid context in modem. Is it ready?" + echo "$MCONTEXT" | logger -s -p daemon.error +fi + +MPDP="${BASH_REMATCH[1]}" +MAPN="${BASH_REMATCH[2]}" +MADDR="${BASH_REMATCH[3]}" +MDCOMP="${BASH_REMATCH[4]}" +MHCOMP="${BASH_REMATCH[5]}" +MFULLBOAT="${BASH_REMATCH[6]}" + +[[ $CONTEXT =~ AT\+CGDCONT=${CONTEXTNUM},\"([^\"]*)\",\"([^\"]*)\"(,\"([^\"]*)\"(,([0-9]+)(,([0-9]+)(,[^\']*))*)*)* ]] +PDP="${BASH_REMATCH[1]}" +APN="${BASH_REMATCH[2]}" +ADDR="${BASH_REMATCH[4]}" # Optional +DCOMP="${BASH_REMATCH[6]}" # Optional +HCOMP="${BASH_REMATCH[8]}" # Optional +FULLBOAT="${BASH_REMATCH[9]}" # Optional + +# On some modems there are more parameters than others. +if [[ $MFULLBOAT != $FULLBOAT ]] ; then + ${LOG} "Only the first five context parameters are considered. The rest will be ignored." + ${LOG} "modem: \"$MFULLBOAT\"" + ${LOG} "chat script: \"$FULLBOAT\"" +fi + +if ((${#DCOMP} == 0)) ; then + ((DCOMP=0)) # Default +fi +if ((${#HCOMP} == 0)) ; then + ((HCOMP=0)) # Default +fi + +# Only update context on a mismatch between chat and modem. +if [[ $MPDP != $PDP ]] || [[ $MAPN != $APN ]] || \ + [[ $MADDR != $ADDR ]] || ((MDCOMP != DCOMP)) || \ + ((MHCOMP != HCOMP)) ; then + ${LOG} "Modem context $MPDP,$MAPN,$MADDR,$MDCOMP,$MHCOMP does not match chat script" + ${LOG} "Chat script context $PDP,$APN,$ADDR,$DCOMP,$HCOMP does not match the modem" + if [[ $MPDP != $PDP ]] ; then + ${LOG} "PDP mismatch" + fi + if [[ $MAPN != $APN ]] ; then + ${LOG} "APN mismatch" + fi + if [[ $MADDR != $ADDR ]] ; then + ${LOG} "ADDR mismatch" + fi + if [[ $MDCOMP != $DCOMP ]] ; then + ${LOG} "DCOMP mismatch" + fi + if [[ $MHCOMP != $HCOMP ]] ; then + ${LOG} "HCOMP mismatch" + fi + if [[ $MFULLBOAT != $FULLBOAT ]] ; then + ${LOG} "Final parameter mismatches ignored" + ${LOG} "Parameter 6 and up on the modem:" + ${LOG} "\"${MFULLBOAT}\"" + ${LOG} "Parameter 6 and up on the chat script:" + ${LOG} "\"${FULLBOAT}\"" + fi + ${LOG} "$MCONTEXT" + ${LOG} "Dropping registration with carrier to set context" + # Need to deregister + /usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+COPS=2' + # H5 radios do not like addresses that are empty with "" + if ((${#ADDR} == 0)) ; then + CMDSTR="AT+CGDCONT=${CONTEXTNUM},\"${PDP}\",\"${APN}\",,$DCOMP,${HCOMP}${FULLBOAT}" + else + CMDSTR="AT+CGDCONT=${CONTEXTNUM},\"${PDP}\",\"${APN}\",\"${ADDR}\",$DCOMP,${HCOMP}${FULLBOAT}" + fi + ${LOG} "Issued command /usr/bin/radio-cmd ${RADIOOPTION} -t10000 ..." + ${LOG} "... ${CMDSTR}" + + # If we fail to set the APN, sleep and try it again for up to 10 seconds. + result=1 + count=10 + while ((result != 0)) && ((count > 0)) ; do + ((count--)) || true + LOGMSG=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 "${CMDSTR}" 2>&1) + result=$? + ${LOG} "Result ${result}, Got response ${LOGMSG}" + if [[ $LOGMSG =~ ERROR ]] ; then + result=1 + fi + sleep 1 + done + + # 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' + /usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+CFUN=1' + + # 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. + if ((result != 0)) ; then + ${LOG} "AT+CGDCONT failed, aborting" + exit $result + 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." +fi +finish "$@" +# NOTREACHED |