PHP Code:
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
MAX_PACKET_SIZE = $5C0 '1472 '$800 = 2048
RxTx_BUFFER = $800 '$600 = 1536
TEMP_BUFFER = $600 '$5B4 = 1460
TCP_PROTOCOL = %0001 '$300 = 768
UDP_PROTOCOL = %0010 '$200 = 512
TCP_CONNECT = $04 '$100 = 256
DELAY = $05
#1, ErrorConnect, ErrorVersion, ErrorChecksum, ErrorProgram, ErrorVerify
#0, Shutdown, LoadRun, ProgramShutdown, ProgramRun
#0, DONE, PUT, CD
DAT
mac byte $00, $08, $DC, $16, $F2, $06
subnet byte 255, 255 ,255, 0
ip byte 192, 168, 0, 120
gateway byte 192, 168, 0, 1
port word 5000
uport word 5050
remoteIp byte 72, 222, 244, 139
remotePort word 80
emailIp byte 0, 0, 0, 0
emailPort word 25
status byte $00, $00, $00, $00
rxdata byte $0[RxTx_BUFFER]
txdata byte $0[RxTx_BUFFER]
udpdata byte $0[TEMP_BUFFER]
fileErrorHandle long $0
debug byte $0
lastFile byte $0[12], 0
closedState byte %0000
openState byte %0000
listenState byte %0000
establishedState byte %0000
closingState byte %0000
closeWaitState byte %0000
lastEstblState byte %0000
lastEstblStateDebug byte %0000
udpListen byte %0000
tcpMask byte %0111
udpMask byte %1000
fifoSocketDepth byte $0
fifoSocket long $00_00_00_00
debugSemId byte $00
debugCounter long $00
stringMethods long $00
closingTimeout long $00, $00, $00, $00
udpLen long $00
time byte "00/00/0000 00:00:00", 0
httpDate byte "Wed, 01 Feb 2000 01:00:00 GMT", 0
globalCache byte $0
VAR
long StackSpace[20]
long P31, P30, LFSR, Ver, Echo
OBJ
Socket : "W5100_Indirect_Driver"
pst : "Parallax Serial Terminal"
SDCard : "SD2.0_FATWrapper"
Request : "Request"
Response : "Response"
str : "StringMethods"
rtc : "S35390A_RTCEngine"
PUB Initialize | id, size, st
debug := 1
SDCard.Start
stringMethods := str.Start
Request.Constructor(stringMethods)
Response.Constructor(stringMethods, @txdata)
pst.Start(115_200)
pause(200)
'Mount the SD card
pst.str(string("Mount SD Card - "))
SDCard.mount(fileErrorHandle)
pst.str(string("OK",13))
pst.str(string("Start RTC: "))
rtc.RTCEngineStart(29, 28, -1)
pause(200)
pst.str(FillTime)
'Start the W5100 driver
if(Socket.Start)
pst.str(string(13, "W5100 Driver Started", 13))
pst.str(string(13, "Status Memory Lock ID : "))
pst.dec(Socket.GetLockId)
pst.char(13)
if(debugSemId := locknew) == -1
pst.str(string("Error, no HTTP server locks available", 13))
else
pst.str(string("HTTP Server Lock ID : "))
pst.dec(debugSemId)
pst.char(13)
'Set the Socket addresses
SetMac(@mac)
SetGateway(@gateway)
SetSubnet(@subnet)
SetIP(@ip)
' Initailize TCP sockets (defalut setting; TCP, Port, remote ip and remote port)
repeat id from 0 to 3
InitializeSocket(id)
Request.Release(id)
pause(50)
' Set all TCP sockets to listen
pst.char(13)
repeat id from 0 to 3
Socket.Listen(id)
pst.str(string("TCP Socket Listener ID : "))
pst.dec(id)
pst.char(13)
pause(50)
' Initialize UDP socket(s)
{
id := 3
InitializeUPDSocket(id)
pause(50)
pst.str(string("UDP Socket Listener ID : "))
pst.dec(id)
pst.char(13)
}
pst.Str(string(13,"Started Socket Monitoring Service", 13))
cognew(StatusMonitor, @StackSpace)
pause(250)
pst.Str(string(13, "Initial Socket States",13))
StackDump
pst.Str(string(13, "Initial Socket Queue",13))
QueueDump
Main
PUB Main | packetSize, id, i, reset, j, temp
'HTTP server service
'GetMyIp(0)
'SendTestEmail(0)
pst.str(string(13,"//////////////////////////////////////////////////////////////",13))
repeat
repeat until fifoSocket == 0
bytefill(@rxdata, 0, RxTx_BUFFER)
if(debug)
pst.str(string(13, "----- Start of Request----------------------------",13))
'QueueDump
pause(DELAY)
else
pause(DELAY)
' Pop the next socket handle
id := DequeueSocket
if(id < 0)
next
if(debug)
pst.str(string(13,"ID: "))
pst.dec(id)
pst.str(string(13, "Request Count : "))
pst.dec(debugCounter)
pst.char(13)
'StackDump
packetSize := Socket.rxTCP(id, @rxdata)
'if(debug)
'pst.str(string(13, "packetSize : "))
'pst.dec(packetSize)
'pst.str(string(13, "strsize(@rxdata) : "))
'pst.dec(strsize(@rxdata))
'else
'pause(DELAY)
reset := false
if ((packetSize < 12) AND (strsize(@rxdata) < 12))
repeat i from 0 to 5
'Wait for a few moments and try again
waitcnt((clkfreq/500) + cnt)
packetSize := Socket.rxTCP(id, @rxdata)
'if(debug)
'pst.str(string("retry["))
'pst.dec(i)
'pst.str(string("]: "))
'pst.dec(packetSize)
'pst.char(13)
' pause(100)
if(packetSize > 12)
quit
if(i == 10)
'Clean up resource request
Request.Release(id)
Socket.Close(id)
reset := true
if(debug)
pst.str(string(13,"* Read Failure *",13))
if(reset)
next
Request.InitializeRequest(id, @rxdata)
{
if(debug)
pst.str(string("Content-Length : "))
pst.dec(Request.GetContentLength(id))
pst.char(13)
}
{
if(debug)
pst.str(string("QueryString: "))
pst.str(Request.GetQueryString(id))
pst.char(13)
}
if(debug)
pst.char(13)
HeaderLine1(id)
'toString(id)
else
pause(DELAY)
' Process router
Dispatcher(id)
'Clean up request resource
Request.Release(id)
' This starts the close process -> 0x00
' use close to force a close
Socket.Disconnect(id)
bytefill(@txdata, 0, RxTx_BUFFER)
if(debug)
'StackDump
'pst.char(13)
'QueueDump
pause(DELAY)
else
pause(DELAY)
debugCounter++
GotoMain
PRI GotoMain
Main
PRI QueueDump
pst.str(string("FIFO["))
pst.dec(fifoSocketDepth)
pst.str(string("] "))
pst.hex(fifoSocket, 8)
PRI StackDump | clsd, open, lstn, estb, clwt, clng, id, ulst
repeat until not lockset(debugSemId)
clsd := closedState
open := openState
lstn := listenState
estb := establishedState
clwt := closeWaitState
clng := closingState
ulst := udpListen
lockclr(debugSemId)
pst.char(13)
repeat id from 3 to 0
pst.dec(id)
pst.str(string("-"))
pst.hex(status[id], 2)
pst.str(string(" "))
pause(1)
pst.str(string(13,"clsd open lstn estb clwt clng udps", 13))
pst.bin(clsd, 4)
pst.str(string("-"))
pst.bin(open, 4)
pst.str(string("-"))
pst.bin(lstn, 4)
pst.str(string("-"))
pst.bin(estb, 4)
pst.str(string("-"))
pst.bin(clwt, 4)
pst.str(string("-"))
pst.bin(clng, 4)
pst.str(string("-"))
pst.bin(ulst, 4)
pst.char(13)
PRI StatusMonitor | id, tmp, value
repeat
Socket.GetStatus32(@status[0])
' Encode status register states
repeat until not lockset(debugSemId)
closedState := openState := listenState := establishedState := {
} closeWaitState := closingState := 0
repeat id from 0 to 3
case(status[id])
$00: closedState |= |< id
closedState &= tcpMask
$13: openState |= |< id
openState &= tcpMask
$14: listenState |= |< id
listenState &= tcpMask
$17: establishedState |= |< id
establishedState &= tcpMask
$18,$1A,$1B: closingState |= |< id
closingState &= tcpMask
$1C: closeWaitState |= |< id
closeWaitState &= tcpMask
$1D: closingState |= |< id
closingState &= tcpMask
$22: udpListen |= |< id
udpListen &= udpMask
if(lastEstblState <> establishedState)
value := establishedState
repeat while value > 0
tmp := DecodeId(value)
if(tmp > -1)
QueueSocket(tmp)
tmp := |< tmp
tmp := !tmp
value &= tmp
lastEstblState := establishedState
lockclr(debugSemId)
' Initialize a closed socket
if(closedState > 0)
id := DecodeId(closedState)
if(id > -1)
InitializeSocket(id & tcpMask)
'Start a listener on an initialized/open socket
if(openState > 0)
id := DecodeId(openState)
if(id > -1)
Socket.Listen(id & tcpMask)
' Close the socket if the status is close/wait
' response processor should close the socket with disconnect
' there could be a timeout so we have a forced close.
' TODO: CCheck for a port that gets stuck in a closing state
'if(closeWaitState > 0)
'id := DecodeId(closeWaitState)
'if(id > -1)
'Socket.Close(id & tcpMask)
'pause(100)
return
PRI GetTcpSocketMask(id)
return id & tcpMask
PRI DecodeId(value) | tmp
if(%0001 & value)
return 0
if(%0010 & value)
return 1
if(%0100 & value)
return 2
if(%1000 & value)
return 3
return -1
PRI QueueSocket(id) | tmp
if(fifoSocketDepth > 4)
return false
tmp := |< id
'Unique check
ifnot(IsUnique(tmp))
return false
tmp <<= (fifoSocketDepth++) * 8
fifoSocket |= tmp
return true
PRI IsUnique(encodedId) | tmp
tmp := encodedId & $0F
repeat 4
if(encodedId & fifoSocket)
return false
encodedId <<= 8
return true
PRI DequeueSocket | tmp
if(fifoSocketDepth == 0)
return -2
repeat until not lockset(debugSemId)
tmp := fifoSocket & $0F
fifoSocket >>= 8
fifoSocketDepth--
lockclr(debugSemId)
return DecodeId(tmp)
PRI ResetSocket(id)
Socket.Disconnect(id)
Socket.Close(id)
PRI ChangeDirectory(id) | i, found
'Return if the directory is not found
ifnot(FileExists(Request.GetPathNode(id, i)))
return false
'Handle directory structure for this Request
if(Request.GetDepth(id) > 1)
repeat i from 0 to Request.GetDepth(id)-2
found := SDCard.changeDirectory(Request.GetPathNode(id, i))
return true
PRI FileExists(fileToCompare) | filenamePtr
'Start file find at the top of the list
SDCard.startFindFile
'Verify that the file exists
filenamePtr := SDCard.nextFile
repeat while filenamePtr <> 0
filenamePtr := SDCard.nextFile
if(str.MatchPattern(filenamePtr, fileToCompare, 0, false ) == 0 )
return true
return false
PRI StaticFileHandler(id) | fileSize, i, headerLen, temp, j
'pst.str(string(13,"Static File Handler",13))
SDCard.changeDirectory(@approot)
'pst.char(13)
'Make sure the directory exists
ifnot(ChangeDirectory(id))
'send 404 error
WriteError(id)
SDCard.changeDirectory(@approot)
return
' Make sure the file exists
ifnot(FileExists(Request.GetFileName(id)))
'send 404 error
WriteError(id)
SDCard.changeDirectory(@approot)
return
' Open the file for reading
SDCard.openFile(Request.GetFileName(id), "r")
fileSize := SDCard.getFileSize
'WriteResponseHeader(id)
'BuildHeader(extension, statusCode, expirer)
headerLen := Response.BuildHeader(Request.GetExtension(id), 200, false)
Socket.txTCP(id, @txdata, headerLen)
if fileSize < MAX_PACKET_SIZE
' send the file in one packet
SDCard.readFromFile(@txdata, fileSize)
Socket.txTCP(id, @txdata, fileSize)
else
' send the file in a bunch of packets
repeat
SDCard.readFromFile(@txdata, MAX_PACKET_SIZE)
Socket.txTCP(id, @txdata, MAX_PACKET_SIZE)
fileSize -= MAX_PACKET_SIZE
' once the remaining fileSize is less then the max packet size, just send that remaining bit and quit the loop
if fileSize < MAX_PACKET_SIZE and fileSize > 0
SDCard.readFromFile(@txdata, fileSize)
Socket.txTCP(id, @txdata, fileSize)
quit
' Bailout
if(i++ > 1_000_000)
WriteError(id)
quit
SDCard.closeFile
SDCard.changeDirectory(@approot)
return
PUB WriteError(id) | headerOffset
pst.str(string(13, "Write 404 Error",13 ))
headerOffset := Response.BuildHeader(Request.GetExtension(id), 404, false)
Socket.txTCP(id, @txdata, headerOffset)
return
PUB SetTcpSocketMaskById(id, state) | tmp
tmp := |< id
if(state == 1)
tcpMask |= tmp
else
tmp := !tmp
tcpMask &= tmp
PUB IsolateTcpSocketById(id) | tmp
tmp := |< id
tcpMask &= tmp
PUB GetCommandRegisterAddress(id)
return Socket#_S0_CR + (id * $0100)
PUB GetStatusRegisterAddress(id)
return Socket#_S0_SR + (id * $0100)
PRI SetMac(_firstOctet)
Socket.WriteMACaddress(true, _firstOctet)
return
PRI SetGateway(_firstOctet)
Socket.WriteGatewayAddress(true, _firstOctet)
return
PRI SetSubnet(_firstOctet)
Socket.WriteSubnetMask(true, _firstOctet)
return
PRI SetIP(_firstOctet)
Socket.WriteIPAddress(true, _firstOctet)
return
PRI StringSend(id, _dataPtr)
Socket.txTCP(id, _dataPtr, strsize(_dataPtr))
return
PRI SendChar(id, _dataPtr)
Socket.txTCP(id, _dataPtr, 1)
return
PRI SendChars(id, _dataPtr, _length)
Socket.txTCP(id, _dataPtr, _length)
return
PRI InitializeSocket(id)
Socket.Initialize(id, TCP_PROTOCOL, port, remotePort, @remoteIp)
return
PRI InitializeSocketForEmail(id)
Socket.Initialize(id, TCP_PROTOCOL, port, emailPort, @emailIp)
return
PRI InitializeUPDSocket(id)
Socket.Initialize(id, UDP_PROTOCOL, uport, remotePort, @remoteIp)
return
PRI HeaderLine1(id) | i
pst.str(Request.GetMethod(id))
pst.char($20)
i := 0
repeat Request.GetDepth(id)
pst.char($2F)
pst.str(Request.GetPathNode(id, i++))
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'Chance to do some processing before sending the response
PRI Dispatcher(id)
{ }
'if(strcomp(Request.GetName(id), string("index")))
'Index(id)
if(strcomp(Request.GetName(id), string("post")))
Post(id)
if(strcomp(Request.GetName(id), string("upload")))
Upload(id)
if(strcomp(Request.GetName(id), string("ajax")))
Ajax(id)
if(strcomp(Request.GetName(id), string("getdir")))
GetDir(id)
return
if(strcomp(Request.GetName(id), string("gettime")))
GetTime(id)
return
if(strcomp(Request.GetName(id), string("upsite")))
UploadSite(id)
return
StaticFileHandler(id)
return
{ }
PRI Index(id)
pst.str(string(13, "Index Processor", 13))
pst.str(string("led := "))
pst.str(Request.Get(id, string("led")))
pst.char(13)
pst.str(string("this := "))
pst.str(Request.Get(id, string("this")))
pst.char(13)
return
{ }
PRI Post(id)
pst.str(string(13, "**************************", 13))
pst.str(@rxdata)
pst.str(string(13, "**************************", 13))
return
{
'tempMask := tcpMask
'IsolateTcpSocketById(id)
}
PRI Upload(id) | tempMask, strt, end, rxBytes, bodyPtr, bytesRead, i, packetSize, j, dataS, dataE, bodySize, bodyE, temp
AppendLog(@rxdata)
bytefill(@boundary1, 0, 64)
i := 0
j := 0
dataE := 0
bytesRead := 0
ifnot(strcomp(Request.GetMethod(id), String("POST")))
return
'pst.str(string(13, "Content Length: "))
rxBytes := Request.GetContentLength(id)
'pst.dec(rxBytes)
'pst.char(13)
'pst.str(string(13, "@rxdata Length: "))
'pst.dec(strsize(@rxdata))
'pst.char(13)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Content-Type: multipart/form-data; boundary=
'Get the mutlipart boundary
'pst.str(string(13, "Get start of boundary= "))
strt := str.MatchPattern(@rxdata, @multipart, 0, false)
strt += strsize(@multipart)
'pst.hex(strt, 4)
'pst.str(string(13, "End of boundary= ") )
end := str.MatchPattern(@rxdata, @crlf, strt, true)
'pst.hex(end, 4)
'pst.str(string(13, "Buffer boundary") )
bytemove(@boundary1, @rxdata+strt, end-strt)
'pst.str(string(13, "Boundary: "))
'pst.str(@boundary)
'pst.str(string(13, "Boundary Len: "))
'pst.dec(strsize(@boundary))
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Find the body and see if we need to grab more stream data
'pst.str(string(13, "Find body data: "))
strt := str.MatchPattern(@rxdata, @crlf_crlf, 0, true)
bodyPtr := strt + strsize(@crlf_crlf)
'pst.hex(bodyPtr, 4)
'pst.str(string(13, "Body length: "))
bodySize := strsize(@rxdata)-bodyPtr
'pst.dec(bodySize)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Get the filename being uploaded
'pst.str(string(13, "Find the start of filename"))
'Find filename="upload.txt"
strt := str.MatchPattern(@rxdata, @fn, strt, false)
if(strt == -1)
'pst.str(string(13, "Filename not found!"))
'Try to handle MAC POST
pause(200)
packetSize := Socket.rxTCP(id, @rxdata)
strt := str.MatchPattern(@rxdata, @fn, strt, false)
if(strt == -1)
return
'pst.str(string(13,"filename pointer: "))
'pst.hex(strt, 4)
'Point to the first letter after the double quote
strt += strsize(@fn) + 1
'pst.str(string(13, "Find the end of filename"))
'Find the ending double quote = $22
end := str.MatchPattern(@rxdata, @doublequote, strt, true)
'pst.str(string(13,"End filename pointer: "))
pst.hex(end, 4)
if(end-strt > 12)
'pst.str(string(13, "File name is longer than 12 chars"))
return
'pst.str(string(13, "Write file name to buffer"))
Set(@uploadfile, strt+@rxdata, end-strt)
'pst.str(string(13, "filename: "))
'pst.str(@uploadfile)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Drill into the first boundary to get the file content
'@crlf_crlf should be after the file name in the header
'pst.str(string(13, "Find file data start: "))
strt := str.MatchPattern(@rxdata, @crlf_crlf, end, true)
if(strt == -1)
strt := 0
else
strt := strt + strsize(@crlf_crlf)
dataS := strt
bytesRead := strsize(@rxdata)-dataS
'pst.hex(dataS, 4)
' Check for an end boundary
end := str.MatchPattern(@rxdata, @boundary, strt, true)
'pst.str(string(13, "Find file data end: "))
'pst.hex(end, 4)
if(end == -1)
dataE := 0
else
dataE := end-1
bytesRead := end-strt
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'write file content to the SD card
'does the file exist? Yes = delete/create; no = create
'pst.str(string(13, "change directory"))
SDCard.changeDirectory(@approot)
SDCard.changeDirectory(@uploadfolder)
'pst.str(string(13, "File Exists?"))
if(FileExists(@uploadfile))
'pst.str(string(13, "YES File Exists - DELETE"))
SDCard.deleteEntry(@uploadfile)
'pst.str(string(13, "Create file"))
SDCard.newFile(@uploadfile)
'pst.str(string(13, "Open file"))
SDCard.openFile(@uploadfile, "w")
'do we a boundary in the 2K buffer?
if(end > -1)
dataE := end
' Write data within boundaries if everything fits in the buffer
' the loop spans the 2k buffer
'pst.str(string(13, "Write to file"))
if(bytesRead > 0)
SDCard.writeData(@rxdata+dataS, bytesRead)
rxBytes := rxBytes - bodySize
' pst.str(string(13, "Bytes Left: "))
pst.dec(rxBytes)
'pst.str(string(13, "Looping"))
bytefill(@rxdata, 0, RxTx_BUFFER)
repeat while rxBytes > 0
packetSize := Socket.rxTCP(id, @rxdata)
if(packetSize > 0)
'For the most part, I'm see 1460 byte packets in FF
'Let's see if we hit a boundary
'and hope the boundary is not split between packets
end := str.MatchPattern(@rxdata, @boundary, 0, true)
if(end == -1)
SDCard.writeData(@rxdata, packetSize)
else
'pst.str(string(13, "Writing end of data"))
pst.str(@rxdata+end-2)
SDCard.writeData(@rxdata, end-2)
rxBytes := rxBytes - packetSize
'pst.str(string(13, "Bytes Left: "))
pst.dec(rxBytes)
pause(200)
i := 0
else
i++
pause(200)
if(i > 100)
quit
'pst.str(string(13, "loops : "))
pst.dec(j)
'pst.str(string(13, "rxBytes : "))
pst.dec(rxBytes)
'pst.str(string(13, "Close file", 13))
SDCard.closeFile
SDCard.changeDirectory(@approot)
'Reset the tcpMask
'tcpMask := tempMask
bytefill(@uploadfile, 0, 12)
bytefill(@rxdata, 0, RxTx_BUFFER)
return
PRI UploadSite(id) | rxBytes, bytesRead, packetSize, i, j, command
packetSize := 0
i := 0
command := PUT
'We're expecting a HTTP PUT
ifnot(strcomp(Request.GetMethod(id), String("PUT")))
return
'pst.char(13)
'pst.str(@rxdata)
'pst.char(13)
'Initail handshake
bytefill(@rxdata, 0, RxTx_BUFFER)
pst.str(string(13, "Send Greeting"))
StringSend(id, string("Hello from Spinneret!",13,10))
'Authenticate
ifnot(Authenticate(id))
return
'Get first level target directory
GetDirectory(id)
'Repeat until we get the QUIT command from the client
repeat until command == DONE
'Initailize
pst.str(string(13, "------------[ Debug ]------------", 13))
bytefill(@binFile, 0, 12)
pause(100)
' Get a filename and size
GetUploadFileName(id)
rxBytes := GetFileSize(id)
'if the file exists then delete the file and create a new file
pst.str(string(13, "File Exists?"))
if(FileExists(@binFile))
pst.str(string(13, "YES File Exists - DELETE"))
SDCard.deleteEntry(@binFile)
pst.str(string(13, "Create file"))
SDCard.newFile(@binFile)
pst.str(string(13, "Open file"))
SDCard.openFile(@binFile, "w")
pst.str(string(13, "File Upload in process"))
j := 0
'Reads the file stream and write to the SD Card
repeat while rxBytes > 0
j++
' Get byte stream
packetSize := Socket.rxTCP(id, @rxdata)
if(packetSize > 0)
'Write byte stream to the SD card
SDCard.writeData(@rxdata, packetSize)
StringSend(id, string("OK - Write"))
rxBytes := rxBytes - packetSize
pst.str(string(13, "Bytes Left: "))
pst.dec(rxBytes)
pause(100)
i := 0
else
i++
pause(100)
if(i > 100)
StringSend(id, string("TIMEOUT"))
SDCard.closeFile
quit
' Diagnotics - Loop counter
pst.str(string(13, "loops : "))
pst.dec(j)
SDCard.closeFile
command := GetHttpFileTxCommnad(id)
'change directory
if(command == CD)
SDCard.changeDirectory(@approot)
GetDirectory(id)
'CD to root and get out of here
SDCard.changeDirectory(@approot)
pst.str(string(13, "Done!!!", 13))
return
PRI Authenticate(id) : ok | packetSize
''Username
ok := false
pst.str(string(13, "Wait for username"))
repeat
packetSize := Socket.rxTCP(id, @rxdata)
pause(200)
if(packetSize > 0)
quit
pst.str(string(13, "Received Username"))
pst.char(13)
pst.str(@rxdata)
if(strcomp(@rxdata, string("username")))
StringSend(id, string("OK - Authenticated"))
ok := true
else
StringSend(id, string("QUIT - No Dice"))
bytefill(@rxdata, 0, 50)
return
PRI GetUploadFileName(id) | packetSize
''Get file name
pst.str(string(13, "Wait for filename"))
repeat
packetSize := Socket.rxTCP(id, @rxdata)
pause(200)
if(packetSize > 0)
quit
pst.str(string(13, "Received Filename: "))
pst.str(@rxdata)
bytemove(@binFile, @rxdata, strsize(@rxdata) #> 12)
StringSend(id, string("OK - Received Filename"))
bytefill(@rxdata, 0, 50)
return
PRI GetFileSize(id) : rxBytes | packetSize
pst.str(string(13, "Get file size"))
repeat
packetSize := Socket.rxTCP(id, @rxdata)
pause(200)
if(packetSize > 0)
quit
pst.str(string(13, "Received File Size: "))
rxBytes := str.ToInteger(@rxdata)
pst.dec(rxBytes)
StringSend(id, string("OK - Received File Size"))
bytefill(@rxdata, 0, 50)
return
PRI GetDirectory(id) : rxBytes | packetSize
bytefill(@binDir, 0, 8)
pst.str(string(13, "Get directory"))
repeat
packetSize := Socket.rxTCP(id, @rxdata)
pause(200)
if(packetSize > 0)
quit
pst.str(string(13, "Received Directory: "))
StringSend(id, string("OK - Received Directory"))
bytemove(@binDir, @rxdata, strsize(@rxdata))
pst.str(@binDir)
bytefill(@rxdata, 0, 50)
pst.str(string(13, "Change Directory "))
SDCard.changeDirectory(@binDir)
pst.str(string(13, "Change Directory Success"))
return
PRI GetHttpFileTxCommnad(id) : again | packetSize
bytefill(@rxdata, 0, RxTx_BUFFER)
pst.str(string(13, "Upload another file?"))
repeat
packetSize := Socket.rxTCP(id, @rxdata)
pause(200)
if(packetSize > 0)
quit
pst.str(string(13, "Received Command: "))
pst.str(@rxdata)
if(strcomp(@rxdata, string("QUIT")))
StringSend(id, string("OK - Bye"))
again := DONE
if(strcomp(@rxdata, string("PUT")))
StringSend(id, string("OK - Put File"))
again := PUT
if(strcomp(@rxdata, string("CD")))
StringSend(id, string("OK - Change Directory"))
again := CD
pst.str(string(13, "File Command: "))
pst.dec(again)
bytefill(@rxdata, 0, 50)
return
PRI GetTime(id) | ptr, headerOffset
ptr := @udpdata
'FillTime
FillHttpDate
bytemove(ptr, string("<p>"),3)
ptr += 3
bytemove(ptr, @httpDate, strsize(@httpDate))
ptr += strsize(@httpDate)
'bytemove(ptr, @time, strsize(@time))
'ptr += strsize(@time)
'bytemove(ptr, string(" (GMT-7)"), 8)
'ptr += 8
bytemove(ptr, string("</p>"),4)
ptr += 3
headerOffset := Response.BuildHeader(Request.GetExtension(id), 200, false)
Socket.txTCP(id, @txdata, headerOffset)
StringSend(id, @udpdata)
bytefill(@udpdata, 0, TEMP_BUFFER)
return
PRI GetDir(id) | filenamePtr, ptr, headerOffset, cmd, qfile
'pst.str(string(13, "GetDir", 13))
ptr := @udpdata
'pst.str(string(13, "change dir", 13))
SDCard.changeDirectory(@approot)
SDCard.changeDirectory(@uploadfolder)
cmd := Request.Get(id, string("cmd"))
if(strcomp(cmd, string("d")))
qfile := Request.Get(id, string("file"))
SDCard.deleteEntry(qfile)
'pst.str(string(13, "startFindFile", 13))
SDCard.startFindFile
'Verify that the file exists
filenamePtr := 1
repeat while filenamePtr <> 0
filenamePtr := SDCard.nextFile
if(strcomp(filenamePtr, string(".")) or strcomp(filenamePtr, string("..")) or strsize(filenamePtr) == 0)
next
'pst.str(filenamePtr)
'pst.char(13)
'pst.dec(strsize(filenamePtr))
'pst.char(13)
bytemove(ptr, string("<a href='uploads/"),17)
ptr += 17
bytemove(ptr, filenamePtr, strsize(filenamePtr))
ptr += strsize(filenamePtr)
bytemove(ptr, string("'>"),2)
ptr += 2
bytemove(ptr, filenamePtr, strsize(filenamePtr))
ptr += strsize(filenamePtr)
bytemove(ptr, string("</a> "),16)
ptr += 16
{
bytemove(ptr, string("<a href='uploads/"),17)
ptr += 17
bytemove(ptr, filenamePtr, strsize(filenamePtr))
ptr += strsize(filenamePtr)
bytemove(ptr, string("'?cmd=d>delete</a>"),18)
ptr += 18
}
bytemove(ptr, string("<br>"),4)
ptr += 4
SDCard.changeDirectory(@approot)
'pst.char(13)
'pst.str(@udpdata)
'pst.char(13)
'pst.str(string(13, "send header", 13))
headerOffset := Response.BuildHeader(Request.GetExtension(id), 200, false)
Socket.txTCP(id, @txdata, headerOffset)
'pst.str(string(13, "send data", 13))
StringSend(id, @udpdata)
bytefill(@udpdata, 0, TEMP_BUFFER)
return
PRI AppendLog(logToAppend)
SDCard.changeDirectory(@approot)
if(FileExists(@logfile))
'pst.str(string(13, "LOG: open file for writing", 13))
SDCard.openFile(@logfile, "A")
else
'pst.str(string(13, "LOG: Create new file", 13))
SDCard.newFile(@logfile)
SDCard.writeData(string(13,10,"----- Start "),14)
SDCard.writeData(FillTime, 19)
SDCard.writeData(string(" -----"),6)
SDCard.writeData(@crlf_crlf, 2)
'pst.str(string(13, "LOG: Append", 13))
SDCard.writeData(logToAppend, strsize(logToAppend))
SDCard.writeData(@crlf_crlf, 2)
SDCard.writeData(string("----- End "),10)
SDCard.writeData(FillTime, 19)
SDCard.writeData(string(" -----"),6)
SDCard.writeData(@crlf_crlf, 2)
'pst.str(string(13, "LOG: Close file", 13))
SDCard.closeFile
PRI Set(DestAddress, SrcAddress, Count)
bytemove(DestAddress, SrcAddress, Count)
bytefill(DestAddress+Count, $0, 1)
PRI Ajax(id)
pst.str(string(13, "**************************", 13))
pst.str(@rxdata)
pst.str(string(13, "**************************", 13))
return
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
{ }
PRI FillTime | ptr, num
'ToString(integerToConvert, destinationPointer)
'00/00/0000 00:00:00
ptr := @time
rtc.readTime
FillTimeHelper(rtc.clockMonth, ptr)
ptr += 3
FillTimeHelper(rtc.clockDate, ptr)
ptr += 3
FillTimeHelper(rtc.clockYear, ptr)
ptr += 5
FillTimeHelper(rtc.clockHour , ptr)
ptr += 3
FillTimeHelper(rtc.clockMinute , ptr)
ptr += 3
FillTimeHelper(rtc.clockSecond, ptr)
return @time
PRI FillHttpDate | ptr, num, temp
'ToString(integerToConvert, destinationPointer)
'Wed, 01 Feb 2000 01:00:00 GMT
ptr := @httpDate
rtc.readTime
temp := rtc.getDayString
bytemove(ptr, temp, strsize(temp))
ptr += strsize(temp) + 2
FillTimeHelper(rtc.clockDate, ptr)
ptr += 3
temp := rtc.getMonthString
bytemove(ptr, temp, strsize(temp))
ptr += strsize(temp) + 1
FillTimeHelper(rtc.clockYear, ptr)
ptr += 5
FillTimeHelper(rtc.clockHour , ptr)
ptr += 3
FillTimeHelper(rtc.clockMinute , ptr)
ptr += 3
FillTimeHelper(rtc.clockSecond, ptr)
return @httpDate
PRI FillTimeHelper(number, ptr) | offset
offset := 0
if(number < 10)
offset := 1
str.ToString(@number, @tempNum)
bytemove(ptr+offset, @tempNum, strsize(@tempNum))
{
PRI toString(id) | i
pst.str(string("-------------------------",13))
pst.str(string("Version : "))
pst.str(Request.GetVersion(id))
pst.char(13)
pst.str(string("QueryString : "))
pst.str(Request.GetQueryString(id))
pst.char(13)
pst.str(string("Method : "))
pst.str(Request.GetMethod(id))
pst.char(13)
pst.str(string("Depth : "))
pst.dec(Request.GetDepth(id))
pst.char(13)
i := 0
repeat Request.GetDepth(id)
pst.dec(i)
pst.str(string(". Name : "))
pst.str(Request.GetPathNode(id, i++))
pst.char(13)
pst.str(string("FileName : "))
pst.str(Request.GetFileName(id))
pst.char(13)
pst.str(string("Name : "))
pst.str(Request.GetName(id))
pst.char(13)
pst.str(string("Extension : "))
pst.str(Request.GetExtension(id))
pst.char(13)
pst.str(string("Content-Len : "))
pst.dec(Request.GetContentLength(id))
pst.char(13)
}
PRI Pause(Duration)
waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt)
return
DAT
approot byte "\", 0
placeholder byte "<!--[content]-->", 0
tempFile byte "temp.htm", 0
defaultpage byte "index.htm", 0
logfile byte "log.txt", 0
cacheFile byte "cache.txt", 0
binFile byte "filename.bin", 0
binDir byte "director", 0
loadFile byte "led0.bin", 0
FS byte "/", 0
fn byte "filename=", 0
doublequote byte $22, 0
crlf byte 13, 10, 0
crlf_crlf byte 13, 10, 13, 10, 0
uploadfile byte $0[12], 0
divider byte "----", 0
uploadfolder byte "uploads", 0
tempNum byte "0000",0
multipart byte "Content-Type: multipart/form-data; boundary=",0
boundary byte $2D, $2D
boundary1 byte $0[64]
hashboundary byte "123ABC",0
loadme file "TogglePin0.binary"
Bookmarks