1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-06-17 17:30:49 +00:00

Internet CHAT client/server

This commit is contained in:
dschmenk 2015-12-01 16:56:35 -08:00
parent 9a5d238910
commit d6f3b5c475
18 changed files with 776 additions and 100 deletions

233
src/chatsrc/chat.pla Normal file
View File

@ -0,0 +1,233 @@
//
// HTTP Daemon
//
import cmdsys
predef syscall, call, getc, gets, putc, puts, putln, gotoxy
predef memset, memcpy, modaddr, modexec
predef isugt, isuge, isult, isule
predef heapmark, heapallocalign, heapalloc, heaprelease
byte MACHID
end
//
// Net object
//
import inet
word iNet
struc t_inet
word initIP
word serviceIP
word openUDP
word sendUDP
word closeUDP
word listenTCP
word connectTCP
word sendTCP
word closeTCP
word setInterfaceIP
word getInterfaceHA
word setDNS
word resolveIP
word setCallback
word setParam
end
end
const VERSION = 3
const txtline = $07D0
const inbuf = $0200
const instr = $01FF
byte[4] serverIP
word port, timeout
word update_list, update_len
byte response
byte hellopkt = $DA, $7E, VERSION, VERSION >> 8, $00, $00, $A2, 'H'
byte[9] handle = ""
byte chatpkt = $DA, $7E, VERSION, VERSION >> 8, $00, $01, $A2, 'C'
byte[33] msg
//
// DEBUG
//
def putln
return putc($0D)
end
def putb(hexb)
return call($FDDA, hexb, 0, 0, 0)
end
def puth(hex)
return call($F941, hex >> 8, hex, 0, 0)
end
def puti(i)
if i < 0; putc('-'); i = -i; fin
if i < 10
putc(i + '0')
else
puti(i / 10)
putc(i % 10 + '0')
fin
end
def putip(ipptr)
byte i
for i = 0 to 2
puti(ipptr->[i]); putc('.')
next
return puti(ipptr->[i])
end
def toupper(c)
if c >= 'a'
c = c - $20
fin
return c
end
def recvUDP(ipsrc, portsrc, data, len, param)
byte t
response = data->7
when response
is 'C'
putln
if data->16
^$32 = $3F // Inverse
for t = 0 to data->8
putc(toupper(^(data + t + 9)))
next
^$32 = $FF // Normal
for t = data->8 to 7
putc(' ')
next
puts(data + 16)
else
puts("Welcome, "); puts(data + 8)
fin
break
is 'W'
//puts("Connected to ")
//puts(instr); putc('='); putip(@serverIP)
break
is 'U'
update_list = data
update_len = len
break;
is 'E'
puts("Server error!"); putln
wend
end
def gotoxy(x, y)
^$24 = x + ^$20
return call($FB5B, y + ^$22, 0, 0, 0)
end
def txtwin(left, top, width, height)
if !width or !height
left = 0
top = 0
width = 40
height = 24
fin
^$20 = left
^$21 = width
^$22 = top
^$23 = height + top
return gotoxy(0, 0)
end
def txtclr
^$20 = 0
^$21 = 40
^$22 = 0
^$23 = 24
return call($FC58, $00, $00, $00, $00)
end
def kbstr
byte key, inlen
^$C010
inlen = 0
repeat
^(txtline + inlen) = $DF
key = ^$C000
if key & $80
^(txtline + inlen) = $A0
^$C010
if key == $88
if inlen > 0
inlen = inlen - 1
fin
elsif key == $9B
while inlen
^(txtline + inlen) = $A0
inlen = inlen - 1
loop
elsif key >= $A0 and inlen < 39
^(txtline + inlen) = key
^(inbuf + inlen) = key & $7F
inlen = inlen + 1
fin
fin
iNet:serviceIP()
until key == $8D
^instr = inlen
repeat
^(txtline + inlen) = $A0
inlen = inlen - 1
until inlen == $FF
return instr
end
if !iNet:initIP()
return -1
fin
repeat
puts("Enter chat server address\n")
gets(':'+$80)
if ^instr
if iNet:resolveIP(instr, @serverIP)
repeat
puts("Enter chat handle (7 characters or less)\n")
gets(':'+$80)
until ^instr > 0 and ^instr < 8
memcpy(@handle, instr, ^instr + 1)
port = iNet:openUDP($6501, @recvUDP, 0)
iNet:sendUDP(port, @serverIP, $6502, @hellopkt, 16)
timeout = 1000
while !response and timeout
iNet:serviceIP()
timeout = timeout - 1
loop
if response == 'W'
txtclr()
gotoxy(0, 22)
puts("========================================")
txtwin(0, 0, 40, 22)
gotoxy(0, 0)
repeat
kbstr()
if ^instr
if ^instr > 31
^instr = 31
fin
memcpy(@msg, instr, ^instr + 1)
iNet:sendUDP(port, @serverIP, $6502, @chatpkt, 40)
fin
until ^instr == 0
txtclr()
elsif response == 'U'
heaprelease(update_list + update_len) // Set top of heap to end of update list
memcpy($0300, @serverIP, 4) // Pass serverIP to UPDATE
*$0304 = $6502 // Pass server port to UPDATE
*$0306 = update_list + 8 // Pass list pointer to UPDATE
^instr = 0
modexec("UPDATE")
else
puts("Welcome timed out."); putln
fin
else
puts("Unable to resolve."); puts(instr); putln
fin
fin
until not ^instr
done

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<chat xmlns="updates">
<file name="PLASMA.SYSTEM" type="0xFF" aux="0x2000" mask="0x0001"/>
<file name="UTHERNET" type="0xFE" aux="0x1000" mask="0x0002"/>
<file name="UTHERNET2" type="0xFE" aux="0x1000" mask="0x0004"/>
<file name="ETHERIP" type="0xFE" aux="0x1000" mask="0x0008"/>
<file name="INET" type="0xFE" aux="0x1000" mask="0x0010"/>
<file name="DHCP" type="0xFE" aux="0x1000" mask="0x0020"/>
<file name="UPDATE" type="0xFE" aux="0x1000" mask="0x0040"/>
<file name="CHAT" type="0xFE" aux="0x1000" mask="0x0080"/>
<file name="AUTORUN" type="0x06" aux="0x0000" mask="0x0100"/>
<current level="3"/>
<version level="1" updates="0x0000"/>
<version level="2" updates="0x00C0"/>
<version level="3" updates="0x01C0"/>
</chat>

