Warning, cross-references for /kernel/include/lwip/tcp.h need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #ifndef __LWIP_TCP_H__
0033 #define __LWIP_TCP_H__
0034
0035 #include "lwip/opt.h"
0036
0037 #if LWIP_TCP
0038
0039 #include "lwip/sys.h"
0040 #include "lwip/mem.h"
0041 #include "lwip/pbuf.h"
0042 #include "lwip/ip.h"
0043 #include "lwip/icmp.h"
0044 #include "lwip/err.h"
0045
0046 #ifdef __cplusplus
0047 extern "C" {
0048 #endif
0049
0050 struct tcp_pcb;
0051
0052
0053
0054
0055 #define tcp_init()
0056 void tcp_tmr (void);
0057
0058
0059
0060 struct tcp_pcb * tcp_new (void);
0061 struct tcp_pcb * tcp_alloc (u8_t prio);
0062
0063 void tcp_arg (struct tcp_pcb *pcb, void *arg);
0064 void tcp_accept (struct tcp_pcb *pcb,
0065 err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
0066 err_t err));
0067 void tcp_recv (struct tcp_pcb *pcb,
0068 err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
0069 struct pbuf *p, err_t err));
0070 void tcp_sent (struct tcp_pcb *pcb,
0071 err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
0072 u16_t len));
0073 void tcp_poll (struct tcp_pcb *pcb,
0074 err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
0075 u8_t interval);
0076 void tcp_err (struct tcp_pcb *pcb,
0077 void (* err)(void *arg, err_t err));
0078
0079 #define tcp_mss(pcb) ((pcb)->mss)
0080 #define tcp_sndbuf(pcb) ((pcb)->snd_buf)
0081 #define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY)
0082 #define tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY)
0083 #define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0)
0084
0085 #if TCP_LISTEN_BACKLOG
0086 #define tcp_accepted(pcb) (((struct tcp_pcb_listen *)(pcb))->accepts_pending--)
0087 #else
0088 #define tcp_accepted(pcb)
0089 #endif
0090
0091 void tcp_recved (struct tcp_pcb *pcb, u16_t len);
0092 err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
0093 u16_t port);
0094 err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
0095 u16_t port, err_t (* connected)(void *arg,
0096 struct tcp_pcb *tpcb,
0097 err_t err));
0098
0099 struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
0100 #define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)
0101
0102 void tcp_abandon (struct tcp_pcb *pcb, int reset);
0103 #define tcp_abort(pcb) tcp_abandon((pcb), 1)
0104 err_t tcp_close (struct tcp_pcb *pcb);
0105
0106
0107 #define TCP_WRITE_FLAG_COPY 0x01
0108 #define TCP_WRITE_FLAG_MORE 0x02
0109
0110 err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
0111 u8_t apiflags);
0112
0113 void tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
0114
0115 #define TCP_PRIO_MIN 1
0116 #define TCP_PRIO_NORMAL 64
0117 #define TCP_PRIO_MAX 127
0118
0119
0120
0121 void tcp_slowtmr (void);
0122 void tcp_fasttmr (void);
0123
0124
0125
0126 void tcp_input (struct pbuf *p, struct netif *inp);
0127
0128 err_t tcp_send_empty_ack(struct tcp_pcb *pcb);
0129 err_t tcp_output (struct tcp_pcb *pcb);
0130 void tcp_rexmit (struct tcp_pcb *pcb);
0131 void tcp_rexmit_rto (struct tcp_pcb *pcb);
0132 void tcp_rexmit_fast (struct tcp_pcb *pcb);
0133 u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb);
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 #define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \
0145 ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
0146 (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
0147 ((tpcb)->unsent->len >= (tpcb)->mss))) \
0148 ) ? 1 : 0)
0149 #define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
0150
0151
0152 #define TCP_SEQ_LT(a,b) ((s32_t)((a)-(b)) < 0)
0153 #define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0)
0154 #define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0)
0155 #define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0)
0156
0157 #if 0
0158 #define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
0159 #endif
0160 #define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
0161 #define TCP_FIN 0x01U
0162 #define TCP_SYN 0x02U
0163 #define TCP_RST 0x04U
0164 #define TCP_PSH 0x08U
0165 #define TCP_ACK 0x10U
0166 #define TCP_URG 0x20U
0167 #define TCP_ECE 0x40U
0168 #define TCP_CWR 0x80U
0169
0170 #define TCP_FLAGS 0x3fU
0171
0172
0173 #define TCP_HLEN 20
0174
0175 #ifndef TCP_TMR_INTERVAL
0176 #define TCP_TMR_INTERVAL 250
0177 #endif
0178
0179 #ifndef TCP_FAST_INTERVAL
0180 #define TCP_FAST_INTERVAL TCP_TMR_INTERVAL
0181 #endif
0182
0183 #ifndef TCP_SLOW_INTERVAL
0184 #define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL)
0185 #endif
0186
0187 #define TCP_FIN_WAIT_TIMEOUT 20000
0188 #define TCP_SYN_RCVD_TIMEOUT 20000
0189
0190 #define TCP_OOSEQ_TIMEOUT 6U
0191
0192 #ifndef TCP_MSL
0193 #define TCP_MSL 60000UL
0194 #endif
0195
0196
0197 #ifndef TCP_KEEPIDLE_DEFAULT
0198 #define TCP_KEEPIDLE_DEFAULT 7200000UL
0199 #endif
0200
0201 #ifndef TCP_KEEPINTVL_DEFAULT
0202 #define TCP_KEEPINTVL_DEFAULT 75000UL
0203 #endif
0204
0205 #ifndef TCP_KEEPCNT_DEFAULT
0206 #define TCP_KEEPCNT_DEFAULT 9U
0207 #endif
0208
0209 #define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT
0210
0211
0212
0213
0214 #ifdef PACK_STRUCT_USE_INCLUDES
0215 # include "arch/bpstruct.h"
0216 #endif
0217 PACK_STRUCT_BEGIN
0218 struct tcp_hdr {
0219 PACK_STRUCT_FIELD(u16_t src);
0220 PACK_STRUCT_FIELD(u16_t dest);
0221 PACK_STRUCT_FIELD(u32_t seqno);
0222 PACK_STRUCT_FIELD(u32_t ackno);
0223 PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
0224 PACK_STRUCT_FIELD(u16_t wnd);
0225 PACK_STRUCT_FIELD(u16_t chksum);
0226 PACK_STRUCT_FIELD(u16_t urgp);
0227 } PACK_STRUCT_STRUCT;
0228 PACK_STRUCT_END
0229 #ifdef PACK_STRUCT_USE_INCLUDES
0230 # include "arch/epstruct.h"
0231 #endif
0232
0233 #define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)
0234 #define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
0235 #define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
0236
0237 #define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))
0238 #define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
0239 #define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & htons((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags))
0240 #define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags))
0241 #define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
0242
0243 #define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0))
0244
0245 enum tcp_state {
0246 CLOSED = 0,
0247 LISTEN = 1,
0248 SYN_SENT = 2,
0249 SYN_RCVD = 3,
0250 ESTABLISHED = 4,
0251 FIN_WAIT_1 = 5,
0252 FIN_WAIT_2 = 6,
0253 CLOSE_WAIT = 7,
0254 CLOSING = 8,
0255 LAST_ACK = 9,
0256 TIME_WAIT = 10
0257 };
0258
0259
0260
0261 #define TF_RESET (u8_t)0x08U
0262 #define TF_CLOSED (u8_t)0x10U
0263 #define TF_GOT_FIN (u8_t)0x20U
0264
0265
0266 #if LWIP_CALLBACK_API
0267
0268
0269
0270
0271
0272
0273
0274 #define DEF_ACCEPT_CALLBACK err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err)
0275 #else
0276 #define DEF_ACCEPT_CALLBACK
0277 #endif
0278
0279
0280
0281
0282 #define TCP_PCB_COMMON(type) \
0283 type *next; \
0284 enum tcp_state state; \
0285 u8_t prio; \
0286 void *callback_arg; \
0287 \
0288 u16_t local_port; \
0289 \
0290 DEF_ACCEPT_CALLBACK
0291
0292
0293
0294 struct tcp_pcb {
0295
0296 IP_PCB;
0297
0298 TCP_PCB_COMMON(struct tcp_pcb);
0299
0300
0301 u16_t remote_port;
0302
0303 u8_t flags;
0304 #define TF_ACK_DELAY ((u8_t)0x01U)
0305 #define TF_ACK_NOW ((u8_t)0x02U)
0306 #define TF_INFR ((u8_t)0x04U)
0307 #define TF_TIMESTAMP ((u8_t)0x08U)
0308 #define TF_FIN ((u8_t)0x20U)
0309 #define TF_NODELAY ((u8_t)0x40U)
0310 #define TF_NAGLEMEMERR ((u8_t)0x80U)
0311
0312
0313
0314
0315 u32_t rcv_nxt;
0316 u16_t rcv_wnd;
0317 u16_t rcv_ann_wnd;
0318 u32_t rcv_ann_right_edge;
0319
0320
0321 u32_t tmr;
0322 u8_t polltmr, pollinterval;
0323
0324
0325 s16_t rtime;
0326
0327 u16_t mss;
0328
0329
0330 u32_t rttest;
0331 u32_t rtseq;
0332 s16_t sa, sv;
0333
0334 s16_t rto;
0335 u8_t nrtx;
0336
0337
0338 u32_t lastack;
0339 u8_t dupacks;
0340
0341
0342 u16_t cwnd;
0343 u16_t ssthresh;
0344
0345
0346 u32_t snd_nxt;
0347 u16_t snd_wnd;
0348 u32_t snd_wl1, snd_wl2;
0349
0350 u32_t snd_lbb;
0351
0352 u16_t acked;
0353
0354 u16_t snd_buf;
0355 #define TCP_SNDQUEUELEN_OVERFLOW (0xffff-3)
0356 u16_t snd_queuelen;
0357
0358
0359
0360 struct tcp_seg *unsent;
0361 struct tcp_seg *unacked;
0362 #if TCP_QUEUE_OOSEQ
0363 struct tcp_seg *ooseq;
0364 #endif
0365
0366 struct pbuf *refused_data;
0367
0368 #if LWIP_CALLBACK_API
0369
0370
0371
0372
0373
0374
0375 err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);
0376
0377
0378
0379
0380
0381
0382
0383
0384 err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
0385
0386
0387
0388
0389
0390
0391
0392 err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);
0393
0394
0395
0396
0397
0398
0399
0400
0401 err_t (* poll)(void *arg, struct tcp_pcb *pcb);
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411 void (* errf)(void *arg, err_t err);
0412 #endif
0413
0414 #if LWIP_TCP_TIMESTAMPS
0415 u32_t ts_lastacksent;
0416 u32_t ts_recent;
0417 #endif
0418
0419
0420 u32_t keep_idle;
0421 #if LWIP_TCP_KEEPALIVE
0422 u32_t keep_intvl;
0423 u32_t keep_cnt;
0424 #endif
0425
0426
0427 u32_t persist_cnt;
0428
0429 u8_t persist_backoff;
0430
0431
0432 u8_t keep_cnt_sent;
0433 };
0434
0435 struct tcp_pcb_listen {
0436
0437 IP_PCB;
0438
0439 TCP_PCB_COMMON(struct tcp_pcb_listen);
0440
0441 #if TCP_LISTEN_BACKLOG
0442 u8_t backlog;
0443 u8_t accepts_pending;
0444 #endif
0445 };
0446
0447 #if LWIP_EVENT_API
0448
0449 enum lwip_event {
0450 LWIP_EVENT_ACCEPT,
0451 LWIP_EVENT_SENT,
0452 LWIP_EVENT_RECV,
0453 LWIP_EVENT_CONNECTED,
0454 LWIP_EVENT_POLL,
0455 LWIP_EVENT_ERR
0456 };
0457
0458 err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
0459 enum lwip_event,
0460 struct pbuf *p,
0461 u16_t size,
0462 err_t err);
0463
0464 #define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
0465 LWIP_EVENT_ACCEPT, NULL, 0, err)
0466 #define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
0467 LWIP_EVENT_SENT, NULL, space, ERR_OK)
0468 #define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
0469 LWIP_EVENT_RECV, (p), 0, (err))
0470 #define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
0471 LWIP_EVENT_CONNECTED, NULL, 0, (err))
0472 #define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
0473 LWIP_EVENT_POLL, NULL, 0, ERR_OK)
0474 #define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \
0475 LWIP_EVENT_ERR, NULL, 0, (err))
0476 #else
0477
0478 #define TCP_EVENT_ACCEPT(pcb,err,ret) \
0479 do { \
0480 if((pcb)->accept != NULL) \
0481 (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \
0482 else (ret) = ERR_OK; \
0483 } while (0)
0484
0485 #define TCP_EVENT_SENT(pcb,space,ret) \
0486 do { \
0487 if((pcb)->sent != NULL) \
0488 (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \
0489 else (ret) = ERR_OK; \
0490 } while (0)
0491
0492 #define TCP_EVENT_RECV(pcb,p,err,ret) \
0493 do { \
0494 if((pcb)->recv != NULL) { \
0495 (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); \
0496 } else { \
0497 (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \
0498 } \
0499 } while (0)
0500
0501 #define TCP_EVENT_CONNECTED(pcb,err,ret) \
0502 do { \
0503 if((pcb)->connected != NULL) \
0504 (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \
0505 else (ret) = ERR_OK; \
0506 } while (0)
0507
0508 #define TCP_EVENT_POLL(pcb,ret) \
0509 do { \
0510 if((pcb)->poll != NULL) \
0511 (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \
0512 else (ret) = ERR_OK; \
0513 } while (0)
0514
0515 #define TCP_EVENT_ERR(errf,arg,err) \
0516 do { \
0517 if((errf) != NULL) \
0518 (errf)((arg),(err)); \
0519 } while (0)
0520
0521 #endif
0522
0523
0524 struct tcp_seg {
0525 struct tcp_seg *next;
0526 struct pbuf *p;
0527 void *dataptr;
0528 u16_t len;
0529 u8_t flags;
0530 #define TF_SEG_OPTS_MSS (u8_t)0x01U
0531 #define TF_SEG_OPTS_TS (u8_t)0x02U
0532 struct tcp_hdr *tcphdr;
0533 };
0534
0535 #define LWIP_TCP_OPT_LENGTH(flags) \
0536 (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \
0537 (flags & TF_SEG_OPTS_TS ? 12 : 0)
0538
0539
0540 #define TCP_BUILD_MSS_OPTION(x) (x) = htonl(((u32_t)2 << 24) | \
0541 ((u32_t)4 << 16) | \
0542 (((u32_t)TCP_MSS / 256) << 8) | \
0543 (TCP_MSS & 255))
0544
0545
0546 struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
0547 void tcp_pcb_purge(struct tcp_pcb *pcb);
0548 void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
0549
0550 u8_t tcp_segs_free(struct tcp_seg *seg);
0551 u8_t tcp_seg_free(struct tcp_seg *seg);
0552 struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
0553
0554 #define tcp_ack(pcb) \
0555 do { \
0556 if((pcb)->flags & TF_ACK_DELAY) { \
0557 (pcb)->flags &= ~TF_ACK_DELAY; \
0558 (pcb)->flags |= TF_ACK_NOW; \
0559 tcp_output(pcb); \
0560 } \
0561 else { \
0562 (pcb)->flags |= TF_ACK_DELAY; \
0563 } \
0564 } while (0)
0565
0566 #define tcp_ack_now(pcb) \
0567 do { \
0568 (pcb)->flags |= TF_ACK_NOW; \
0569 tcp_output(pcb); \
0570 } while (0)
0571
0572 err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);
0573 err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,
0574 u8_t flags, u8_t apiflags, u8_t optflags);
0575
0576 void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
0577
0578 void tcp_rst(u32_t seqno, u32_t ackno,
0579 struct ip_addr *local_ip, struct ip_addr *remote_ip,
0580 u16_t local_port, u16_t remote_port);
0581
0582 u32_t tcp_next_iss(void);
0583
0584 void tcp_keepalive(struct tcp_pcb *pcb);
0585 void tcp_zero_window_probe(struct tcp_pcb *pcb);
0586
0587 #if TCP_CALCULATE_EFF_SEND_MSS
0588 u16_t tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr);
0589 #endif
0590
0591 #if LWIP_CALLBACK_API
0592 err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
0593 #endif
0594
0595 extern struct tcp_pcb *tcp_input_pcb;
0596 extern u32_t tcp_ticks;
0597
0598 const char* tcp_debug_state_str(enum tcp_state s);
0599 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
0600 void tcp_debug_print(struct tcp_hdr *tcphdr);
0601 void tcp_debug_print_flags(u8_t flags);
0602 void tcp_debug_print_state(enum tcp_state s);
0603 void tcp_debug_print_pcbs(void);
0604 s16_t tcp_pcbs_sane(void);
0605 #else
0606 # define tcp_debug_print(tcphdr)
0607 # define tcp_debug_print_flags(flags)
0608 # define tcp_debug_print_state(s)
0609 # define tcp_debug_print_pcbs()
0610 # define tcp_pcbs_sane() 1
0611 #endif
0612
0613 #if NO_SYS
0614 #define tcp_timer_needed()
0615 #else
0616 void tcp_timer_needed(void);
0617 #endif
0618
0619
0620 union tcp_listen_pcbs_t {
0621 struct tcp_pcb_listen *listen_pcbs;
0622 struct tcp_pcb *pcbs;
0623 };
0624 extern union tcp_listen_pcbs_t tcp_listen_pcbs;
0625 extern struct tcp_pcb *tcp_active_pcbs;
0626
0627
0628 extern struct tcp_pcb *tcp_tw_pcbs;
0629
0630 extern struct tcp_pcb *tcp_tmp_pcb;
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641 #if 0
0642 #define TCP_REG(pcbs, npcb) do {\
0643 LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \
0644 for(tcp_tmp_pcb = *pcbs; \
0645 tcp_tmp_pcb != NULL; \
0646 tcp_tmp_pcb = tcp_tmp_pcb->next) { \
0647 LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \
0648 } \
0649 LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
0650 npcb->next = *pcbs; \
0651 LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
0652 *(pcbs) = npcb; \
0653 LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
0654 tcp_timer_needed(); \
0655 } while(0)
0656 #define TCP_RMV(pcbs, npcb) do { \
0657 LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \
0658 LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \
0659 if(*pcbs == npcb) { \
0660 *pcbs = (*pcbs)->next; \
0661 } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
0662 if(tcp_tmp_pcb->next == npcb) { \
0663 tcp_tmp_pcb->next = npcb->next; \
0664 break; \
0665 } \
0666 } \
0667 npcb->next = NULL; \
0668 LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
0669 LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \
0670 } while(0)
0671
0672 #else
0673
0674 #define TCP_REG(pcbs, npcb) \
0675 do { \
0676 npcb->next = *pcbs; \
0677 *(pcbs) = npcb; \
0678 tcp_timer_needed(); \
0679 } while (0)
0680
0681 #define TCP_RMV(pcbs, npcb) \
0682 do { \
0683 if(*(pcbs) == npcb) { \
0684 (*(pcbs)) = (*pcbs)->next; \
0685 } \
0686 else { \
0687 for(tcp_tmp_pcb = *pcbs; \
0688 tcp_tmp_pcb != NULL; \
0689 tcp_tmp_pcb = tcp_tmp_pcb->next) { \
0690 if(tcp_tmp_pcb->next == npcb) { \
0691 tcp_tmp_pcb->next = npcb->next; \
0692 break; \
0693 } \
0694 } \
0695 } \
0696 npcb->next = NULL; \
0697 } while(0)
0698
0699 #endif
0700
0701 #ifdef __cplusplus
0702 }
0703 #endif
0704
0705 #endif
0706
0707 #endif