Web51 TCP sockets |
|
The system is mainly event-driven. It is not possible to write a procedure that would process incoming characters in a loop and have a background process deliver them. Rather, Web51 behaves more like the background process that calls a character-processing procedure whenever a character is received. Characters are usually processed in several state machines with state transitions dependent on the received character. For example, the states of the http state machine expect the characters 'G' 'E' 'T' ' ' in this order, transiting to the filesystem index calculation mode afterwards.
Behavior of the TCP stack is controlled by several configuration constants.
; "telnet" .global STACK1MODE .equ STACK1MODE, RESENDMODE .global ETHRETRY1 .equ ETHRETRY1, 5*50 ; timeout = 50 s .global PORT1 ; local port .equ PORT1, 23 .global PORT3 ; remote port .equ PORT3, 23 ; "http" .global STACK2MODE .equ STACK2MODE, NORESENDMODE .global ETHRETRY2 .equ ETHRETRY2, 5*2 ; timeout = 2 s .global PORT2 ; local port .equ PORT2, 80
First, there are the STACKxMODE constants with valid values RESENDMODE and NORESENDMODE. These affect the TCP
stack operation in terms of acknowledging outgoing data. RESENDMODE is more correct with respect to TCP definition;
data are removed from the buffer when the other side acknowledges them. Unacknowledged data remain in the buffer
and the transmission can be repeated. However, the transmit buffer size is limited; for example, the sendchar
procedure limits the buffer size to about 1280 bytes. If the limit is exceeded, the buffer contents are transmitted
and the associated pointers are reset. This mode is for instance suitable for transferring data from the serial line,
with the data being copied to the TCP packet from the serial line buffer only if there is space.
If it is impossible to regulate the size of transmitted data, the NORESENDMODE shoud be used. This mode supports
the "transmit and forget" function; contents of the buffer are transmitted, automatically acknowledged, and split
into several TCP segments if necessary. The last TCP packet has the FIN flag set. This mode is suitable for example
for serving WWW pages - if the communication is corrupted, data can be thrown away and the entire communication
starts over from the beginning.
The ETHRETRYx constants specify the timeout for individual TCP stacks.
Stack 2 is not capable of active connection establishing.
During operation, the TCP stack calls three callback procedures depending on the TCP connection state. Procedure open_stack is called when the TCP connection is open. It can be used for instance to initialize the procedure for processing of incoming data. Procedure process_stack is called whenever there are incoming data or acknowledgements. This procedure processes the incoming data and also passes data to the TCP stack. Procedure close_stack is called when the connection is terminated.
.text .global open_stack1 .global process_stack1 .global close_stack1 open_stack1: ret process_stack1: ljmp telnet close_stack1: ljmp close_telnet .global open_stack2 .global process_stack2 .global close_stack2 open_stack2: ljmp open_http process_stack2: ljmp http close_stack2: ret
All of the above code examples are extracted from www8051.asm from the "serial" example. The above sample demonstrates assignment of the callbacks to actual procedures that transfer data between TCP and the serial line and control the http protocol.
Let's use the example of transferring data over TCP to demonstrate the function of the callback procedure named telnet. Two parameters are passed to the process_stack procedure:
Before process_stack is called, the variables unwrited, tcpWritePointer and flaghide are also set. They control writing data to the TCP stack. However, they are usually masked from the user by functions for writing to the TCP stack, such as sendchar, sendDecb, sendHexb, sNibl, send_string.
Unlike writing to the TCP stack, Web51 does not have character-oriented function for reading from the TCP stack. Processing of received data is managed by the user, using the variables data_addr and data_len.
First, check if there are data to be processed in the received packet and save the length of the data.
telnet: ;;send max. data_len bytes to serial line mov a,data_len+1 ;LSB mov workreg+3,a ;LSB mov workreg+2,data_len ;MSB orl a,data_len ;MSB jz sendTelnetDta
Copy part of the received packet from RTL8019AS buffer to the work buffer in the microcontroller for processing.
tgetbuf:
mov Timeout1,#ethtiming ;restart retry timer
;; Retry1 = ETHRETRY1;
mov Retry1,#ETHRETRY1
setb flag1retry ;; NEW data in packet, send delayed Ack
LCALL pcode
;; copy_r2s (buf, data_addr, sizeof(buf));
.pcode pr2s BYTE buf, @data_addr, #BYTE sizeofbuf ;copy telnet data
;; data_addr += sizeof(buf);
.pcode paddwi BYTE data_addr, #BYTE sizeofbuf
.byte 0
mov R0,#buf-1
Process the copied data. In case of the telnet procedure, processing is simple - just copy the data byte by byte into the serial line buffer. If the serial line buffer is full, processing terminates prematurely.
tnxtin:inc R0 mov a,#(buf + sizeofbuf) xrl a,R0 jz tgetbuf mov a,data_len jnz tdata mov a,data_len+1 jnz tdata sjmp tallsend tdata: mov a,@r0 lcall xputchar jz ttimeout ;; data_len--; mov a,data_len+1 ; LSB dec a mov data_len+1,a cjne A,#0xFF,sndx dec data_len ; MSB sndx: sjmp tnxtin
Acknowledge processed data from the passed TCP packet with a call to AckBytes.
ttimeout:
;; workreg -= data_len;
mov r0,#workreg+3
clr C
mov a,@r0
subb a,data_len+1
mov @r0,a
dec r0
mov a,@r0
subb a,data_len
mov @r0,a
tallsend:
; Acknowledge only processed data
;; tx_eth_pkt.pkt.ip.ipdata.tcp.tcpheader.Ack =
;; rcvSeq + sendbytes;
mov R7,workreg+3 ;LSB
mov R6,workreg+2 ;MSB
lcall AckBytes
TCP connection is full duplex; therefore, a reply acknowledging received data may contain other outgoing data. If there is space in the transmitted packet (keep in mind the RESENDMODE used), we can fill it with data from the serial line buffer. The entire packet is stored in the RTL8019AS for retransmission in case of errors. Unlike in older TCP implementations in Web51, data processed by getchar/sendchar are removed from the serial line buffer. Removal does not wait for acknowledgement from the other side.[5]
sendTelnetDta: MOV A,tcpWritePointer ; MSB anl A,#0xFC ; send data only ; if tcpWritePointer %lt; 0x0400 jnz tnodata ;; if data in buffer, transmit jnb rxint,tnodata lcall getchar lcall sendchar sjmp sendTelnetDta tnodata: ret
Upon return from the process_stack procedure, sendchar buffers, if any, are copied to the packet, TCP flags and checksums are added, ..., and the packet is transmitted.
[5] In the NORESENDMODE operation, length of the transmitted packet is not important. If necessary, the outgoing data are transmitted in several packets. Upon return from the process_stack procedure, the last packet sent has the FIN flag set and the connection is terminated.
| Web51 description | News | FAQ | ORDER FORM | DOWNLOAD | Links |
| (c)Copyright 2000 - 2002, HW server & Radek Benedikt
Web51@HW.cz, Web51.HW.cz |
|