' sprint.sb
'
' This runs through the Over-The-Air Service Provisioning procedure
' for the Sprint network on a Sierra Wireless MC5725 CDMA module.
' Usage:
'
' bas sprint.sb
'
' The script automatically works out which ASY ports from the modemcc 0 asy_add and info_asy_add settings
' It also deactivates the PPP instance in case it's in use.
' Progress and final result is reported in the eventlog
' Progress is also logged to a RAM file called sstat.txt
' Web files sstat.asp and sstat1.asp are also generated to allow progress
' to be observed at the web interface
' the following line makes all string comparisons case insensitive
'
OPTION COMPARE sbCaseInsensitive
' set up the error handler
'
on error goto ErrorLabel
const nl = "\r\n"
' Enter an error message in the event log
' Also prints message to console output
' And appends the message to the web log file
'
function eventmsg(msg)
print #aspout, msg, nl
print msg, nl
junk = system("setevent \"" & msg & "\"" & " 0")
end function
' Appends the message to the web log file
'
function logmsg(msg)
print #aspout, msg, nl
end function
' Generate the log files for monitoring progress at the web interface
'
function init_log_files
local fh
fh = 0
open "sstat.asp" for output as fh
print #fh, "\r\n"
print #fh, "
\r\n"
print #fh, "\r\n"
print #fh, "\r\n"
print #fh, "\r\n"
close fh
aspout=0
open "sstat.txt" for output as aspout
end function
' Generate a final status message which can be displayed at the web interface
' This re-writes the top sstat1 frame page
function log_status(log_msg)
local fh
fh = 0
open "sstat1.asp" for output as fh
print #fh, "\r\n"
print #fh, "\r\n"
print #fh, "Sprint Provisioning Status\r\n"
print #fh, "\r\n"
print #fh, "\r\n"
print #fh, "\r\n"
print #fh, "\r\n"
print #fh, "\r\n"
print #fh, "
"
print #fh, "\r\n"
print #fh, "\r\n"
print #fh, "\r\n"
close fh
end function
' Enter an error message in the event log and exit
' Also prints message to console output
' And updates the web status page
'
function errexit(msg)
log_status(msg)
print #aspout, msg, nl
print msg, nl
junk = system("setevent \"" & msg & "\"" & " 6")
stop
end function
' Return the value of Sarian parameter in rsp
' strCmd needs to be of form " ?"
' e.g. "ppp 0 ans ?"
function getParam(strCmd,rsp)
local res, tmp, tmpPos, x, pos2
getParam = false
res = execute(strCmd, 0, tmp)
if res = true then
tmpPos = InStr(tmp, nl & "OK" & nl)
if tmpPos > 0 then
For x = tmpPos To 1 Step -1
pos2 = InStr(tmp, nl, x - 3)
If pos2 > 0 and pos2 <> tmpPos then
x = 1
endif
next x
if pos2 > 0 and pos2 <> tmpPos then
rsp = mid(tmp, pos2 + 2, tmpPos - pos2 - 2)
getParam = true
endif
endif
endif
end function
' find the first PPP instance configured for GPRS
' returns TRUE if we found one, and put the instance number into num
' otherwise returns FALSE
'
function get_gprs_ppp_instance(num)
local mdmstr, i
get_gprs_ppp_instance = false
for i = 0 to 4
if getParam("ppp " & i & " use_modem ?", mdmstr) = TRUE then
' print "PPP ", i, " use_modem = ", mdmstr, nl
if mdmstr = "1" or mdmstr = "4" or mdmstr = "5" then
get_gprs_ppp_instance = true
num = i
exit function
endif
else
print "Failed to get PPP ", i, " use_modem", nl
endif
next i
end function
' init_mc75io - opens a serial port and initialises a receive buffer for it
' Sets the following GLOBAL vars:
' mc75in - the input file handle
' mc75out - the output file handle
' mc75rxbuf - the receive buffer
' Parameter required is a GLOBAL variable mc75asyport, eg "ASY5"
'
function init_mc75io
' open the serial port used for the MC75
' two handles, one for input and one for output
mc75in = 0
open mc75asyport for input as mc75in
' if error() <> 0 then
' print "error opening asy port", nl
' endif
mc75out = 0
open mc75asyport for output as mc75out
mc75rxbuf = ""
junk = setevent(0)
junk = setevent(mc75in)
end function
' clear the receive buffer
'
function clear_mc75io
local junk, infobuf, tbuf
mx75rxbuf = ""
if waitevents(1000) = mc75in then
junk = sockinfo(mc75in, infobuf)
if infobuf[2] <> 0 then
tbuf = input(infobuf[2], mc75in)
endif
endif
end function
' gets a character from mc75in
' timeout is fixed at 10 secs for now
' Return TRUE if successful, otherwise FALSE
' If TRUE, then character is retuned in the rsp parameter
'
function getchar(rsp)
local tstart, junk
getchar = FALSE
tstart = ticks
while ticks-tstart < 1000
if len(mc75rxbuf) <> 0 then
rsp = left(mc75rxbuf, 1)
mc75rxbuf = mid(mc75rxbuf, 2)
getchar = TRUE
exit function
endif
junk = sockinfo(mc75in, sinfo)
' print "Bytes available = ", sinfo[2], nl
if sinfo[2] <> 0 then
' print "Reading ", sinfo[2], " Bytes", nl
mc75rxbuf = input(sinfo[2], mc75in)
' else
' sleep(1)
endif
wend
end function
' Get a line from mc75in
' Return TRUE if successful, otherwise FALSE
' If TRUE, then line is retuned in the rsp parameter
'
function getline(rsp)
local junk, sinfo, tbuf, tchr
getline = FALSE
tbuf = ""
while TRUE
if getchar(tchr) <> TRUE then exit function
' see if we received a LF (our end of line)
if asc(tchr) = 0x0a then
rsp = tbuf
getline = TRUE
exit function
endif
' ignore CR, append all other chars
if asc(tchr) <> 0x0d then
tbuf = tbuf & tchr
endif
wend
end function
function getOKline
local i, myline
getOKline = FALSE
for i = 1 to 10
if getline(myline) <> TRUE then exit function
if myline = "OK" then
getOKline = TRUE
exit function
endif
next i
end function
'
' Collect a number of lines into an array
' Stop at OK, ERROR or timeout
' return the number of lines received.
'
function getResplines(rsplines)
local nlines, i, myline
nlines = 0
getResplines = 0
for i = 1 to 10
if getline(myline) <> TRUE then exit function
rsplines[nlines] = myline
nlines += 1
getResplines = nlines
if (instr(myline, "OK") <> undef) or (instr(myline, "ERROR") <> undef) then
exit function
endif
next i
end function
' extract a line from an array obtained from getResplines
'
function extract_result(rsp_lines, nlines, search_str)
local i
extract_result = ""
for i = 0 to nlines-1
if instr(rsp_lines[i], search_str) <> undef then
extract_result = mid(rsp_lines[i], len(search_str)+1)
exit function
endif
next i
end function
' Close i/o handles and try to put the config back the way it was
' If using a TCP socket we only have one handle to close.
function restorecfg
local res, resstr
if socketopened = 0 then
close(mc75out)
endif
close(mc75in)
sleep(1)
res = execute("modemcc 0 asy_add " & asystr, 0, resstr)
res = execute("ppp " & gprs_ppp_instance & " use_modem 1", 0, resstr)
res = execute("ppp " & gprs_ppp_instance & " aodion on", 0, resstr)
end function
function get_modem_model
local i, nlines, rsplines
get_modem_model = ""
print #mc75out, "AT+GMM\r"
nlines = getResplines(rsplines)
if nlines = 0 then
eventmsg "No response to AT+GMM"
exit function
endif
if rsplines[nlines-1] <> "OK" then
eventmsg "AT+GMM did not return OK, got " & rsplines[nlines-1]
exit function
endif
' for i = 0 to nlines-1
' eventmsg "Got line: " & rsplines[i]
' next i
for i = 0 to nlines-1
if rsplines[i] <> "" AND rsplines[i] <> "AT+GMM" then
get_modem_model = rsplines[i]
exit function
endif
next i
end function
' ******** MAIN PROGRAM STARTS HERE ********
errcnt = 0
socketopened = 0
init_log_files()
eventmsg "Sprint activation started"
' Get the required parameters.
' First check the command line, as this can override the configured parameters
' Then check the provisioning config settings
'
split command() by " " to msl_str, mdn_str, min_str
if isundef(msl_str) or isundef(mdn_str) or isundef(min_str) then
if getParam("provision 0 string1 ?", msl_str) = TRUE then
if getParam("provision 0 string2 ?", mdn_str) = TRUE then
if getParam("provision 0 string3 ?", min_str) = TRUE then
else
errexit "failed to get min_str\r\n"
endif
else
errexit "failed to get mdn_str\r\n"
endif
else
errexit "failed to get msl_str\r\n"
endif
' print "\nUsage: sprint.sb \n"
' errexit "Sprint activation failed: missing parameters"
' exit sub
endif
print "msl_str=", msl_str, ", mdn_str=", mdn_str, ", min_str=", min_str, "\r\n"
' We allow the MSL to be omitted, but if it is present then the PTN and MSID must also be provided
'
if msl_str = "" then
eventmsg "MSL parameter not present: MDN and MSID will not be programmed "
else
if mdn_str = "" then
errexit "Sprint activation failed: missing PTN parameter"
endif
if min_str = "" then
errexit "Sprint activation failed: missing MSID parameter"
endif
endif
' Find out what ASY port is used by modemcc for GPRS
'
if getParam("modemcc 0 asy_add ?", asystr) = TRUE then
print "modemcc 0 asy_add is: ", asystr, nl
else
errexit "Sprint activation failed: unable to get modemcc 0 asy_add"
endif
if asystr = "255" or asystr = "0" or asystr = "" then
errexit "Sprint activation failed: invalid modemcc asy_add (try muxon)"
endif
' Find out which PPP instance is configured for GPRS
'
got_gprs_ppp = get_gprs_ppp_instance(gprs_ppp_instance)
if got_gprs_ppp then
print "PPP ", gprs_ppp_instance, " is configured for GPRS", nl
res = execute("ppp " & gprs_ppp_instance & " deact_rq", 0, resstr)
sleep(1)
res = execute("ppp " & gprs_ppp_instance & " use_modem !", 0, resstr)
res = execute("ppp " & gprs_ppp_instance & " aodion off", 0, resstr)
else
print "No PPP instances configured for GPRS", nl
endif
res = execute("modemoff", 0, resstr)
sleep(5)
res = execute("modemcc 0 asy_add 255", 0, resstr)
' initialise the AT serial port
AsyPortName = "ASY" & asystr
mc75asyport = AsyPortName
print "AsyPortName = ", AsyPortName, nl
init_mc75io()
' First make sure we can talk to the device by ATing it
' until we get OK back
'
i = 0
GotOK = false
while i < 10 and GotOK = false
i += 1
print "Sending AT...", nl
print #mc75out, "AT\r"
if getOKline() = true then GotOK = true
wend
if GotOK = false then
restorecfg()
errexit "Sprint activation failed: cannot AT device on " & AsyPortName
endif
' Now reconnect to the module via a TCP connection
' We need to do this because the Sprint provisioning process can generate
' large bursts of data (typical outout is 33Kbytes). The serial interface has
' a limited receive buffer size, whereas the TCP interface can handle this.
'
close(mc75in)
close(mc75out)
mc75in = 0
mc75port = 4000 + val(asystr)
open "127.0.0.1:" & mc75port for socket as mc75in
mc75out = mc75in
mc75rxbuf = ""
socketopened = 1
junk = setevent(0)
junk = setevent(mc75in)
eventmsg "Sprint: connected to modem on " & AsyPortName
modem_model = get_modem_model()
eventmsg "Modem model is: " & modem_model
reset_cmd = "AT!RESET"
iota_cmd = "AT!IOTASTART"
if left(modem_model, 6) = "MC5727" then
iota_cmd = "AT!DMDC=2"
endif
' only write the account activation data if it was supplied
'
if msl_str <> "" then
namlck_cmd = "AT~NAMLCK=" & msl_str
namval_cmd = "AT~NAMVAL=0," & mdn_str & "," & min_str & ",0,0"
namval0_cmd = "AT~NAMVAL=0"
' Enter the MSL to unlock the modem
'
eventmsg "Sent " & namlck_cmd
print #mc75out, namlck_cmd, "\r"
if getOKline() = false then
restorecfg()
errexit "Sprint activation failed: NAMLCK failed"
endif
' Enter phonenumber etc
'
eventmsg "Sent " & namval_cmd
print #mc75out, namval_cmd, "\r"
if getOKline() = false then
restorecfg()
errexit "Sprint activation failed: NAMVAL failed"
endif
' Set the NAM
'
eventmsg "Sent " & namval0_cmd
print #mc75out, namval0_cmd, "\r"
if getOKline() = false then
restorecfg()
errexit "Sprint activation failed: NAMVAL failed"
endif
' Send a reset
'
eventmsg "Sent " & reset_cmd
print #mc75out, reset_cmd, "\r"
if getOKline() = false then
restorecfg()
errexit "Sprint activation failed: RESET failed"
endif
' close the socket while we wait for a reset
'
close(mc75in)
socketopened = 0
eventmsg "Waiting 30 secs for modem reset"
sleep(30)
' now reopen the socket
'
mc75in = 0
open "127.0.0.1:" & mc75port for socket as mc75in
mc75out = mc75in
mc75rxbuf = ""
socketopened = 1
junk = setevent(0)
junk = setevent(mc75in)
'
' First AT the modem again
clear_mc75io()
i = 0
GotOK = false
while i < 10 and GotOK = false
i += 1
print "Sending AT...", nl
print #mc75out, "AT\r"
if getOKline() = true then GotOK = true
wend
if GotOK = false then
restorecfg()
errexit "Sprint activation failed: AT failed after RESET"
endif
endif
' now start up the IOTA session
'
eventmsg "Sent " & iota_cmd
print #mc75out, iota_cmd, "\r"
' set the end time. ticks are units of 10ms
' 5 mins normally
ticks_end = ticks + 5*60*100
' 15 secs for debugging
' ticks_end = ticks + 15*100
' now sit and wait for an OK response
' log all output received
'
iota_done = FALSE
while ticks <= ticks_end and iota_done = FALSE
if getline(iotaline) = TRUE then
logmsg iotaline
if iotaline = "ERROR" then
restorecfg()
errexit "Sprint activation failed: ERROR result received"
endif
if iotaline = "OK" then
iota_done = TRUE
endif
endif
wend
if iota_done = FALSE then
restorecfg()
errexit "Sprint activation failed: timeout awaiting OK result"
endif
' send a reset command. Don't worry about the reply as we'll be rebooting anyway
'
eventmsg "Sent AT!RESET"
print #mc75out, "AT!RESET\r"
' Restore the modem connection
'
restorecfg()
errexit "Sprint activation SUCCESSFUL"
stop
ErrorLabel:
'print "Got error code: ", error(), "(", error$, ")", nl
if error() = 22 and errcnt < 20 then
print "Retrying connection ...", nl
sleep(1)
errcnt = errcnt + 1
on error goto ErrorLabel
resume
endif
restorecfg()
errexit(error$)