View File

@ -0,0 +1,44 @@
#!/usr/bin/python
import sys, struct, socket, select
server = ("localhost", 0x6502)
myhandle = "Python"
VERSION = 3
# SOCK_DGRAM is the socket type to use for UDP sockets
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(struct.pack('<HHHBc8p', 0x7EDA, VERSION, 1, 0xFF, 'H', myhandle), server)
data, server = s.recvfrom(2048)
magic, ver, seq, hw, res = struct.unpack_from('<HHHBc', data)
if res == 'U':
ulistofst = 8
print "Update file list: (", len(data), " bytes)"
while len(data) - ulistofst >= 20:
filename, filetype, fileaux = struct.unpack_from('<17pBH', data, ulistofst)
if filename == "": break
print filename, filetype, fileaux
ulistofst += 20
elif res <> 'W':
print "Server rejected HELLO"
else:
p = select.poll()
p.register(s, select.POLLIN)
p.register(sys.stdin, select.POLLIN)
while 1:
pollin = p.poll()
if len(pollin) > 0:
if pollin[0][0] == sys.stdin.fileno():
instr = raw_input()
if len(instr) == 0: break
s.sendto(struct.pack('<HHHBc32p', 0x7EDA, VERSION, 1, 0xFF, 'C', instr), server)
elif pollin[0][0] == s.fileno():
data, server = s.recvfrom(2048)
magic, ver, seq, hw, req = struct.unpack_from('<HHHBc', data)
if req == 'C':
handle, msg = struct.unpack_from('8p32p', data, 8)
if msg:
print handle, ": ", msg
#elif handle <> myhandle:
else:
print "Welcome, ", handle
s.close()

