50 |
|
|
51 |
/* Lower layer interface to TCP: */ |
/* Lower layer interface to TCP: */ |
52 |
void tcp_init (void); /* Must be called first to |
void tcp_init (void); /* Must be called first to |
53 |
initialize TCP. */ |
initialize TCP. */ |
54 |
void tcp_tmr (void); /* Must be called every |
void tcp_tmr (void); /* Must be called every |
55 |
TCP_TMR_INTERVAL |
TCP_TMR_INTERVAL |
56 |
ms. (Typically 100 ms). */ |
ms. (Typically 100 ms). */ |
57 |
/* Application program's interface: */ |
/* Application program's interface: */ |
58 |
struct tcp_pcb * tcp_new (void); |
struct tcp_pcb * tcp_new (void); |
59 |
struct tcp_pcb * tcp_alloc (u8_t prio); |
struct tcp_pcb * tcp_alloc (u8_t prio); |
60 |
|
|
61 |
void tcp_arg (struct tcp_pcb *pcb, void *arg); |
void tcp_arg (struct tcp_pcb *pcb, void *arg); |
62 |
void tcp_accept (struct tcp_pcb *pcb, |
void tcp_accept (struct tcp_pcb *pcb, |
63 |
err_t (* accept)(void *arg, struct tcp_pcb *newpcb, |
err_t (* accept)(void *arg, struct tcp_pcb *newpcb, |
64 |
err_t err)); |
err_t err)); |
65 |
void tcp_recv (struct tcp_pcb *pcb, |
void tcp_recv (struct tcp_pcb *pcb, |
66 |
err_t (* recv)(void *arg, struct tcp_pcb *tpcb, |
err_t (* recv)(void *arg, struct tcp_pcb *tpcb, |
67 |
struct pbuf *p, err_t err)); |
struct pbuf *p, err_t err)); |
68 |
void tcp_sent (struct tcp_pcb *pcb, |
void tcp_sent (struct tcp_pcb *pcb, |
69 |
err_t (* sent)(void *arg, struct tcp_pcb *tpcb, |
err_t (* sent)(void *arg, struct tcp_pcb *tpcb, |
70 |
u16_t len)); |
u16_t len)); |
71 |
void tcp_poll (struct tcp_pcb *pcb, |
void tcp_poll (struct tcp_pcb *pcb, |
72 |
err_t (* poll)(void *arg, struct tcp_pcb *tpcb), |
err_t (* poll)(void *arg, struct tcp_pcb *tpcb), |
73 |
u8_t interval); |
u8_t interval); |
74 |
void tcp_err (struct tcp_pcb *pcb, |
void tcp_err (struct tcp_pcb *pcb, |
75 |
void (* err)(void *arg, err_t err)); |
void (* err)(void *arg, err_t err)); |
76 |
|
|
77 |
#define tcp_mss(pcb) ((pcb)->mss) |
#define tcp_mss(pcb) ((pcb)->mss) |
78 |
#define tcp_sndbuf(pcb) ((pcb)->snd_buf) |
#define tcp_sndbuf(pcb) ((pcb)->snd_buf) |
79 |
|
|
80 |
void tcp_recved (struct tcp_pcb *pcb, u16_t len); |
void tcp_recved (struct tcp_pcb *pcb, u16_t len); |
81 |
err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr, |
err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr, |
82 |
u16_t port); |
u16_t port); |
83 |
err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr, |
err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr, |
84 |
u16_t port, err_t (* connected)(void *arg, |
u16_t port, err_t (* connected)(void *arg, |
85 |
struct tcp_pcb *tpcb, |
struct tcp_pcb *tpcb, |
86 |
err_t err)); |
err_t err)); |
87 |
struct tcp_pcb * tcp_listen (struct tcp_pcb *pcb); |
struct tcp_pcb * tcp_listen (struct tcp_pcb *pcb); |
88 |
void tcp_abort (struct tcp_pcb *pcb); |
void tcp_abort (struct tcp_pcb *pcb); |
89 |
err_t tcp_close (struct tcp_pcb *pcb); |
err_t tcp_close (struct tcp_pcb *pcb); |
90 |
err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, |
err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, |
91 |
u8_t copy); |
u8_t copy); |
92 |
|
|
93 |
void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); |
void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); |
94 |
|
|
175 |
#define TCPH_FLAGS_SET(hdr, flags) (hdr)->_offset_flags = htons((TCPH_OFFSET(hdr) << 8) | (flags)) |
#define TCPH_FLAGS_SET(hdr, flags) (hdr)->_offset_flags = htons((TCPH_OFFSET(hdr) << 8) | (flags)) |
176 |
|
|
177 |
#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \ |
#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \ |
178 |
TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0)) |
TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0)) |
179 |
|
|
180 |
enum tcp_state { |
enum tcp_state { |
181 |
CLOSED = 0, |
CLOSED = 0, |
247 |
snd_max, /* Highest seqno sent. */ |
snd_max, /* Highest seqno sent. */ |
248 |
snd_wnd, /* sender window */ |
snd_wnd, /* sender window */ |
249 |
snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last |
snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last |
250 |
window update. */ |
window update. */ |
251 |
snd_lbb; /* Sequence number of next byte to be buffered. */ |
snd_lbb; /* Sequence number of next byte to be buffered. */ |
252 |
|
|
253 |
u16_t acked; |
u16_t acked; |
315 |
}; |
}; |
316 |
|
|
317 |
err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, |
err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, |
318 |
enum lwip_event, |
enum lwip_event, |
319 |
struct pbuf *p, |
struct pbuf *p, |
320 |
u16_t size, |
u16_t size, |
321 |
err_t err); |
err_t err); |
322 |
|
|
323 |
#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
324 |
LWIP_EVENT_ACCEPT, NULL, 0, err) |
LWIP_EVENT_ACCEPT, NULL, 0, err) |
325 |
#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
326 |
LWIP_EVENT_SENT, NULL, space, ERR_OK) |
LWIP_EVENT_SENT, NULL, space, ERR_OK) |
327 |
#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
328 |
LWIP_EVENT_RECV, (p), 0, (err)) |
LWIP_EVENT_RECV, (p), 0, (err)) |
329 |
#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
330 |
LWIP_EVENT_CONNECTED, NULL, 0, (err)) |
LWIP_EVENT_CONNECTED, NULL, 0, (err)) |
331 |
#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ |
332 |
LWIP_EVENT_POLL, NULL, 0, ERR_OK) |
LWIP_EVENT_POLL, NULL, 0, ERR_OK) |
333 |
#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ |
#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ |
334 |
LWIP_EVENT_ERR, NULL, 0, (err)) |
LWIP_EVENT_ERR, NULL, 0, (err)) |
335 |
#else /* LWIP_EVENT_API */ |
#else /* LWIP_EVENT_API */ |
336 |
#define TCP_EVENT_ACCEPT(pcb,err,ret) \ |
#define TCP_EVENT_ACCEPT(pcb,err,ret) \ |
337 |
if((pcb)->accept != NULL) \ |
if((pcb)->accept != NULL) \ |
342 |
#define TCP_EVENT_RECV(pcb,p,err,ret) \ |
#define TCP_EVENT_RECV(pcb,p,err,ret) \ |
343 |
if((pcb)->recv != NULL) \ |
if((pcb)->recv != NULL) \ |
344 |
{ ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { \ |
{ ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { \ |
345 |
pbuf_free(p); } |
pbuf_free(p); } |
346 |
#define TCP_EVENT_CONNECTED(pcb,err,ret) \ |
#define TCP_EVENT_CONNECTED(pcb,err,ret) \ |
347 |
if((pcb)->connected != NULL) \ |
if((pcb)->connected != NULL) \ |
348 |
(ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err))) |
(ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err))) |
385 |
|
|
386 |
err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags); |
err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags); |
387 |
err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len, |
err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len, |
388 |
u8_t flags, u8_t copy, |
u8_t flags, u8_t copy, |
389 |
u8_t *optdata, u8_t optlen); |
u8_t *optdata, u8_t optlen); |
390 |
|
|
391 |
void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); |
void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); |
392 |
|
|
393 |
void tcp_rst(u32_t seqno, u32_t ackno, |
void tcp_rst(u32_t seqno, u32_t ackno, |
394 |
struct ip_addr *local_ip, struct ip_addr *remote_ip, |
struct ip_addr *local_ip, struct ip_addr *remote_ip, |
395 |
u16_t local_port, u16_t remote_port); |
u16_t local_port, u16_t remote_port); |
396 |
|
|
397 |
u32_t tcp_next_iss(void); |
u32_t tcp_next_iss(void); |
398 |
|
|
418 |
/* The TCP PCB lists. */ |
/* The TCP PCB lists. */ |
419 |
extern struct tcp_pcb_listen *tcp_listen_pcbs; /* List of all TCP PCBs in LISTEN state. */ |
extern struct tcp_pcb_listen *tcp_listen_pcbs; /* List of all TCP PCBs in LISTEN state. */ |
420 |
extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a |
extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a |
421 |
state in which they accept or send |
state in which they accept or send |
422 |
data. */ |
data. */ |
423 |
extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ |
extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ |
424 |
|
|
425 |
extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ |
extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ |
437 |
#define TCP_REG(pcbs, npcb) do {\ |
#define TCP_REG(pcbs, npcb) do {\ |
438 |
DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \ |
DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \ |
439 |
for(tcp_tmp_pcb = *pcbs; \ |
for(tcp_tmp_pcb = *pcbs; \ |
440 |
tcp_tmp_pcb != NULL; \ |
tcp_tmp_pcb != NULL; \ |
441 |
tcp_tmp_pcb = tcp_tmp_pcb->next) { \ |
tcp_tmp_pcb = tcp_tmp_pcb->next) { \ |
442 |
LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \ |
LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \ |
443 |
} \ |
} \ |
444 |
LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \ |
LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \ |
446 |
LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \ |
LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \ |
447 |
*(pcbs) = npcb; \ |
*(pcbs) = npcb; \ |
448 |
LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ |
LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ |
449 |
tcp_timer_needed(); \ |
tcp_timer_needed(); \ |
450 |
} while(0) |
} while(0) |
451 |
#define TCP_RMV(pcbs, npcb) do { \ |
#define TCP_RMV(pcbs, npcb) do { \ |
452 |
LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \ |
LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \ |
468 |
#define TCP_REG(pcbs, npcb) do { \ |
#define TCP_REG(pcbs, npcb) do { \ |
469 |
npcb->next = *pcbs; \ |
npcb->next = *pcbs; \ |
470 |
*(pcbs) = npcb; \ |
*(pcbs) = npcb; \ |
471 |
tcp_timer_needed(); \ |
tcp_timer_needed(); \ |
472 |
} while(0) |
} while(0) |
473 |
#define TCP_RMV(pcbs, npcb) do { \ |
#define TCP_RMV(pcbs, npcb) do { \ |
474 |
if(*(pcbs) == npcb) { \ |
if(*(pcbs) == npcb) { \ |