Free (GPLv2) TCP/IP stack developed by TASS Belgium
Fork of PicoTCP by
Revision 31:d3b2dfcc358f, committed 2013-06-12
- Comitter:
- tass
- Date:
- Wed Jun 12 13:35:01 2013 +0000
- Parent:
- 25:d63125298eb3
- Commit message:
- updated pico_tcp and pico_socket after the mainline.
Changed in this revision
--- a/Socket/Socket.cpp Tue Jun 11 23:28:50 2013 +0000 +++ b/Socket/Socket.cpp Wed Jun 12 13:35:01 2013 +0000 @@ -34,9 +34,7 @@ using std::memset; Socket::Socket() : _ep(NULL), _blocking(true) -{ - //set_blocking(true,1500); // ? -} +{} void Socket::set_blocking(bool blocking, unsigned int timeout) { _blocking = blocking; @@ -84,6 +82,8 @@ return -1; picotcp_close(_ep); + delete(_ep->CallResponseQueue); + delete(_ep->CallActivateQueue); pico_free(_ep); _ep = NULL; @@ -92,7 +92,12 @@ Socket::~Socket() { if(_ep) + { + delete(_ep->CallResponseQueue); + delete(_ep->CallActivateQueue); pico_free(_ep); + _ep = NULL; + } } TimeInterval::TimeInterval(unsigned int ms) {
--- a/Socket/TCPSocketServer.cpp Tue Jun 11 23:28:50 2013 +0000 +++ b/Socket/TCPSocketServer.cpp Wed Jun 12 13:35:01 2013 +0000 @@ -60,8 +60,7 @@ int TCPSocketServer::listen(int max) { if (_ep < 0) return -1; - - if (picotcp_listen(_ep, max) < 0) { + if (picotcp_listen(_ep, max) < 0) { close(); return -1; }
--- a/Socket/bsd/proxy_endpoint.cpp Tue Jun 11 23:28:50 2013 +0000 +++ b/Socket/bsd/proxy_endpoint.cpp Wed Jun 12 13:35:01 2013 +0000 @@ -38,6 +38,7 @@ ep = (struct stack_endpoint *)evt.value.p; if (ep->retval == 0) ep->state = SOCK_OPEN; + return ep; } return NULL; @@ -54,6 +55,8 @@ { osStatus st; osEvent evt; + //if(!ep->s) + // return -1; pt_proxy_dbg("Call in progress... (%x)\n", ep->pending); st = ep->CallActivateQueue->put(ep); pt_proxy_dbg("Waiting... (put returned %x)\n", st);
--- a/Socket/bsd/stack_endpoint.cpp Tue Jun 11 23:28:50 2013 +0000 +++ b/Socket/bsd/stack_endpoint.cpp Wed Jun 12 13:35:01 2013 +0000 @@ -198,7 +198,6 @@ static void retry_write(struct stack_endpoint *ep) { - if (ep->pending == NO_COMMAND) return; @@ -446,7 +445,7 @@ Ticker *picotcpTicker = new Ticker(); if (serverThread == NULL) { printf (" *** PicoTCP initialized *** \n"); - serverThread = new Thread(pico_wrapper_loop); + serverThread = new Thread(pico_wrapper_loop,NULL,osPriorityNormal,4096); serverThread->set_priority(osPriorityIdle); //picotcpTicker->attach(&pico_stack_tick, 0.001); }
--- a/include/arch/pico_mbed.h Tue Jun 11 23:28:50 2013 +0000 +++ b/include/arch/pico_mbed.h Wed Jun 12 13:35:01 2013 +0000 @@ -26,6 +26,7 @@ #define pico_zalloc(x) calloc(x, 1) #define pico_free(x) free(x) + #ifdef MEMORY_MEASURE // in case, comment out the two defines above me. extern uint32_t max_mem; extern uint32_t cur_mem; @@ -43,6 +44,7 @@ max_mem = cur_mem; printf("max mem: %lu\n", max_mem); } + return (void*)(ptr + 1); }
--- a/modules/pico_tcp.c Tue Jun 11 23:28:50 2013 +0000 +++ b/modules/pico_tcp.c Wed Jun 12 13:35:01 2013 +0000 @@ -61,6 +61,7 @@ #endif + static inline int seq_compare(uint32_t a, uint32_t b) { uint32_t thresh = ((uint32_t)(-1))>>1; @@ -213,8 +214,11 @@ uint8_t x_mode; uint8_t dupacks; uint8_t backoff; + /* Close wait flag */ + uint8_t closing; +}; -}; +static void checkIfQueueEmptyAndFin(struct pico_socket_tcp * t); /* Queues */ static struct pico_queue tcp_in = {}; @@ -710,7 +714,7 @@ if (in_frame_len > f->payload_len - in_frame_off) in_frame_len = f->payload_len - in_frame_off; - memcpy(buf + tot_rd_len, f->payload + in_frame_off, in_frame_len); + memcpy((uint8_t *)buf + tot_rd_len, f->payload + in_frame_off, in_frame_len); tot_rd_len += in_frame_len; t->rcv_processed += in_frame_len; @@ -1041,6 +1045,44 @@ t->snd_nxt++; } +/*****/ +static inline void checkIfQueueEmptyAndFin(struct pico_socket_tcp * t) +{ + struct pico_socket *s =(struct pico_socket *)&t->sock; + if(t->closing && t->tcpq_out.frames==0) + { + s->state &= 0x00FFU; + /* set SHUT_REMOTE */ + s->state |= PICO_SOCKET_STATE_SHUT_REMOTE; + s->state |= PICO_SOCKET_STATE_TCP_CLOSE_WAIT; + tcp_dbg("TCP> Close-wait\n"); + if (s->wakeup) + { + s->wakeup(PICO_SOCK_EV_CLOSE, s); + } + t->closing = 0; + } + + if ((t->tcpq_out.frames == 0) && (s->state & PICO_SOCKET_STATE_SHUT_LOCAL)) { /* if no more packets in queue, XXX replacled !f by tcpq check */ + if ((s->state & PICO_SOCKET_STATE_TCP) == PICO_SOCKET_STATE_TCP_ESTABLISHED) { + tcp_dbg("TCP> buffer empty, shutdown established ...\n"); + /* send fin if queue empty and in state shut local (write) */ + tcp_send_fin(t); + /* change tcp state to FIN_WAIT1 */ + s->state &= 0x00FFU; + s->state |= PICO_SOCKET_STATE_TCP_FIN_WAIT1; + } else if ((s->state & PICO_SOCKET_STATE_TCP) == PICO_SOCKET_STATE_TCP_CLOSE_WAIT) { + /* send fin if queue empty and in state shut local (write) */ + tcp_send_fin(t); + /* change tcp state to LAST_ACK */ + s->state &= 0x00FFU; + s->state |= PICO_SOCKET_STATE_TCP_LAST_ACK; + tcp_dbg("TCP> STATE: LAST_ACK.\n"); + } + } +} +/*****/ + static void tcp_sack_prepare(struct pico_socket_tcp *t) { struct pico_frame *pkt; @@ -1280,6 +1322,7 @@ add_retransmission_timer(t, 0); if (t->tcpq_out.size < t->tcpq_out.max_size) t->sock.ev_pending |= PICO_SOCK_EV_WR; + checkIfQueueEmptyAndFin(t); return; } } @@ -1739,19 +1782,31 @@ if (f->flags & PICO_TCP_ACK) tcp_ack(s,f); if (seq_compare(SEQN(f), t->rcv_nxt) == 0) { - /* received FIN, increase ACK nr */ - t->rcv_nxt = long_be(hdr->seq) + 1; - s->state &= 0x00FFU; - s->state |= PICO_SOCKET_STATE_TCP_CLOSE_WAIT; - /* set SHUT_REMOTE */ - s->state |= PICO_SOCKET_STATE_SHUT_REMOTE; - tcp_dbg("TCP> Close-wait\n"); - if (s->wakeup){ - if(f->payload_len>0){ - struct pico_socket_tcp *t = (struct pico_socket_tcp *)s; - t->sock.ev_pending |=PICO_SOCK_EV_CLOSE; - }else - s->wakeup(PICO_SOCK_EV_CLOSE, s); + if(t->tcpq_out.frames == 0) + { + /* received FIN, increase ACK nr */ + t->rcv_nxt = long_be(hdr->seq) + 1; + s->state &= 0x00FFU; + s->state |= PICO_SOCKET_STATE_TCP_CLOSE_WAIT; + /* set SHUT_REMOTE */ + s->state |= PICO_SOCKET_STATE_SHUT_REMOTE; + tcp_dbg("TCP> Close-wait\n"); + if (s->wakeup){ + if(f->payload_len>0){ + struct pico_socket_tcp *t = (struct pico_socket_tcp *)s; + t->sock.ev_pending |=PICO_SOCK_EV_CLOSE; + }else + s->wakeup(PICO_SOCK_EV_CLOSE, s); + } + } + else + { + if(!t->closing) + { + /* Update ACK for the first FIN */ + t->rcv_nxt = long_be(hdr->seq) + 1; + } + t->closing = 1; } } else { tcp_send_ack(t); /* return ACK */ @@ -2032,23 +2087,9 @@ // no packets in queue ?? } - if ((t->tcpq_out.frames == 0) && (s->state & PICO_SOCKET_STATE_SHUT_LOCAL)) { /* if no more packets in queue, XXX replacled !f by tcpq check */ - if ((s->state & PICO_SOCKET_STATE_TCP) == PICO_SOCKET_STATE_TCP_ESTABLISHED) { - tcp_dbg("TCP> buffer empty, shutdown established ...\n"); - /* send fin if queue empty and in state shut local (write) */ - tcp_send_fin(t); - /* change tcp state to FIN_WAIT1 */ - s->state &= 0x00FFU; - s->state |= PICO_SOCKET_STATE_TCP_FIN_WAIT1; - } else if ((s->state & PICO_SOCKET_STATE_TCP) == PICO_SOCKET_STATE_TCP_CLOSE_WAIT) { - /* send fin if queue empty and in state shut local (write) */ - tcp_send_fin(t); - /* change tcp state to LAST_ACK */ - s->state &= 0x00FFU; - s->state |= PICO_SOCKET_STATE_TCP_LAST_ACK; - tcp_dbg("TCP> STATE: LAST_ACK.\n"); - } - } + // check to see if we are in the case where FIN was received + // but we still had data in the queue (tcpq_out) + checkIfQueueEmptyAndFin(t); return loop_score; }
--- a/stack/pico_socket.c Tue Jun 11 23:28:50 2013 +0000 +++ b/stack/pico_socket.c Wed Jun 12 13:35:01 2013 +0000 @@ -1993,12 +1993,13 @@ #endif #ifdef PICO_SUPPORT_TCP if (PROTO(s) == PICO_PROTO_TCP) { - if (mode & PICO_SHUT_WR) + if(mode & PICO_SHUT_RDWR) + pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_LOCAL | PICO_SOCKET_STATE_SHUT_REMOTE, 0, 0); + else if (mode & PICO_SHUT_WR) pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_LOCAL, 0, 0); else if (mode & PICO_SHUT_RD) pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_REMOTE, 0, 0); - else if (mode & PICO_SHUT_RDWR) - pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_LOCAL | PICO_SOCKET_STATE_SHUT_REMOTE, 0, 0); + } #endif return 0;