Web51 TCP sockets

Web 51 - Zpracovani Ethernet Paketu  software.html  Web 51 - Implementace jednoducheho http serveru
Systém Web51 nepoužívá ovládání, vzhledem k nedostatku paměti, blízké některému z běžných TCP socketů. Web51 má svoje, dost specifické rozhraní..

Hlavní vlastností tohoto systému je řízení pomocí událostí. Nelze například napsat proceduru zpracovávající ve smyčcce příchozí znaky a využívající procesu na pozadí, který tyto znaky "dodává". Web51 se chová spíše jako ten proces na pozadí, který po přijetí znaku volá proceduru a ta zpracovává znak. Zpracování znaku je obvykle řízeno několika stavovými automaty, které na základě přijatého znaku přechází mezi jednotlivými stavy. Např. stavový automat pro http má stavy očekávající postupně příchod znaků 'G' 'E' 'T' ' ', po kterém se přechází na režim výpočtu indexu (sumy) do souborového systému.

Chování TCP stacku je ovlivňováno nastavením několika konfiguračních konstat.

Příklad 3.1.

; "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

V první řadě jsou to konstanty STACKxMODE s platnými hodnotami RESENDMODE a NORESENDMODE ovlivňující chování TCP stacku z hlediska potvrzování odesílaných dat. RESENDMODE se chová z hlediska TCP korektněji, data se postupně tak jak je protistrana potvrzuje odmazávají z vysílacího bufferu. Nepotvrzená data zůstávají v bufferu a je možno je znovu opakovaně vyslat. Vysílací buffer má omezenou velikost a např. procedura sendchar omezuje jeho velikost na cca 1280 byte. Při překročení tohoto limitu je buffer vyslán a ukazatelé do něj zresetovány. Tento režim je proto vhodný např. na přenosy dat ze sériového kanálu, kdy do TCP paketu kopírujeme data z bufferu sériového kanálu pouze v případě, že je v něm místo. Pro přenos dat, kdy není možno tuto přenášenou velikost dat regulovat, musíme použít druhý režim NORESENDMODE. Tento režim podporuje funkci "vystřel a zapoměň", data po vyslání z bufferu jsou automaticky potvrzena, v případě potřeby rozsegmentována do několika TCP paketů a poslední paket nese příznak FIN. Tento režim je tedy vhodný na vysílaní dat typu www stránek, kdy je možno špatně přenesená data zahodit a celou komunikaci zopakovat od začátku.

Ve druhé řadě je to nastavení konstant ETHRETRYx určujících timeout pro jednotlivé TCP stacky.

Konstanty nastavení stacku :

Ze stacku 2 nelze navazovat aktivní spojení.


Příklad 3.2.

TCP stack při své činnosti volá v závislosti na stavu TCP spojení celkem tři callback procedury. První z nich open_stack je volána při otevření TCP spojení. Lze pomocí ní provést např. inicializaci příslušné procedury, zpracovávající data z TCP spojení. Druhá z nich process_stack je volána vždy když přišla data z TCP spojení, popř. přišlo potvrzení odeslaných dat. Tato procedura zpracovává přijatá data a rovněž předává data do TCP stacku. Třetí z nich close_stack je volána při ukončení spojení.

	.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

Na výše uvedené ukázce kódu, vyjmuté, stejně jako předchozí ukázka konfiguračních konstant, ze souboru www8051.asm z ukázkového projektu serial, je vidět přiřazení těchto callback procedur reálným procedurám obsluhujícím přenos TCP<->sériový kanál a obsluhujícím protokol http.

Zobrazme si na příkladu obsluhy právě přenosu sériového kanálu přes TCP protokol funkci callback procedury telnet Do callback procedury process_stack obsluhující vlastní přenos dat po TCP jsou předávány dva parametry:

Před voláním procedury process_stack jsou rovněž nastaveny proměnné unwrited, tcpWritePointer a flaghide, sloužící k zápisu dat do TCP stacku. Uživateli jsou však obvykle skryty funkcemi umožňujícími zápis do TCP stacku, jakými jsou např. sendchar, sendDecb, sendHexb, sNibl, send_string.

Na rozdíl od zápisu do TCP stacku, systém Web51 nedisponuje znakovými funkcemi pro čtení s TCP stacku. Zpracování přijatého paketu je na základě proměnných data_addr a data_len plně v režii uživatele.

Příklad 3.3.

Nejprve si zkontrolujeme, zda jsou v přijatém paketu data ke zpracování a zazálohujeme si předávanou délku dat.

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

Příklad 3.4.

Z bufferu obvodu RTL8019AS překopírujeme část přijatého paketu ke zpracování do pracovního bufferu buf v procesoru.

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

Příklad 3.5.

Překopírovaná data zpracujeme. V případě procedury telnet celkem jednoduše, přesuneme je byte za bytem do vyrovnávací paměti sériového kanálu. Je-li paměť sériového kanálu plná, zpracování předčasně ukončíme.

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

Příklad 3.6.

Potvrdíme protistanici pomocí volání AckBytes data která jsme z předaného TCP paketu zpracovali.

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

Příklad 3.7.

TCP spojení je plně duplexní, proto odpověd, nesoucí potvrzení zpracování přijatých dat, může nést data v opačném směru. Je-li ve vysílaném paketu místo (musíme brát ohled na nastavený režim RESENDMODE), doplníme jej daty z bufferu sériového kanálu. V obvodu RTL8019AS se celý vysílaný paket uchovává pro případné znovuvyslání při chybě TCP/IP přenosu. Na rozdíl od prvních implementací TCP stacku ve Web51 jsou proto data zpracovaná dvojicí volání procedur getchar/sendchar z bufferu sériového kanálu odstraněna. Nečeká se s jejich odstraněním na potvrzení přijetí protistranou.[5]

sendTelnetDta:
	MOV	A,tcpWritePointer	; MSB
	anl	A,#0xFC			; send data only 
					; if tcpWritePointer %lt; 0x0400
	jnz	tnodata
;; jsou-li v bufferu nejaka data vysli je
	jnb	rxint,tnodata
	lcall	getchar
	lcall	sendchar
	sjmp	sendTelnetDta
tnodata:
	ret

Po návratu z procedury process_stack jsou do vysílaného paketu vykopírovány případné vyrovnávací buffery procedury sendchar, doplněny TCP příznaky, suma, ... a paket je odeslán.

[5] V režimu NORESENDMODE nemusíme na délku vysílaného paketu brát ohled, vysílaná data se v případě potřeby vyšlou v několika paketech, po návratu z procedury process_stack je však poslední odesílaný paket označen příznakem FIN a spojení je uzavřeno.




Sponzored by LPhard Ltd. Graphics by GIMP Created by EasyPad

(c)Copyright 2000, 2001, HW server & Radek Benedikt
Web51@HW.cz, Web51.HW.cz

Final applications of the Web51 : www.HWgroup.cz
Web 51 - Zpracovani Ethernet Paketu  Obsah  Web 51 - Implementace jednoducheho http serveru