Spinneret setup help
Wildatheart
Posts: 195
I've been trying to get my Spinneret up and running, but I can't seem to get beyond "GET /index.htm Write 404 Error". I do have the "Hello World" file (index.htm) on the SD card.
My Spinneret is listed in the D-Link's list of "LAN COMPUTERS" at 192.168.0.120, and I can also get a 0 or 1 ms ping response through my D-Link Router test.
Changes to HTTPServer example are as folows:
mac.....................byte $00, $08, $DC, $16, $F2, $06
subnet.................byte 255, 255 ,255, 0
gateway..............byte 192, 168, 0, 1
ip........................byte 192, 168, 0, 120
port.....................word 5000
remoteIp.............byte 72, 222, 244, 139
I can post screenshots of the D-Link settings if it will help.
Thanks for your help. Gordon
My Spinneret is listed in the D-Link's list of "LAN COMPUTERS" at 192.168.0.120, and I can also get a 0 or 1 ms ping response through my D-Link Router test.
Changes to HTTPServer example are as folows:
mac.....................byte $00, $08, $DC, $16, $F2, $06
subnet.................byte 255, 255 ,255, 0
gateway..............byte 192, 168, 0, 1
ip........................byte 192, 168, 0, 120
port.....................word 5000
remoteIp.............byte 72, 222, 244, 139
I can post screenshots of the D-Link settings if it will help.
Thanks for your help. Gordon
Comments
Try formatting the SD card and copying the files over again. BTW, what kind of SD card are you using?
What URL are you typing into the browser address bar?
I'm using URL in IE7or8 http://192.168.0.120:5000/
I should mention that below
clsd open lstn estb clwt cling udps
is
0000-0000-0111-0000-0000-0000-0000
not
0000-0000-1111-0000-0000-0000-0000
as shown in the tutorial
The format options used were
File System - Fat32
Allocation Unit Size 32kb
I should also ask, is it reasonable for the Spinneret to exhaust a fresh 9v battery in less than an hour of usage?
500/175 = 2.8 hours under no load. So draining a 9V battery in an hour is very achievable.
Post your running source code.
Describe your connections.
Yada, yada, yada...
Spinneret connections:
[HP laptop running PST, USB]<--->[Prop Plug on Spinneret]
[Spinneret CAT5]<--->[DLink Router LAN port #2]
[Spinneret J6]<--->[9volt battery]
Entering 192.168.0.120:5000 on desktop PC IE produces screenshot PST (not yet attached)
[php]
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" [/php]
[php]
<html>
<head>
<title>Hello World</title>
</head>
<body>
Hello World!
</body>
</html>
[/php]
I have 4 or 5 screenshots but I'll have to figure out how to attach them if they'd help.
The latest HTTPServer is using Kye's 3.0 driver.
Load the "proven to work" default HTTPServer to verify network configuration.
http://code.google.com/p/spinneret-web-server/source/browse/#svn%2Ftrunk%2FMultiSocketServer_MikeG%2FTutorialSourceArchives%2Fspin
Then troubleshoot the SD driver changes you made to HTTPServer.
Suggestions:
Get yourself a wal-wart power supply. I'm using an old 5V cell phone charger.
Post configuration and any changes made to original source code when posting a problem.
Now then... yes, the wall-wart is a must! I believe HTML5 isn't fully operational yet, but I tried it anyway and am able to serve up the page at...
http://192.168.0.120:5000
It works 100% of the time from my Windows desktop and laptop, but I get timeouts and a blank screen on my Ipad in about 14 out of the 15 attempts. Is it possible to adjust a timing setting in either the Ipad or the server?
A button press on the page gives an indication of the responsiveness of the Spinneret. It's pretty fast!
What data is displayed in PST? Is the Spinneret locking up? How many images or links do you have on the page? Is the connection over WiFi?
All browsers behave differently. You'll have to do some troubleshooting to figure out the problem. You might have to write a little Spin to target the issue or print more information to PST.
I do not have an iPad so I'd be shooting in the dark.
http://72.222.244.139 to open this project to the WWW. Not sure.
In any case, the attached shows the PST after 1 attempt on my Iphone. Although all objects on the page don't show - probably because its mobile - I can serve up a reasonable representation of the page on the phone. But maybe the Iphone is still connecting through LAN. My Windows IE browser does open the full page and the resulting effect is noted in the attached.
I'll leave the Spinneret connected if anyone would like to check it from the outside. But gee whiz, there are hundreds of options in the DLink settings so I wouldn't think that I'd break out and into the WWW any time soon.
You forgot the port number (:5000)in your link
Thanks for noting the missing 5K http://72.222.244.139:5000
Suggestion, make your test page as simple as possible. No graphics, no css, no HTML5, just a simple "Hello World".
Massimo
OS X Lion 10.7.3 - Firefox 11.0
OS X Lion 10.7.3 - Safari 5.1.4
WIN 7 - Firefox 11.0
WIN 7 - IE 9
Fedora 16 Linux - Firefox 11.0
iPhone 4GS WiFi IOS 5.1 - Safari
iPhone 4GS 4G IOS5.1 - Safari
Yesterday, it was not working for me at all from anything I tried.
I continue to use html5 at this time so it seems IE9, Safari 5. and... is required to fully view the page.
My version 1 Ipad still has a little problem with reliable connection but I think that's the problem of the older Ipad itself.
Thanks to all who helped with what I perceived as a daunting task.