View File

@ -0,0 +1 @@
+CHAT

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

104
src/chatsrc/chatserver/server.py Executable file
View File

@ -0,0 +1,104 @@
#!/usr/bin/python
# Apple II Chat server program
import struct, socket, select, time
import xml.etree.ElementTree as ET
HOST = '' # Symbolic name meaning all available interfaces
PORT = 0x6502 # Apple II Chat non-privileged port
VERSION = 1
client_list = {}
chat_files = {}
chat_vers = []
def client_add(address, port, handle):
global client_list
client_list[address] = (port, handle)
def broadcast(handle, msg):
global client_list
if msg:
print handle, ": ", msg
else:
print "Welcome, ", handle
bcastmsg = struct.pack('<HHHBc8p32p', 0x7EDA, VERSION, 0, 0xCA, 'C', handle, msg)
for c in client_list:
client = (c, client_list[c][0])
s.sendto(bcastmsg, client)
def send_update(client, ver):
updatemask = 0
updatelist = []
for i in xrange(ver, VERSION):
updatemask |= chat_vers[i]
for f in chat_files:
if updatemask & chat_files[f][2]:
updatelist.append(f)
print "Update client version ", ver, " with:", updatelist
pkthdr = struct.pack('<HHHBc', 0x7EDA, VERSION, 0, 0xCA, 'U')
pktmsg = ""
for f in updatelist:
pktmsg += struct.pack('<17pBH', f, chat_files[f][0], chat_files[f][1])
pktmsg += struct.pack('B', 0)
s.sendto(pkthdr + pktmsg, client)
#
# Read version XML file
#
tree = ET.parse('chat-version.xml')
root = tree.getroot()
for chatfile in root.findall('{updates}file'):
fname = chatfile.get('name')
ftype = int(chatfile.get('type'), 0)
faux = int(chatfile.get('aux'), 0)
fmask = int(chatfile.get('mask'), 0)
chat_files[fname] = (ftype, faux, fmask)
for chatver in root.findall('{updates}version'):
chat_vers.insert(int(chatver.get('level')), int(chatver.get('updates'), 0))
chatver = root.find('{updates}current')
VERSION = int(chatver.get('level'))
print "CHAT server version:", VERSION
#
# Initialize UDP socket
#
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((HOST, PORT))
p = select.poll()
p.register(s.fileno(), select.POLLIN)
#
# Main server loop
#
while 1:
if p.poll(1000):
data, client = s.recvfrom(2048)
address, port = client
magic, ver, seq, hw, req = struct.unpack_from('<HHHBc', data)
if req == 'H':
handle, = struct.unpack_from('8p', data, 8)
if ver <> VERSION:
send_update(client, ver)
else:
client_add(address, port, handle)
s.sendto(struct.pack('<HHHBc', magic, ver, seq, 0xCA, 'W'), client)
broadcast(handle, "")
elif req == 'C':
try:
msg, = struct.unpack_from('32p', data, 8)
handle = client_list[address][1]
broadcast(handle, msg)
except:
s.sendto(struct.pack('<HHHBc', 0x7EDA, VERSION, 0, 0xCA, 'E'), client)
elif req == 'F':
try:
filename, fileblock = struct.unpack_from('<17pH', data, 8)
f = open('clientfiles/'+filename, 'r')
f.seek(fileblock * 1024)
msg = f.read(1024)
f.close()
s.sendto(struct.pack('<HHHBc', 0x7EDA, VERSION, seq, 0xCA, 'F') + msg, client)
except:
s.sendto(struct.pack('<HHHBc', 0x7EDA, VERSION, seq, 0xCA, 'E'), client)
else:
print "Unknown request: " + req
else:
pass
s.close()

