diff options
Diffstat (limited to 'recipes-core')
-rwxr-xr-x | recipes-core/multitech/config/chat_wrapper | 258 |
1 files changed, 204 insertions, 54 deletions
diff --git a/recipes-core/multitech/config/chat_wrapper b/recipes-core/multitech/config/chat_wrapper index a693661..9aae971 100755 --- a/recipes-core/multitech/config/chat_wrapper +++ b/recipes-core/multitech/config/chat_wrapper @@ -22,7 +22,6 @@ # 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. -. /usr/libexec/ppp/wait_for_reset NAME=chat_wrapper CONFIG=/etc/default/${NAME} @@ -31,30 +30,7 @@ RQCMD="/usr/bin/radio-query ${RADIOOPTION}" : ${LOG:="/usr/bin/logger -t ${NAME} -p daemon.notice"} -function finish -{ - ${LOG} "Launch:" "$@" - 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 -{ - id="^[0-9][0-9][0-9][0-9][0-9][0-9]" - if ! log=$(stty 2>&1) || ! [[ $($RQCMD --iccid) =~ $id ]] ; then - ${LOG} "Modem has response issues, so see if we can try again" - if ((${#log} > 0)); then - ${LOG} "stty error: ${log}" - fi - array=( ) +function do_radio_reset { # our parent is PPID, which is pppd. Get the pppd # parameter list. while IFS= read -r -d '' eparm; do @@ -69,38 +45,30 @@ function sanity 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" - ${LOG} "Failure: Verify that modem and SIM are in place" - rm -f ${CHAT_WRAPPER_RECURSION} - exit 1 - fi - touch ${CHAT_WRAPPER_RECURSION} - ${LOG} "Bad TTY, possibly due to modem in bad state/no SIM detected" - ${LOG} "Reset modem, and we relaunch pppd" + # No returning from this function. pppd will be + # restarted by us. # 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 - wait_for_reset - ${LOG} "Completed wait_for_reset" + /usr/bin/mts-wait-for-cell-reset + ${LOG} "Completed mts-wait-for-cell-reset" count=0 while ((count < 60)) ; do + ((count++)) # Wait for radio-reset to get the modem responding - if [[ $(radio-cmd -t10000 'AT') =~ ^OK ]]; then + if [[ $(radio-cmd ${RADIOOPTION} -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) mypid="${mypid#"${mypid%%[![:space:]]*}"}" - mypid="${mypid%"${mypid##*[![:space:]]}"}" + mypid="${mypid%"${mypid##*[![:space:]]}"}" ${LOG} "PPID is $PPID, pid is $mypid" # Remove the lock, if it belongs to our parent, pppd + # or if it is empty. if ((${#mypid} == 0)) || [[ $mypid = $PPID ]] ; then ${LOG} "match $mypid $PPID" - sleep 60 rm -f $f else ${LOG} "mismatch |$mypid| |$PPID|" @@ -108,16 +76,181 @@ function sanity fi done # Locks gone, so start new pppd + ${LOG} "{$execarg[0]}" nohup "${execarg[@]}" >/dev/null 2>&1 & # Tell our parent we failed, which causes our pppd to terminate. exit 1 else - sleep 5 + sleep 1 fi done ${LOG} "ERROR: After five minutes the modem is still not ready" ${LOG} "ERROR: Verify that SIM is in place" exit 1 +} + + +function finish +{ + ${LOG} "Launch:" "$@" + exec "$@" + # NOTREACHED +} + +function set_telit_dataonly +{ + local result result1 mode cemode calldisa needreset + needreset=1 # 1 means no reset of cell modem (function exit status) + cemode=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+CEMODE?' 2>&1) + result=$? + if ((result == 0)) ; then + if [[ $cemode =~ CEMODE:[[:space:]]*([0-9]+) ]] ; then + mode=${BASH_REMATCH[1]} + if ((${#mode} > 0)) && ((mode != 2)) ; then + ${LOG} "Attempting to set CEMODE to 2" + cemode1=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 "AT+CEMODE=2" 2>&1) + result1=$? + needreset=0 + ${LOG} "radio-cmd AT+CEMODE=2 command yields $cemode1 with exit status $result1" + ${LOG} "Cellular modem will be reset after attmpted CEMODE change." + fi + else + ${LOG} "radio-cmd AT+CEMODE? command yields $cemode" + fi + else + ${LOG} "radio-cmd AT+CEMODE? command yields $cemode with exit status $result" + fi + + calldisa=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT#CALLDISA?' 2>&1) + result=$? + if ((result == 0)) ; then + if [[ $calldisa =~ CALLDISA:[[:space:]]*([0-9,]+) ]] ; then + mode=${BASH_REMATCH[1]} + if [[ ${mode} != 1,1 ]] ; then + ${LOG} "Attempting to set CALLDISA to 1,1" + cemode1=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 "AT#CALLDISA=1,1" 2>&1) + result1=$? + needreset=0 + ${LOG} "radio-cmd AT+CALLDISA=1,1 command yields $cemode1 with exit status $result1" + ${LOG} "Cellular modem must be reset after attmpted calldisa change." + fi + else + ${LOG} "radio-cmd AT+CALLDISA? command yields $calldisa" + fi + else + ${LOG} "radio-cmd AT+CALLDISA? command yields $calldisa with exit status $result" + fi + return $needreset +} + +function set_quectel_dataonly +{ + local result result1 ue ims sms vc needreset + needreset=1 # 1 means no reset of cell modem (function exit status) + ue=$(radio-cmd ${RADIOOPTION} -t10000 'AT+QNVFR="/nv/item_files/modem/mmode/ue_usage_setting"' 2>&1) + result=$? + if ((result == 0)) ; then + if [[ $ue =~ QNVFR:[[:space:]]*([0-9]+)[[:space:]]+ ]] ; then + if [[ ${BASH_REMATCH[1]} != 01 ]] ; then + ${LOG} "Attempting to set ue usage to 01" + ue=$(radio-cmd ${RADIOOPTION} -t10000 'AT+QNVFW="/nv/item_files/modem/mmode/ue_usage_setting",01' 2>&1) + result1=$? + needreset=0 + ${LOG} "write ue_usage_setting yields $ue with exit status $result1" + fi + else + ${LOG} "read ue_usage_setting yields $ue" + fi + else + ${LOG} "read ue_usage_setting yields $ue with exit status $result" + fi + + ims=$(radio-cmd ${RADIOOPTION} -t10000 'AT+QNVFR="/nv/item_files/ims/IMS_enable"' 2>&1) + result=$? + if ((result == 0)) ; then + if [[ $ims =~ QNVFR:[[:space:]]*([0-9]+)[[:space:]]+ ]] ; then + if [[ ${BASH_REMATCH[1]} != 00 ]] ; then + ${LOG} "Attempting to set IMS_enable to 00" + ims=$(radio-cmd ${RADIOOPTION} -t10000 'AT+QNVFW="/nv/item_files/ims/IMS_enable",00' 2>&1) + result1=$? + needreset=0 + ${LOG} "write IMS_enable yields $ims with exit status $result1" + fi + else + ${LOG} "read IMS_enable yields $ims" + fi + else + ${LOG} "read IMS_enable yields $ims with exit status $result" + fi + + vc=$(radio-cmd ${RADIOOPTION} -t10000 'AT+QNVR=5280,0' 2>&1) + result=$? + if ((result == 0)) ; then + if [[ $vc =~ QNVR:[[:space:]]\"*([0-9]+)\" ]] ; then + if [[ ${BASH_REMATCH[1]} != 0102000000000000 ]] ; then + ${LOG} "Attempting to set sms to 01" + vc=$(radio-cmd ${RADIOOPTION} -t10000 'AT+QNVW=5280,0,"0102000000000000"' 2>&1) + result1=$? + needreset=0 + ${LOG} "voice turn off yields $vc with exit status $result1" + fi + else + ${LOG} "read voice state yields $vc" + fi + else + ${LOG} "read voice state yields $vc with exit status $result" + fi + + sms=$(radio-cmd ${RADIOOPTION} -t10000 'AT+QNVFR="/nv/item_files/modem/mmode/sms_only"' 2>&1) + result=$? + if ((result == 0)) ; then + if [[ $sms =~ QNVFR:[[:space:]]\"*([0-9]+) ]] ; then + if [[ ${BASH_REMATCH[1]} != 01 ]] ; then + ${LOG} "Attempting to set sms to 01" + sms=$(radio-cmd ${RADIOOPTION} -t10000 'AT+QNVFW="/nv/item_files/modem/mmode/sms_only",01' 2>&1) + result1=$? + needreset=0 + ${LOG} "sms turn on yields $sms with exit status $result1" + fi + else + ${LOG} "read sms state yields $sms" + fi + else + ${LOG} "read sms state yields $sms with exit status $result" + fi + + return $needreset +} + +# 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 +{ + id="^[0-9][0-9][0-9][0-9][0-9][0-9]" + if ! log=$(stty 2>&1) || ! [[ $($RQCMD --iccid) =~ $id ]] ; then + ${LOG} "Modem has response issues, so see if we can try again" + if ((${#log} > 0)); then + ${LOG} "stty error: ${log}" + fi + + # Break any recursion loop. + if [[ -f ${CHAT_WRAPPER_RECURSION} ]] ; then + ${LOG} "Failure: modem is still unresponsive after reset" + ${LOG} "Failure: Verify that modem and SIM are in place" + rm -f ${CHAT_WRAPPER_RECURSION} + exit 1 + fi + touch ${CHAT_WRAPPER_RECURSION} + ${LOG} "Bad TTY, possibly due to modem in bad state/no SIM detected" + ${LOG} "Reset modem, and we relaunch pppd" + + do_radio_reset fi return 0 } # End of sanity function @@ -127,7 +260,7 @@ WAITREG=0 [[ -f $CONFIG ]] || exit 1 -. ${CONFIG} +. ${CONFIG} : ${REGWAITTIME:=300} : ${FINALWAIT:=5} @@ -139,7 +272,7 @@ ${LOG} Timeout is $REGWAITTIME, execute "$@" # Wait for udev to discover modem has been reset. -wait_for_reset +/usr/bin/mts-wait-for-cell-reset ((i=$#)) chatscript="${!i}" @@ -172,12 +305,30 @@ if ((result1 != 0)) || ((${#cfun} == 0)) ; then sanity ((WAITREG++)) fi +# Must have a readable SIM in order to set DATA Mode +if ((SETATTDATAMODE == 1)) ; then + CARRIER=$($RQCMD --carrier 2>&1) + if [[ $CARRIER =~ ^AT\&T[[:space:]]+Wireless ]] ; then + MODEL=$($RQCMD --model 2>&1) + ${LOG} "Cellular modem is $MODEL" + if [[ ${MODEL} == EG25 ]] || [[ ${MODEL} == EG95 ]] ; then + if set_quectel_dataonly ; then + do_radio_reset + fi + else # Could be a problem when we add new Quectel models + if set_telit_dataonly ; then + do_radio_reset + fi + fi + fi +fi # Set ATT Data Mode + 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 +fi # Set CFUN=1 ${LOG} "Using Context ${CONTEXTNUM} based on chat script: ${CONTEXT}" @@ -192,11 +343,11 @@ if [[ $MCONTEXT =~ ^[Ee][Rr][Rr][Oo][Rr] ]] ; then MCONTEXT=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+CGDCONT?' 2>&1 | tr -d '\r') CRESULT=$? 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 - echo "Result is $CRESULT" | logger -s -p daemon.error + echo "Result is $CRESULT" | logger -s -p daemon.error if [[ $MCONTEXT =~ ^[Ee][Rr][Rr][Oo][Rr] ]] ; then logger -s -p daemon.error "Context query response error. Diagnose ..." sanity @@ -243,7 +394,7 @@ if [[ $MADDR != $ADDR ]] ; then ADDRMATCH=1 fi fi -fi +fi # Only update context on a mismatch between chat and modem. if [[ $MPDP != $PDP ]] || [[ $MAPN != $APN ]] || \ @@ -284,9 +435,9 @@ if [[ $MPDP != $PDP ]] || [[ $MAPN != $APN ]] || \ count=10 while ((count > 0)) && ! [[ $($RQCMD --netreg) =~ ^NOT\ REGISTERED$ ]] ; do sleep 2 - ((count--)) + ((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}" @@ -299,7 +450,7 @@ if [[ $MPDP != $PDP ]] || [[ $MAPN != $APN ]] || \ # 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 + while ((result != 0)) && ((count > 0)) ; do ((count--)) || true LOGMSG=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 "${CMDSTR}" 2>&1) result=$? @@ -338,10 +489,9 @@ else cops=$(/usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+COPS?') result0=$? - if ((result0 != 0)) || ! [[ $cops =~ ^\+COPS:[[:space:]]0[,[:space:]] ]] ; then + if ((result0 != 0)) || ! [[ $cops =~ ^\+COPS:\ 0, ]] ; then /usr/bin/radio-cmd ${RADIOOPTION} -t10000 'AT+COPS=0' ((WAITREG++)) - ${LOG} "Cops status was $cops" ${LOG} "Just set COPS=0 so wait ${COPSWAIT} seconds" sleep ${COPSWAIT} fi @@ -360,7 +510,7 @@ while ! [[ $($RQCMD --netreg) =~ ^(REGISTERED|ROAMING)$ ]] ; do if ((t1-t0 > REGWAITTIME)) ; then ${LOG} "$((t1-t0)) seconds has expired without registration" sanity - fi + fi done uptime=$(cat /proc/uptime) [[ $uptime =~ ^([^\.]*) ]] |