www.pudn.com > uCOSII上实现的tcpip.rar > ztcp.h


#ifndef _ZTCP_H
#define _ZTCP_H

#include "zarch.h"
#include "zdef.h"
#include "zbuffer.h"
#include "znetif.h"
#include "zipv4.h"
#include "zsocket.h"

#define TCP_ACCEPT_NUMBER	5
#define TCP_SEGMENT_NUMBER	32

STRUCT_BEGIN
typedef struct _tcp_header
{
	u16_t src;
	u16_t dest;
	u32_t seqno;
	u32_t ackno;
	u16_t _offset_flags;
	u16_t wnd;
	u16_t chksum;
	u16_t urgp;
}tcp_header_t;
STRUCT_END

typedef enum _tcp_state {
	CLOSED	    = 0,
	LISTEN	    = 1,
	SYN_SENT    = 2,
	SYN_RCVD    = 3,
	ESTABLISHED = 4,
	FIN_WAIT_1  = 5,
	FIN_WAIT_2  = 6,
	CLOSE_WAIT  = 7,
	CLOSING	    = 8,
	LAST_ACK    = 9,
	TIME_WAIT   = 10
}tcp_state;

/* This structure is used to repressent TCP segments.
 * Our segment include TCP + ETH + IP + DATA because simple*/
typedef struct _tcp_seg
{
		struct _tcp_seg *next;		/*segment chain*/
		u16_t len;					/* the TCP length of this segment */
		tcp_header_t *ptcpheader; 	/* the TCP's header information*/
		zbuffer_t	*pbuffer;			/* pointer to real data's zbuffer*/
		void 		*pdata;			/* pointer to real data's position*/
		

		u8_t	_id;				/*used for segment alloc and free*/
		zbuffer_t *_ori_pbuffer;	/* data + TCP header + IP + eth */
}tcp_seg_t;


typedef struct _tcp_pcb
{
	struct _tcp_pcb *next;
	zsocket_t	*_psocket;		/*identify of TCP socket*/

	u8_t		user_state;	/*used for API function, such as poll or block*/
	sys_sem_t	user_sem;	/*used for API function wait a EVENT*/
	
	s8_t		accept;		/*if this is a SERVER tcp socket*/
	struct	_tcp_pcb	*server;	/*if this pcb is accepted from a server*/
	
	
	tcp_state	state;			/*the state of TCP */
	/* receiver varables */
	u32_t rcv_nxt;	 /* next seqno expected */
	u16_t rcv_wnd;	 /* receiver window */

	/* Timers */
	u32_t tmr;

	/* Retransmission timer. */
	u8_t rtime;

	u16_t mss;   /* maximum segment size */

	u8_t flags;

#define TF_ACK_DELAY 0x01   /* Delayed ACK. */
#define TF_ACK_NOW   0x02   /* Immediate ACK. */
#define TF_INFR	     0x04   /* In fast recovery. */
#define TF_RESET     0x08   /* Connection was reset. */
#define TF_CLOSED    0x10   /* Connection was sucessfully closed. */
#define TF_GOT_FIN   0x20   /* Connection was closed by the remote end. */

	/* RTT estimation variables. */
	u16_t rttest; /* RTT estimate in 500ms ticks */
	u32_t rtseq;  /* sequence number being timed */
	s32_t sa, sv;

	u16_t rto;    /* retransmission time-out */
	u8_t nrtx;    /* number of retransmissions */

	/* fast retransmit/recovery */
	u32_t lastack; /* Highest acknowledged seqno. */
	u8_t dupacks;
	u16_t	acked;

	/* congestion avoidance/control variables */
	u16_t cwnd;
	u16_t ssthresh;


	/* sender variables */
	u32_t snd_nxt,	     /* next seqno to be sent */
	snd_max,       /* Highest seqno sent. */
	snd_wnd,       /* sender window */
	snd_wl1, snd_wl2,
	snd_lbb;

	u16_t snd_buf;	 /* Avaliable buffer space for sending. */
	u8_t snd_queuelen;

	u8_t polltmr, pollinterval;

	tcp_seg_t *unsent;
	tcp_seg_t *unacked;

	zbuffer_t	*recv_pbuf;		/*read data buffer*/

}tcp_pcb_t;



#define TCP_SEQ_LT(a,b)	    ((s32_t)((a)-(b)) < 0)
#define TCP_SEQ_LEQ(a,b)    ((s32_t)((a)-(b)) <= 0)
#define TCP_SEQ_GT(a,b)	    ((s32_t)((a)-(b)) > 0)
#define TCP_SEQ_GEQ(a,b)    ((s32_t)((a)-(b)) >= 0)


#define TCP_FIN 0x01
#define TCP_SYN 0x02
#define TCP_RST 0x04
#define TCP_PSH 0x08
#define TCP_ACK 0x10
#define TCP_URG 0x20


/* Length of the TCP header, excluding options. */
#define TCP_HEAD_LEN 20

/* ---------- TCP options ---------- */
#define TCP_TTL			255

/* Controls if TCP should queue segments that arrive out of
   order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ		1

/* TCP Maximum segment size. */
#define TCP_MSS			1024

/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF		4096

/* TCP sender buffer space (segment). This must be at least = 2 *
   TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN	TCP_SND_BUF/TCP_MSS

/* TCP receive window. */
#define TCP_WND			1024*4

/* Maximum number of retransmissions of data segments. */
#define TCP_MAXRTX		7	/*We have reduce to 7 from 12 --zhouchang*/

/* Maximum number of retransmissions of SYN segments. */
#define TCP_SYNMAXRTX		4