37
src/chatsrc/makefile Executable file
View File

@ -0,0 +1,37 @@
.SUFFIXES =
AFLAGS = -o $@
CHAT = CHAT\#FE1000
UPDATE = UPDATE\#FE1000
PLASM = ../plasm
#
# Image filetypes for Virtual ][
#
PLATYPE = .\$$ED
BINTYPE = .BIN
SYSTYPE = .SYS
TXTTYPE = .TXT
#
# Image filetypes for CiderPress
#
#RELTYPE = \#FE1000
#INTERPTYPE = \#050000
#BINTYPE = \#060000
#SYSTYPE = \#FF2000
#TXTTYPE = \#040000
all: $(UPDATE) $(CHAT)
clean:
-rm *FE1000 *FF2000
-rm *.o *~ *.a
$(UPDATE): update.pla $(PLASM)
./$(PLASM) -AM < update.pla > update.a
acme --setpc 4094 -o $(UPDATE) update.a
cp $(UPDATE) chatserver/clientfiles/UPDATE
$(CHAT): chat.pla $(PLASM)
./$(PLASM) -AM < chat.pla > chat.a
acme --setpc 4094 -o $(CHAT) chat.a
cp $(CHAT) chatserver/clientfiles/CHAT

231
src/chatsrc/update.pla Normal file
View File

@ -0,0 +1,231 @@
//
// HTTP Daemon
//
import cmdsys
predef syscall, call, getc, gets, putc, puts, putln
predef memset, memcpy, modaddr, modexec
predef isugt, isuge, isult, isule
predef heapmark, heapallocalign, heapalloc, heaprelease
byte MACHID
end
//
// Net object
//
import inet
word iNet
struc t_inet
word initIP
word serviceIP
word openUDP
word sendUDP
word closeUDP
word listenTCP
word connectTCP
word sendTCP
word closeTCP
word setInterfaceIP
word getInterfaceHA
word setDNS
word resolveIP
word setCallback
word setParam
end
end
const VERSION = 1
byte[4] serverIP
word serverPort
word updateList
word portUDP, timeout
byte response
byte perr
byte dlFile = "DOWNLOAD"
byte dlRef
byte rdreqpkt = $DA, $7E, VERSION, VERSION >> 8, $00, $00, $A2, 'F'
byte[17] filename = ""
word fileblock
word xferlen
asm reboot
BIT $C082 ; ENABLE ROM
DEC $03F4 ; INVALIDATE POWER-UP BYTE
JMP ($FFFC) ; RESET
end
//
// ProDOS routines
//
def getpfx(path)
byte params[3]
^path = 0
params.0 = 1
params:1 = path
perr = syscall($C7, @params)
return path
end
def setpfx(path)
byte params[3]
params.0 = 1
params:1 = path
perr = syscall($C6, @params)
return path
end
def open(path, buff)
byte params[6]
params.0 = 3
params:1 = path
params:3 = buff
params.5 = 0
perr = syscall($C8, @params)
return params.5
end
def close(refnum)
byte params[2]
params.0 = 1
params.1 = refnum
perr = syscall($CC, @params)
return perr
end
def read(refnum, buff, len)
byte params[8]
params.0 = 4
params.1 = refnum
params:2 = buff
params:4 = len
params:6 = 0
perr = syscall($CA, @params)
return params:6
end
def write(refnum, buff, len)
byte params[8]
params.0 = 4
params.1 = refnum
params:2 = buff
params:4 = len
params:6 = 0
perr = syscall($CB, @params)
return params:6
end
def create(path, access, type, aux)
byte params[12]
params.0 = 7
params:1 = path
params.3 = access
params.4 = type
params:5 = aux
params.7 = $1
params:8 = 0
params:10 = 0
perr = syscall($C0, @params)
return perr
end
def destroy(path)
byte params[3]
params.0 = 1
params:1 = path
perr = syscall($C1, @params)
return perr
end
def rename(path, newpath)
byte params[5]
params.0 = 2
params:1 = path
params:3 = newpath
perr = syscall($C2, @params)
return perr
end
//
// Restart
//
def restart
puts("Press any key to reboot...")
getc()
reboot()
end
//
// Error
//
def dl_error(errstr)
puts("Update Error: "); puts(errstr); putln
restart()
end
//
// Receive UDP packet
//
def recvUDP(ipsrc, portsrc, data, len, param)
when data->7
is 'F'
if data=>4 == rdreqpkt:4 // Sequence numbers match
xferlen = len - 8
if xferlen > 0
if write(dlRef, data + 8, xferlen) <> xferlen or perr
dl_error("Write download file")
fin
fin
response = 'F'
fin
break
is 'E'
dl_error("Server error")
break
otherwise
dl_error("Unexpected packet")
wend
end
//
// Main update loop
//
memcpy(@serverIP, $0300, 4) // Passed in IP
serverPort = *$0304 // Passed in port
updateList = *$0306 // Passed in update list
portUDP = iNet:openUDP($6500, @recvUDP, 0)
while ^updateList
puts("Updating: "); puts(updateList)
destroy(@dlFile)
if create(@dlFile, $C3, updateList->17, updateList=>18)
dl_error("Unable to create download file")
fin
dlRef = open(@dlFile, $0800) // Use system io_buffer
if not dlRef
dl_error("Unable to open download file")
fin
rdreqpkt:4 = 2 // Init sequence number
memcpy(@filename, updateList, 17)
fileblock = 0
repeat
iNet:sendUDP(portUDP, @serverIP, serverPort, @rdreqpkt, 27)
timeout = 1000
response = 0
while not response and timeout
iNet:serviceIP()
timeout = timeout - 1
loop
if not response
dl_error("No response from server")
fin
putc('.')
fileblock = fileblock + 1
rdreqpkt:4 = rdreqpkt:4 + 1 // Increment sequence
until xferlen <> 1024
close(dlRef)
destroy(updateList)
rename(@dlFile, updateList)
if perr
dl_error("Rename download file")
fin
updateList = updateList + 20
putln
loop
iNet:closeUDP(portUDP)
puts("Update complete.\n")
restart()
done

