Free (GPLv2) TCP/IP stack developed by TASS Belgium
Fork of PicoTCP by
Revision 35:6078073547bb, committed 2013-06-21
- Comitter:
- tass
- Date:
- Fri Jun 21 08:47:35 2013 +0000
- Parent:
- 34:d868bb69114e
- Child:
- 36:afa3ab5e06b3
- Commit message:
- Added missing functions(broadcast, multicast, udp support functions). Fixed some small things.
Changed in this revision
--- a/Socket/Socket.cpp Thu Jun 20 13:48:41 2013 +0000 +++ b/Socket/Socket.cpp Fri Jun 21 08:47:35 2013 +0000 @@ -60,10 +60,12 @@ } int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen) { + (void)level; return picotcp_setsockopt(_ep, optname, (void *)optval); } int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) { + (void)level; return picotcp_getsockopt(_ep, optname, optval); }
--- a/Socket/Socket.h Thu Jun 20 13:48:41 2013 +0000 +++ b/Socket/Socket.h Fri Jun 21 08:47:35 2013 +0000 @@ -59,8 +59,8 @@ void set_blocking(bool blocking, unsigned int timeout=1500); /** Set socket options - \param level stack level (see: lwip/sockets.h) - \param optname option ID + \param level stack level - parameter is ignored (kept for compatibility) + \param optname option ID - please check pico_socket.h \param optval option value \param socklen_t length of the option value \return 0 on success, -1 on failure @@ -68,8 +68,8 @@ int set_option(int level, int optname, const void *optval, socklen_t optlen); /** Get socket options - \param level stack level (see: lwip/sockets.h) - \param optname option ID + \param level stack level - parameter is ignored (kept for compatibility) + \param optname option ID - please check pico_socket.h or lower in the page \param optval buffer pointer where to write the option value \param socklen_t length of the option value \return 0 on success, -1 on failure
--- a/Socket/TCPSocketConnection.cpp Thu Jun 20 13:48:41 2013 +0000 +++ b/Socket/TCPSocketConnection.cpp Fri Jun 21 08:47:35 2013 +0000 @@ -68,14 +68,13 @@ if ((_ep < 0) || !_is_connected) return -1; - if (!_blocking) { - TimeInterval timeout(_timeout); - if (wait_writable(timeout) != 0) - { - printf("Failed\n"); - return -1; - } + TimeInterval timeout(!_blocking ? _timeout : osWaitForever); + if (wait_writable(timeout) != 0) + { + printf("Failed\n"); + return -1; } + ret = picotcp_write(_ep, data, length); if (ret < length) { _ep->revents &= (~PICO_SOCK_EV_WR); @@ -90,12 +89,11 @@ if ((_ep < 0) || !_is_connected) return -1; - if (!_blocking) { - TimeInterval timeout(_timeout); - // Wait for socket to be writeable - if (wait_writable(timeout) != 0) { - return 0; - } + + TimeInterval timeout(!_blocking? _timeout : osWaitForever); + // Wait for socket to be writeable + if (wait_writable(timeout) != 0) { + return 0; } ret = picotcp_write(_ep, data, length); if (ret < length) { @@ -110,14 +108,14 @@ if ((_ep < 0) || !_is_connected) return -1; - if (!_blocking) { - TimeInterval timeout(_timeout); - if (wait_readable(timeout) != 0) - { - printf("Failed receiving\n"); - return -1; - } + + TimeInterval timeout(!_blocking ? _timeout : osWaitForever); + if (wait_readable(timeout) != 0) + { + printf("Failed receiving\n"); + return -1; } + ret = picotcp_read(_ep, data, length); if (ret < length) { _ep->revents &= (~PICO_SOCK_EV_RD);
--- a/Socket/UDPSocket.cpp Thu Jun 20 13:48:41 2013 +0000 +++ b/Socket/UDPSocket.cpp Fri Jun 21 08:47:35 2013 +0000 @@ -46,8 +46,9 @@ int UDPSocket::bind(int port) { if (init_socket(SOCK_DGRAM) < 0) return -1; - + struct sockaddr_in localHost; + std::memset(&localHost, 0, sizeof(localHost)); localHost.sin_family = AF_INET; @@ -74,33 +75,26 @@ // -1 if unsuccessful, else number of bytes written int UDPSocket::sendTo(Endpoint &remote, char *packet, int length) { - if (_ep < 0) + if (!_ep) { printf("Error on socket descriptor \n"); return -1; } - /* This is not needed for our udp sock ? - if (_blocking) { - TimeInterval timeout(_timeout); - if (wait_writable(timeout) != 0) - return 0; - }*/ - - return picotcp_sendto(_ep, packet, length, (struct sockaddr *) &remote._remoteHost, sizeof(remote._remoteHost)); + return picotcp_sendto(_ep, packet, length, (struct sockaddr *) &remote._remoteHost, sizeof(struct sockaddr_in)); } // -1 if unsuccessful, else number of bytes received int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length) { - if (_ep < 0) + + if (!_ep) return -1; - if (!_blocking) { - TimeInterval timeout(_timeout); - if (wait_readable(timeout) != 0) - return 0; - } - //remote.reset_address(); why is this needed ? + TimeInterval timeout(!_blocking ? _timeout : osWaitForever); + if (wait_readable(timeout) != 0) + return 0; + + socklen_t remoteHostLen = sizeof(remote._remoteHost); return picotcp_recvfrom(_ep, buffer, length, (struct sockaddr*) &remote._remoteHost, &remoteHostLen); }
--- a/Socket/bsd/stack_endpoint.cpp Thu Jun 20 13:48:41 2013 +0000 +++ b/Socket/bsd/stack_endpoint.cpp Fri Jun 21 08:47:35 2013 +0000 @@ -81,9 +81,11 @@ } if ((ev & PICO_SOCK_EV_CLOSE) || (ev & PICO_SOCK_EV_FIN)) { ep->connected = 0; + ep->state = SOCK_CLOSED; } if ((ev & PICO_SOCK_EV_CONN) || (ev & PICO_SOCK_EV_RD)) { ep->connected = 1; + ep->state = SOCK_CONNECTED; } ep->queue->put((void *)0); } @@ -104,6 +106,7 @@ } else { ep->s->priv = ep; printf("Added socket (open)\n"); + ep->state = SOCK_OPEN; ep->queue = new Queue<void,1>(); } PicoTcpLock->unlock(); @@ -113,13 +116,6 @@ int picotcp_state(struct stack_endpoint *ep) { -/* TODO: return one of: - SOCK_OPEN, - SOCK_BOUND, - SOCK_LISTEN, - SOCK_CONNECTED, - SOCK_CLOSED -*/ return ep->state; } @@ -131,6 +127,8 @@ PicoTcpLock->lock(); ret = pico_socket_bind(ep->s, (struct pico_ip4 *)(&local_addr->sin_addr.s_addr), &local_addr->sin_port); + if(ret == 0) + ep->state = SOCK_BOUND; PicoTcpLock->unlock(); return ret; } @@ -144,6 +142,8 @@ ep_accepting->queue = new Queue<void,1>(); if (!ep_accepting) ret = -1; + if(ret == 0) + ep->state = SOCK_LISTEN; PicoTcpLock->unlock(); return ret; } @@ -161,6 +161,7 @@ ep->revents &= (~PICO_SOCK_EV_CONN); ep->revents |= PICO_SOCK_EV_WR; ptsock_dbg("Established. sock state: %x\n", ep->s->state); + ep->state = SOCK_CONNECTED; retval = 0; } else { retval = -1; @@ -193,6 +194,7 @@ ep->revents &= (~PICO_SOCK_EV_CONN); aep->revents = 0; // set this to 0 to allow seq connections aep->revents |= PICO_SOCK_EV_WR; + aep->state = SOCK_CONNECTED; printf("Added socket (accept)\n"); *len = sizeof(struct sockaddr_in); @@ -222,28 +224,109 @@ return ret; } -int picotcp_send(struct stack_endpoint *ep,void * buff, int len, int flags) +int picotcp_send(struct stack_endpoint *ep,void * buf, int len, int flags) { - /* TODO */ - return -1; + int retval = 0; + int tot_len = 0; + if (!buf || (len <= 0)) + return 0; + PicoTcpLock->lock(); + while (tot_len < len) { + retval = pico_socket_send(ep->s, ((uint8_t *)buf) + tot_len , len - tot_len); + if (retval == 0) { + if (tot_len < len) + ep->revents &= ~PICO_SOCK_EV_WR; + break; + } + if (retval < 0) { + tot_len = -1; + break; + } + tot_len += retval; + } + PicoTcpLock->unlock(); + picotcp_async_interrupt(NULL); + return tot_len; +} + +int picotcp_recv(struct stack_endpoint *ep,void * buf, int len, int flags) +{ + int retval = 0; + int tot_len = 0; + if (!buf || (len <= 0)) + return 0; + PicoTcpLock->lock(); + while (tot_len < len) { + retval = pico_socket_recv(ep->s, ((uint8_t *)buf) + tot_len , len - tot_len); + if (retval == 0) { + if (tot_len < len) + ep->revents &= ~PICO_SOCK_EV_RD; + break; + } + if (retval < 0) { + tot_len = -1; + break; + } + tot_len += retval; + } + PicoTcpLock->unlock(); + picotcp_async_interrupt(NULL); + return tot_len; } -int picotcp_recv(struct stack_endpoint *ep,void * buff, int len, int flags) +int picotcp_sendto(struct stack_endpoint * ep,void * buf, int len, struct sockaddr* a,socklen_t size) { - /* TODO */ - return -1; + int retval = 0; + int tot_len = 0; + struct sockaddr_in * in = (struct sockaddr_in *)a; + if (!buf || (len <= 0)) + return 0; + if(!ep->broadcast && pico_ipv4_is_broadcast(in->sin_addr.s_addr)) + return -1; + + PicoTcpLock->lock(); + while (tot_len < len) { + retval = pico_socket_sendto(ep->s, ((uint8_t *)buf) + tot_len , len - tot_len,(struct pico_ip4 *)&in->sin_addr.s_addr, in->sin_port); + + if (retval == 0) + break; + + if (retval < 0) { + tot_len = -1; + break; + } + tot_len += retval; + } + PicoTcpLock->unlock(); + picotcp_async_interrupt(NULL); + return tot_len; } -int picotcp_sendto(struct stack_endpoint *ep,void * buff, int len, struct sockaddr *a, socklen_t l) +int picotcp_recvfrom(struct stack_endpoint *ep,void * buf, int len, struct sockaddr *a, socklen_t * size) { - /* TODO */ - return -1; -} - -int picotcp_recvfrom(struct stack_endpoint *ep,void * buff, int len, struct sockaddr *a, socklen_t *l) -{ - /* TODO */ - return -1; + (void)len; + int retval = 0; + int tot_len = 0; + struct sockaddr_in * in = (struct sockaddr_in *)a; + if (!buf || (len <= 0)) + return 0; + PicoTcpLock->lock(); + while (tot_len < len) { + retval = pico_socket_recvfrom(ep->s, ((uint8_t *)buf) + tot_len , len - tot_len,(struct pico_ip4 *)&(in->sin_addr.s_addr),&in->sin_port); + if (retval == 0) { + if (tot_len < len) + ep->revents &= ~PICO_SOCK_EV_RD; + break; + } + if (retval < 0) { + tot_len = -1; + break; + } + tot_len += retval; + } + PicoTcpLock->unlock(); + picotcp_async_interrupt(NULL); + return tot_len; } int picotcp_read(struct stack_endpoint *ep,void *buf, int len) @@ -280,10 +363,10 @@ PicoTcpLock->lock(); while (tot_len < len) { retval = pico_socket_write(ep->s, ((uint8_t *)buf) + tot_len , len - tot_len); - retval = pico_socket_read(ep->s, ((uint8_t *)buf) + tot_len , len - tot_len); + //retval = pico_socket_read(ep->s, ((uint8_t *)buf) + tot_len , len - tot_len); if (retval == 0) { if (tot_len < len) - ep->revents &= ~PICO_SOCK_EV_RD; + ep->revents &= ~PICO_SOCK_EV_WR; break; } if (retval < 0) { @@ -291,7 +374,6 @@ break; } tot_len += retval; - } PicoTcpLock->unlock(); picotcp_async_interrupt(NULL); @@ -301,14 +383,30 @@ int picotcp_setsockopt(struct stack_endpoint *ep, int option, void *value) { - /* TODO */ - return -1; + int ret; + + PicoTcpLock->lock(); + if(option == SO_BROADCAST) + { + ep->broadcast = *(int *)value; + ret = 0; + } + else + ret = pico_socket_setoption(ep->s,option,value); + PicoTcpLock->unlock(); + + return ret; } int picotcp_getsockopt(struct stack_endpoint *ep, int option, void *value) { - /* TODO */ - return -1; + int ret; + + PicoTcpLock->lock(); + ret = pico_socket_getoption(ep->s,option,value); + PicoTcpLock->unlock(); + + return ret; } int picotcp_close(struct stack_endpoint *ep) @@ -327,8 +425,16 @@ int picotcp_join_multicast(struct stack_endpoint *ep,const char* address,const char* local) { - /* TODO */ - return -1; + int ret; + struct pico_ip_mreq mreq={}; + + PicoTcpLock->lock(); + pico_string_to_ipv4(address,&mreq.mcast_group_addr.addr); + pico_string_to_ipv4(local,&mreq.mcast_link_addr.addr); + ret = pico_socket_setoption(ep->s, PICO_IP_ADD_MEMBERSHIP, &mreq); + PicoTcpLock->unlock(); + + return ret; }
--- a/Socket/bsd/wrapper.h Thu Jun 20 13:48:41 2013 +0000 +++ b/Socket/bsd/wrapper.h Fri Jun 21 08:47:35 2013 +0000 @@ -26,6 +26,7 @@ Queue<void,1> *queue;//receive queue of 1 element of type uint32_t timeout; // this is used for timeout sockets int state; // for pico_state + uint8_t broadcast; }; void picotcp_start(void);