Free (GPLv2) TCP/IP stack developed by TASS Belgium

Fork of PicoTCP by Daniele Lacamera

Files at this revision

API Documentation at this revision

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

Socket/Socket.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/Socket.h Show annotated file Show diff for this revision Revisions of this file
Socket/TCPSocketConnection.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/UDPSocket.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/bsd/stack_endpoint.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/bsd/wrapper.h Show annotated file Show diff for this revision Revisions of this file
--- 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);