View File

@ -1,6 +1,14 @@
//
// Original Uthernet ethernet card based on Cirrus Logic cs8900a
//
import cmdsys
predef syscall, call, getc, gets, putc, puts, putln
predef isugt, isuge, isult, isule
predef memset, memcpy, modaddr, modexec
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
byte MACHID
end
//
// Include dependency on S/W IP stack
//
import etherip
@ -25,7 +33,7 @@ const AUTO_INC = $8000
//
// Uthernet register addresses
//
byte[] slot // Init time only
byte[] slot // Init time only
byte rxdata_lo, rxdata_hi
byte txcmd
byte txlen
@ -213,7 +221,7 @@ end
//
// Identify Uthernet card and initialize
//
for slot = $F0 downto $90 step $10
for slot = $90 to $F0 step $10
if (peekiow(slot+TXCMD) & $CC3F) == $09
pokeiow(slot+PREG_INDEX, 0)
if peekiow(slot+PREG_DATA) == $630E
@ -238,6 +246,9 @@ for slot = $F0 downto $90 step $10
//
// Install etherip driver
//
puts("Found Uthernet I in slot #")
putc('0' + ((slot - $80) >> 4))
putln
setEtherDriver(@utherMAC, @peekfrmlen, @peekfrm, @pokefrmlen, @pokefrm)
return modkeep
fin

View File