/*time const for TCP*/
#define TCP_TMR_INTERVAL       100  /*The TCP timer interval in milliseconds. */

#define TCP_FAST_INTERVAL      200  /* the fine grained timeout in
												  milliseconds */
#define TCP_SLOW_INTERVAL      500  /* the coarse grained timeout in
												  milliseconds */
#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
#define TCP_LASK_ACK_TIMEOUT 20000 /* milliseconds */

#define TCP_OOSEQ_TIMEOUT	 6 /* x RTO */

#define TCP_MSL 60000  /* The maximum segment lifetime in microseconds */

/*------------------------------------------------------*/


#define TCPH_OFFSET(hdr) (NTOHS((hdr)->_offset_flags) >> 8)
#define TCPH_FLAGS(hdr) (NTOHS((hdr)->_offset_flags) & 0xff)
#define TCPH_OFFSET_SET(hdr, offset) (hdr)->_offset_flags = HTONS(((offset) << 8) | TCPH_FLAGS(hdr))
#define TCPH_FLAGS_SET(hdr, flags) (hdr)->_offset_flags = HTONS((TCPH_OFFSET(hdr) << 8) | (flags))
#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->ptcpheader) & TCP_FIN || TCPH_FLAGS((seg)->ptcpheader) & TCP_SYN)? 1: 0))
#define TCP_REG(pcbs, npcb) do { \
			    (npcb)->next = *(pcbs);\
			    *(pcbs) = (npcb);\
			    } while(0)
#define TCP_RMV(pcbs, npcb) do { \
			    if(*(pcbs) == (npcb)) { \
			       *(pcbs) = (*(pcbs))->next; \
			    } else for(tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
			       if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == (npcb)) { \
				  tcp_tmp_pcb->next = (npcb)->next; \
				  break; \
			       } \
			    } \
			    (npcb)->next = NULL; \
			    } while(0)
/*tcp_ack just ack seqno and don't send data if ACK_DELAY have beed set*/
#define tcp_ack(pcb)	 if((pcb)->flags & TF_ACK_DELAY) { \
			    (pcb)->flags |= TF_ACK_NOW; \
			    tcp_output(pcb); \
			 } else { \
			    (pcb)->flags |= TF_ACK_DELAY; \
			 }
#define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; \
                         tcp_output(pcb)
#define MIN(x,y) (x) < (y)? (x): (y)
#define UMAX(a, b)      ((a) > (b) ? (a) : (b))


/* Definitions for error constants. */

#define ERR_OK    0      /* No error, everything OK. */
#define ERR_MEM  -1      /* Out of memory error.     */
#define ERR_BUF  -2      /* Buffer error.            */


#define ERR_ABRT -3      /* Connection aborted.      */
#define ERR_RST  -4      /* Connection reset.        */
#define ERR_CLSD -5      /* Connection closed.       */
#define ERR_CONN -6      /* Not connected.           */

#define ERR_VAL  -7      /* Illegal value.           */

#define ERR_ARG  -8      /* Illegal argument.        */

#define ERR_RTE  -9      /* Routing problem.         */

#define ERR_USE  -10     /* Address in use.          */

		
extern u32_t	tcp_ticks;
extern tcp_pcb_t	*ptcp_active_chain;
extern tcp_pcb_t	*ptcp_listen_chain;
extern tcp_pcb_t	*ptcp_tw_chain;
	
extern void tcp_init(void);
extern void tcp_input(znetif_t *pnetif, zbuffer_t *pbuffer);
extern u8_t	tcp_open(zsocket_t *psocket);
extern u8_t	tcp_listen(zsocket_t *psocket);
extern s8_t	tcp_accept(zsocket_t *psocket);
extern u8_t tcp_recv(zsocket_t *psocket, zbuffer_t **ppbuffer, u8_t flags);
extern u8_t	tcp_send(zsocket_t *psocket, u8_t *pdata, u16_t *len, u8_t flags);
extern u8_t tcp_close(zsocket_t *psocket);
extern void tcp_debug(s8_t id, u8_t cmd);

extern void tcp_tmr(void *pdata);

extern tcp_pcb_t *tcp_pcb_new(zsocket_t *psocket);
extern void tcp_pcb_delete(tcp_pcb_t *ptcp);
extern tcp_pcb_t *tcp_pcb_query(s8_t id);
extern void tcp_pcb_dump(tcp_pcb_t *ptcp);
extern void tcp_pcb_remove(tcp_pcb_t **pplist, tcp_pcb_t *ptcp);
extern void tcp_pcb_clean(tcp_pcb_t *ptcp);
extern void tcp_abort(tcp_pcb_t *ptcp, zbuffer_t *pbuffer);
extern s8_t tcp_pcb_close(tcp_pcb_t *ptcp);

s8_t tcp_insert_queue( tcp_pcb_t *ptcp, void *pdata, u16_t data_len, u8_t flags,u8_t *optdata, u8_t opt_len);
extern tcp_seg_t *tcp_seg_new(void);
void tcp_rexmit_seg(tcp_pcb_t *ptcp, tcp_seg_t *seg);
extern void tcp_seg_dump(tcp_seg_t *pseg);
extern void tcp_seg_delete(tcp_seg_t *pseg);

extern u8_t tcp_reset(znetif_t *pnetif, ip_header_t *pipheader, tcp_header_t *ptcpheader);
extern u8_t tcp_ip_out(znetif_t *pnetif, ipaddr_t *pdest_ip, ipaddr_t *psrc_ip,zbuffer_t * pbuffer);
extern s8_t tcp_output(tcp_pcb_t *ptcp);
#endif