]> git.sur5r.net Git - ngadmin/blobdiff - raw/src/net.c
Raw: expose encoding functions
[ngadmin] / raw / src / net.c
index cc619efdd94b8fe51334ffffd97c6a61318cd711..e5af939c39d72f89bd4aa91b2a7201f825dac7c7 100644 (file)
@@ -1,9 +1,45 @@
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <errno.h>
+#include <poll.h>
 
 #include <nsdp/net.h>
-#include "encoding.h"
+#include <nsdp/encoding.h>
+
+
+static inline void timespec_add (struct timespec *tsa, const struct timespec *tsb)
+{
+       tsa->tv_sec += tsb->tv_sec;
+       tsa->tv_nsec += tsb->tv_nsec;
+       while (tsa->tv_nsec >= 1000000000) {
+               tsa->tv_nsec -= 1000000000;
+               tsa->tv_sec++;
+       }
+}
+
+
+static inline int timespec_diff_ms (const struct timespec *tsa, const struct timespec *tsb)
+{
+       int diff = (tsb->tv_sec - tsa->tv_sec) * 1000;
+       
+       if (tsb->tv_sec > tsa->tv_sec)
+               diff += (tsb->tv_nsec - tsa->tv_nsec) / 1000000;
+       else
+               diff -= (tsb->tv_nsec - tsa->tv_nsec) / 1000000;
+       
+       return diff;
+}
+
+
+static inline void timeval_to_timespec (struct timespec *ts, const struct timeval *tv)
+{
+       ts->tv_sec = tv->tv_sec;
+       ts->tv_nsec = tv->tv_usec * 1000;
+}
 
 
 int sendNsdpPacket (int sock, const struct nsdp_cmd *nc, const List *attr)
@@ -34,15 +70,18 @@ int sendNsdpPacket (int sock, const struct nsdp_cmd *nc, const List *attr)
 }
 
 
-int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct timeval *timeout)
+int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct timespec *timeout)
 {
        unsigned char buffer[1500];
        struct nsdp_packet np;
        socklen_t slen = sizeof(struct sockaddr_in);
-       struct timeval rem;
-       fd_set fs;
-       int len = -1;
+       int len = -1, timewait;
        struct sockaddr_in remote;
+       struct timespec timecurrent, timeend;
+#ifndef HAVE_CLOCK_GETTIME
+       struct timeval tv;
+#endif
+       struct pollfd fds;
        
        
        if (sock < 0 || nc == NULL || attr == NULL)
@@ -50,16 +89,44 @@ int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct time
        
        np.buffer = buffer;
        
-       if (timeout != NULL)
-               rem = *timeout;
-       
        memset(&remote, 0, sizeof(struct sockaddr_in));
        remote.sin_family = AF_INET;
        
+       if (timeout == NULL) {
+               timewait = -1;
+       } else {
+#ifdef HAVE_CLOCK_GETTIME
+               clock_gettime(CLOCK_MONOTONIC, &timeend);
+#else
+               gettimeofday(&tv, NULL);
+               timeval_to_timespec(&timeend, &tv);
+#endif
+               timespec_add(&timeend, timeout);
+       }
+       fds.fd = sock;
+       fds.events = POLLIN;
+       fds.revents = 0;
+       
        while (1) {
-               FD_ZERO(&fs);
-               FD_SET(sock, &fs);
-               select(sock + 1, &fs, NULL, NULL, timeout == NULL ? NULL : &rem); /* FIXME: non portable */
+               if (timeout != NULL) {
+#ifdef HAVE_CLOCK_GETTIME
+                       clock_gettime(CLOCK_MONOTONIC, &timecurrent);
+#else
+                       gettimeofday(&tv, NULL);
+                       timeval_to_timespec(&timeend, &tv);
+#endif
+                       timewait = timespec_diff_ms(&timecurrent, &timeend);
+                       if (timewait <= 0)
+                               break;
+               }
+               
+               len = poll(&fds, 1, timewait);
+               if (len < 0) {
+                       break;
+               } else if (len == 0) {
+                       len = -ETIMEDOUT;
+                       break;
+               }
                
                len = recvfrom(sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&remote, &slen);
                if (len < 0)
@@ -71,16 +138,12 @@ int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct time
                if ((nc->remote_addr.sin_addr.s_addr != 0 && remote.sin_addr.s_addr != nc->remote_addr.sin_addr.s_addr) ||
                    (nc->remote_addr.sin_port != 0 && remote.sin_port != nc->remote_addr.sin_port) ||
                    len < (int)sizeof(struct nsdp_header) ||
-                   !validateNsdpHeader(np.nh, nc) ||
+                   !extractNsdpHeader(np.nh, nc) ||
                    extractPacketAttributes(&np, attr, nc->ports) < 0)
                        continue;
                
                nc->remote_addr = remote;
                
-               nc->code = np.nh->code;
-               nc->error = np.nh->error;
-               nc->attr_error = ntohs(np.nh->attr);
-               
                len = 0;
                break;
        }