@ -104,8 +104,10 @@ const WIZ_RXMEM3 = $7800
//
// Wiznet indirect registers
//
byte regidx, regdata
word slot, saveidx
byte slot
word saveidx
byte regidx
byte regdata
//
// Wiznet MAC address
//
@ -720,108 +722,99 @@ def wizServiceIP
if ir
wiz = @wizChannel
for i = 0 to 3
when ir & (1 << i)
is 1
is 2
is 4
is 8
wizregs = wiz=>channel_regs
wizdata = wiz=>channel_rxmem
sir = peekreg(wizregs + WIZ_SnIR)
when wiz->channel_proto
is WIZ_PROTO_UDP
if sir & $04
//
// Receive UDP packet
//
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr + rxlen >= WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(rxpkt,swab(rxpkt=>4),rxpkt+8,rxlen-8,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
break
is WIZ_PROTO_TCP
if sir & $01
//
// Connect TCP socket
//
when wiz->channel_state
is TCP_STATE_LISTEN
peekregs(wiz=>channel_regs + WIZ_SnDIPR, @wiz=>channel_remip, IP4ADR_SIZE)
wiz=>channel_remport = peekregw(wiz=>channel_regs + WIZ_SnDPORT)
is TCP_STATE_CONNECT
wiz->channel_state = TCP_STATE_OPEN
wend
if ir & (1 << i)
wizregs = wiz=>channel_regs
wizdata = wiz=>channel_rxmem
sir = peekreg(wizregs + WIZ_SnIR)
pokereg(wiz=>channel_regs + WIZ_SnIR, sir) // Clear SnIR
when wiz->channel_proto
is WIZ_PROTO_UDP
if sir & $04
//
// Receive UDP packet
//
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr + rxlen >= WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
if sir & $04
//
// Receive TCP packet
//
if wiz->channel_state == TCP_STATE_OPEN
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr + rxlen > WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,rxpkt,rxlen,wiz=>channel_recv_parm)
heaprelease(rxpkt)
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(rxpkt,swab(rxpkt=>4),rxpkt+8,rxlen-8,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
break
is WIZ_PROTO_TCP
if sir & $01
//
// Connect TCP socket
//
when wiz->channel_state
is TCP_STATE_LISTEN
peekregs(wiz=>channel_regs + WIZ_SnDIPR, @wiz=>channel_remip, IP4ADR_SIZE)
wiz=>channel_remport = peekregw(wiz=>channel_regs + WIZ_SnDPORT)
is TCP_STATE_CONNECT
wiz->channel_state = TCP_STATE_OPEN
wend
fin
if sir & $04
//
// Receive TCP packet
//
if wiz->channel_state == TCP_STATE_OPEN
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr + rxlen > WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
fin
if sir & $02
//
// Close TCP socket
//
if wiz->channel_state == TCP_STATE_OPEN // Notify callback w/ len = 0
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,0,wiz=>channel_lclport,0,wiz=>channel_recv_parm)
fin
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,rxpkt,rxlen,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
if sir & $08
//
// Timeout on TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CONNECT
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
wend
fin
if sir & $02
//
// Close TCP socket
//
if wiz->channel_state == TCP_STATE_OPEN // Notify callback w/ len = 0
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,0,wiz=>channel_lclport,0,wiz=>channel_recv_parm)
fin
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
fin
if sir & $08
//
// Timeout on TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CONNECT
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
wend
fin
wend
pokereg(wiz=>channel_regs + WIZ_SnIR, sir) // Clear SnIR
ir = ir ^ (1 << i)
wend
fin
wiz = wiz + t_channel
next
//
// Clear IR
//
pokereg(WIZ_IR, ir)
fin
end
//
@ -884,6 +877,12 @@ for slot = $90 to $F0 step $10
pokeregw(WIZ_RTR, 5000) // Timeout period to 500ms
pokereg(WIZ_RMSR, $55) // 2K Rx memory/channel
pokereg(WIZ_TMSR, $55) // 2K Tx memory/channel
//
// Print settings
//
puts("Found Uthernet II in slot #")
putc('0' + ((slot - $80) >> 4))
putln
//
// Fill channel structure
//

View File

@ -977,7 +977,7 @@ def create(path, access, type, aux)
return perr
end
def destroy(path)
byte params[12]
byte params[3]
params.0 = 1
params:1 = path