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