11 #include <nsdp/packet.h>
14 static inline void timespec_add (struct timespec *tsa, const struct timespec *tsb)
16 tsa->tv_sec += tsb->tv_sec;
17 tsa->tv_nsec += tsb->tv_nsec;
18 while (tsa->tv_nsec >= 1000000000) {
19 tsa->tv_nsec -= 1000000000;
25 static inline int timespec_diff_ms (const struct timespec *tsa, const struct timespec *tsb)
27 int diff = (tsb->tv_sec - tsa->tv_sec) * 1000;
29 if (tsb->tv_sec > tsa->tv_sec)
30 diff += (tsb->tv_nsec - tsa->tv_nsec) / 1000000;
32 diff -= (tsb->tv_nsec - tsa->tv_nsec) / 1000000;
38 static inline void timeval_to_timespec (struct timespec *ts, const struct timeval *tv)
40 ts->tv_sec = tv->tv_sec;
41 ts->tv_nsec = tv->tv_usec * 1000;
45 int sendNsdpPacket (int sock, const struct nsdp_cmd *nc, const List *attr)
47 unsigned char buffer[1500];
48 struct nsdp_packet np;
52 if (sock < 0 || nc == NULL)
56 np.maxlen = sizeof(buffer);
58 initNsdpHeader(np.nh, nc);
60 ret = addPacketAttributes(&np, attr);
64 ret = sendto(sock, buffer, getPacketTotalSize(&np), 0, (struct sockaddr*)&nc->remote_addr, sizeof(struct sockaddr_in));
73 int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct timespec *timeout)
75 unsigned char buffer[1500];
76 struct nsdp_packet np;
77 socklen_t slen = sizeof(struct sockaddr_in);
78 int len = -1, timewait;
79 struct sockaddr_in remote;
80 struct timespec timecurrent, timeend;
81 #ifndef HAVE_CLOCK_GETTIME
87 if (sock < 0 || nc == NULL || attr == NULL)
92 memset(&remote, 0, sizeof(struct sockaddr_in));
93 remote.sin_family = AF_INET;
95 if (timeout == NULL) {
98 #ifdef HAVE_CLOCK_GETTIME
99 clock_gettime(CLOCK_MONOTONIC, &timeend);
101 gettimeofday(&tv, NULL);
102 timeval_to_timespec(&timeend, &tv);
104 timespec_add(&timeend, timeout);
111 if (timeout != NULL) {
112 #ifdef HAVE_CLOCK_GETTIME
113 clock_gettime(CLOCK_MONOTONIC, &timecurrent);
115 gettimeofday(&tv, NULL);
116 timeval_to_timespec(&timeend, &tv);
118 timewait = timespec_diff_ms(&timecurrent, &timeend);
123 len = poll(&fds, 1, timewait);
126 } else if (len == 0) {
131 len = recvfrom(sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&remote, &slen);
138 if ((nc->remote_addr.sin_addr.s_addr != 0 && remote.sin_addr.s_addr != nc->remote_addr.sin_addr.s_addr) ||
139 (nc->remote_addr.sin_port != 0 && remote.sin_port != nc->remote_addr.sin_port) ||
140 len < (int)sizeof(struct nsdp_header) ||
141 !extractNsdpHeader(np.nh, nc) ||
142 extractPacketAttributes(&np, attr) < 0)
145 nc->remote_addr = remote;