26 Register_PerRunConfigOption(CFGID_EXTERNALAPP_CONNECTION_LIMIT,
"externalapp-connection-limit", CFG_INT, NULL,
"TODO some documentation");
29 inline std::ostream&
operator<<(std::ostream& os,
const timeval& tv)
31 return os << (
unsigned long)tv.tv_sec <<
"s" << tv.tv_usec <<
"us";
48 if (initsocketlibonce()!=0)
49 throw cRuntimeError(
"RealtimeScheduler: Cannot initialize socket library");
61 opp_error(
"realtimeScheduler error: initializeNetwork failed\n");
78 if (!mod || !notifMsg || !buffer) {
79 throw cRuntimeError(
"RealtimeScheduler: setInterfaceModule(): "
80 "arguments must be non-NULL");
85 throw cRuntimeError(
"RealtimeScheduler: setInterfaceModule() "
94 throw cRuntimeError(
"RealtimeScheduler: setInterfaceModule() "
109 throw cRuntimeError(
"RealtimeScheduler::registerSocket(): Socket"
110 "already registered!");
123 bool newEvent =
false;
130 timeout.tv_usec = usec;
132 if (select(FD_SETSIZE, &readFD, NULL, NULL, &timeout) > 0) {
134 for (SOCKET fd = 0; fd <=
maxfd; fd++) {
135 if (FD_ISSET(fd, &readFD)) {
143 sockaddr* from = (sockaddr*)
new sockaddr_in;
144 socklen_t addrlen =
sizeof(sockaddr_in);
147 getsockname(
netw_fd, from, &addrlen);
148 if ( from->sa_family != SOCK_DGRAM ) {
155 addrlen =
sizeof(sockaddr_in);
160 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
161 <<
" Error reading from network: " << strerror(sock_errno())
165 opp_error(
"Read from network device returned an error");
166 }
else if (nBytes == 0) {
167 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
168 <<
" Received 0 byte long UDP packet!" << endl;
173 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
174 <<
" Received " << nBytes <<
" bytes"
188 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
189 <<
" Error reading from application TUN socket: "
190 << strerror(sock_errno())
194 opp_error(
"Read from application TUN socket returned "
196 }
else if (nBytes == 0) {
197 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
198 <<
" Received 0 byte long UDP packet!" << endl;
203 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
204 <<
" Received " << nBytes <<
" bytes"
221 char* buf =
new char[fdContext.
mtu];
224 socklen_t size =
sizeof(
error);
225 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (
char*)&error, &size) < 0) {
226 perror(
"getsockopt()");
229 int nBytes = recv(fd, buf, fdContext.
mtu, 0);
234 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
235 <<
" Read error from socket in socketContextMap: "
236 << strerror(sock_errno()) << endl;
238 }
else if (nBytes == 0) {
240 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
241 <<
" Application closed socket"
250 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
251 <<
" Received " << nBytes <<
" bytes"
270 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
271 <<
" Read error from application socket: "
272 << strerror(sock_errno()) << endl;
274 }
else if (nBytes == 0) {
276 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
277 <<
" Application closed socket"
285 ev <<
"[RealtimeScheduler::receiveWithTimeout()]\n"
286 <<
" Received " << nBytes <<
" bytes"
305 gettimeofday(&curTime, NULL);
306 while (targetTime.tv_sec-curTime.tv_sec >=2 ||
307 timeval_diff_usec(targetTime, curTime) >= 200000) {
309 if (ev.idle())
return -1;
312 if (ev.idle())
return -1;
313 gettimeofday(&curTime, NULL);
317 long usec = timeval_diff_usec(targetTime, curTime);
320 if (ev.idle())
return -1;
323 if (ev.idle())
return -1;
331 throw cRuntimeError(
"RealtimeScheduler: setInterfaceModule() not called: it must be called from a module's initialize() function");
338 cMessage *msg = sim->msgQueue.peekFirst();
342 targetTime.tv_sec = LONG_MAX;
343 targetTime.tv_usec = 0;
346 simtime_t eventSimtime = msg->getArrivalTime();
347 targetTime = timeval_add(
baseTime, SIMTIME_DBL(eventSimtime));
352 gettimeofday(&curTime, NULL);
353 if (timeval_greater(targetTime, curTime)) {
356 printf(
"WARNING: receiveUntil returned -1 (user interrupt)\n");
358 }
else if (status == 1) {
359 msg = sim->msgQueue.peekFirst();
393 if (msg->isScheduled())
return;
395 gettimeofday(&curTime, NULL);
396 curTime = timeval_substract(curTime,
baseTime);
397 simtime_t t = curTime.tv_sec + curTime.tv_usec*1e-6;
401 if (t < simTime()) t = simTime();
403 msg->setSentFrom(mod, -1, simTime());
404 msg->setArrival(mod,-1,t);
405 simulation.msgQueue.insert(msg);
416 ev <<
"[RealtimeScheduler::sendBytes()]\n"
417 <<
" Error sending packet: buf = NULL"
423 ev <<
"[RealtimeScheduler::sendBytes()]\n"
424 <<
" Trying to send oversized packet: size " << numBytes <<
" mtu " <<
buffersize
426 opp_error(
"Can't send packet: too large");
429 if (
netw_fd == INVALID_SOCKET ) {
430 ev <<
"[RealtimeScheduler::sendBytes()]\n"
431 <<
" Can't send packet to network: no tun/udp socket"
437 nBytes = sendto(
netw_fd, buf, numBytes, 0, addr, addrlen);
440 nBytes = write(
netw_fd, buf, numBytes);
443 ev <<
"[RealtimeScheduler::sendBytes()]\n"
444 <<
" Error sending data to network: " << strerror(sock_errno()) <<
"\n"
445 <<
" FD = " <<
netw_fd <<
", numBytes = " << numBytes <<
", addrlen = " << addrlen
453 if (numBytes > fdContext.
mtu) {
454 ev <<
"[RealtimeScheduler::sendBytes()]\n"
455 <<
" Trying to send oversized packet: size " << numBytes <<
"\n"
456 <<
" mtu " << fdContext.
mtu
458 opp_error(
"Can't send packet: too large");
460 return send(fd, buf, numBytes, 0 );
463 ev <<
"[RealtimeScheduler::sendBytes()]\n"
464 <<
" Trying to send oversized packet: size " << numBytes <<
"\n"
467 opp_error(
"Can't send packet: too large");
470 if (fd == INVALID_SOCKET) {
471 for (fd = 0; fd <=
maxfd; fd++) {
474 if (FD_ISSET(fd, &
all_fds))
break;
477 throw cRuntimeError(
"Can't send packet to Application: no socket");
482 return write(fd, buf, numBytes);
484 return send(fd, buf, numBytes, 0);