This class implements a event scheduler for OMNeT++ It makes the simulation run in realtime (i.e. More...
#include <realtimescheduler.h>
Classes | |
class | PacketBufferEntry |
Public Types | |
typedef std::list < PacketBufferEntry > | PacketBuffer |
Public Member Functions | |
RealtimeScheduler () | |
Constructor. | |
virtual | ~RealtimeScheduler () |
Destructor. | |
virtual void | startRun () |
Called at the beginning of a simulation run. | |
virtual void | endRun () |
Called at the end of a simulation run. | |
virtual void | executionResumed () |
Recalculates "base time" from current wall clock time. | |
virtual void | setInterfaceModule (cModule *module, cMessage *notificationMsg, PacketBuffer *buffer, int mtu, bool isApp=false) |
To be called from the module which wishes to receive data from the tun device. | |
virtual cMessage * | getNextEvent () |
Scheduler function -- it comes from cScheduler interface. | |
void | sendNotificationMsg (cMessage *msg, cModule *mod) |
send notification msg to module | |
virtual ssize_t | sendBytes (const char *buf, size_t numBytes, sockaddr *addr=0, socklen_t addrlen=0, bool isApp=false, SOCKET fd=INVALID_SOCKET) |
Send data to network. | |
void | closeAppSocket (SOCKET fd) |
Close the application TCP socket. | |
virtual SOCKET | getAppTunFd () |
Returns the FD for the application TUN socket. | |
Protected Member Functions | |
virtual int | initializeNetwork ()=0 |
Initialize the network. | |
virtual void | additionalFD () |
This function is called from main loop if data is accessible from "additional_fd". | |
virtual bool | receiveWithTimeout (long usec) |
Waits for incoming data on the tun device. | |
virtual int | receiveUntil (const timeval &targetTime) |
Tries to read data until the given time is up. | |
Protected Attributes | |
fd_set | all_fds |
SOCKET | maxfd |
SOCKET | netw_fd |
SOCKET | apptun_fd |
cModule * | module |
cMessage * | notificationMsg |
PacketBuffer * | packetBuffer |
size_t | buffersize |
cModule * | appModule |
cMessage * | appNotificationMsg |
PacketBuffer * | appPacketBuffer |
size_t | appBuffersize |
int | appConnectionLimit |
SOCKET | additional_fd |
timeval | baseTime |
This class implements a event scheduler for OMNeT++ It makes the simulation run in realtime (i.e.
1 simsec == 1 sec) It must be subclassed; its subclasses must handle network traffic from/to the simulation
Definition at line 38 of file realtimescheduler.h.
typedef std::list<PacketBufferEntry> RealtimeScheduler::PacketBuffer |
Definition at line 64 of file realtimescheduler.h.
RealtimeScheduler::RealtimeScheduler | ( | ) |
Constructor.
Definition at line 34 of file realtimescheduler.cc.
00034 : cScheduler() 00035 { 00036 FD_ZERO(&all_fds); 00037 maxfd = 0; 00038 netw_fd = INVALID_SOCKET; 00039 additional_fd = INVALID_SOCKET; 00040 apptun_fd = INVALID_SOCKET; 00041 }
RealtimeScheduler::~RealtimeScheduler | ( | ) | [virtual] |
virtual void RealtimeScheduler::additionalFD | ( | ) | [inline, protected, virtual] |
This function is called from main loop if data is accessible from "additional_fd".
This FD can be set in initializeNetwork by concrete implementations.
Reimplemented in AppTunOutScheduler, TunOutScheduler, and UdpOutScheduler.
Definition at line 99 of file realtimescheduler.h.
Referenced by receiveWithTimeout().
void RealtimeScheduler::closeAppSocket | ( | SOCKET | fd | ) |
Close the application TCP socket.
Definition at line 308 of file realtimescheduler.cc.
Referenced by XmlRpcInterface::closeConnection(), and receiveWithTimeout().
00309 { 00310 #ifdef _WIN32 00311 closesocket(fd); 00312 #else 00313 close(fd); 00314 #endif 00315 FD_CLR(fd, &all_fds); 00316 00317 appPacketBuffer->push_back(PacketBufferEntry(0, 0, PacketBufferEntry::PACKET_FD_CLOSE, fd)); 00318 sendNotificationMsg(appNotificationMsg, appModule); 00319 }
void RealtimeScheduler::endRun | ( | ) | [virtual] |
void RealtimeScheduler::executionResumed | ( | ) | [virtual] |
Recalculates "base time" from current wall clock time.
Definition at line 68 of file realtimescheduler.cc.
virtual SOCKET RealtimeScheduler::getAppTunFd | ( | ) | [inline, virtual] |
Returns the FD for the application TUN socket.
Definition at line 203 of file realtimescheduler.h.
Referenced by XmlRpcInterface::initializeApp().
00203 { return apptun_fd; };
cMessage * RealtimeScheduler::getNextEvent | ( | ) | [virtual] |
Scheduler function -- it comes from cScheduler interface.
Definition at line 265 of file realtimescheduler.cc.
00266 { 00267 // assert that we've been configured 00268 if (!module) 00269 throw cRuntimeError("RealtimeScheduler: setInterfaceModule() not called: it must be called from a module's initialize() function"); 00270 // FIXME: reimplement sanity check 00271 // if (app_fd >= 0 && !appModule) 00272 // throw cRuntimeError("RealtimeScheduler: setInterfaceModule() not called from application: it must be called from a module's initialize() function"); 00273 00274 // calculate target time 00275 timeval targetTime; 00276 cMessage *msg = sim->msgQueue.peekFirst(); 00277 if (!msg) { 00278 // if there are no events, wait until something comes from outside 00279 // TBD: obey simtimelimit, cpu-time-limit 00280 targetTime.tv_sec = LONG_MAX; 00281 targetTime.tv_usec = 0; 00282 } else { 00283 // use time of next event 00284 simtime_t eventSimtime = msg->getArrivalTime(); 00285 targetTime = timeval_add(baseTime, SIMTIME_DBL(eventSimtime)); 00286 } 00287 00288 // if needed, wait until that time arrives 00289 timeval curTime; 00290 gettimeofday(&curTime, NULL); 00291 if (timeval_greater(targetTime, curTime)) { 00292 int status = receiveUntil(targetTime); 00293 if (status == -1) { 00294 printf("WARNING: receiveUntil returned -1 (user interrupt)\n"); 00295 return NULL; // interrupted by user 00296 } else if (status == 1) { 00297 msg = sim->msgQueue.peekFirst(); // received something 00298 } 00299 } else { 00300 // printf("WARNING: Lagging behind realtime!\n"); 00301 // we're behind -- customized versions of this class may 00302 // alert if we're too much behind, whatever that means 00303 } 00304 // ok, return the message 00305 return msg; 00306 }
virtual int RealtimeScheduler::initializeNetwork | ( | ) | [protected, pure virtual] |
Initialize the network.
Implemented in AppTunOutScheduler, TunOutScheduler, and UdpOutScheduler.
Referenced by startRun().
int RealtimeScheduler::receiveUntil | ( | const timeval & | targetTime | ) | [protected, virtual] |
Tries to read data until the given time is up.
targetTime | stop waiting after this time is up |
Definition at line 238 of file realtimescheduler.cc.
Referenced by getNextEvent().
00239 { 00240 // if there's more than 200ms to wait, wait in 100ms chunks 00241 // in order to keep UI responsiveness by invoking ev.idle() 00242 timeval curTime; 00243 gettimeofday(&curTime, NULL); 00244 while (targetTime.tv_sec-curTime.tv_sec >=2 || 00245 timeval_diff_usec(targetTime, curTime) >= 200000) { 00246 if (receiveWithTimeout(100000)) { // 100ms 00247 if (ev.idle()) return -1; 00248 return 1; 00249 } 00250 if (ev.idle()) return -1; 00251 gettimeofday(&curTime, NULL); 00252 } 00253 00254 // difference is now at most 100ms, do it at once 00255 long usec = timeval_diff_usec(targetTime, curTime); 00256 if (usec>0) 00257 if (receiveWithTimeout(usec)) { 00258 if (ev.idle()) return -1; 00259 return 1; 00260 } 00261 if (ev.idle()) return -1; 00262 return 0; 00263 }
bool RealtimeScheduler::receiveWithTimeout | ( | long | usec | ) | [protected, virtual] |
Waits for incoming data on the tun device.
usec | Timeout after which to quit waiting (in µsec) |
Definition at line 104 of file realtimescheduler.cc.
Referenced by receiveUntil().
00105 { 00106 bool newEvent = false; 00107 // prepare sets for select() 00108 fd_set readFD; 00109 readFD = all_fds; 00110 00111 timeval timeout; 00112 timeout.tv_sec = 0; 00113 timeout.tv_usec = usec; 00114 00115 if (select(FD_SETSIZE, &readFD, NULL, NULL, &timeout) > 0) { 00116 // Read on all sockets with data 00117 for (SOCKET fd = 0; fd <= maxfd; fd++) { 00118 if (FD_ISSET(fd, &readFD)) { 00119 // Incoming data on netw_fd 00120 if (fd == netw_fd) { 00121 char* buf = new char[buffersize]; 00122 int nBytes; 00123 00124 // FIXME: Ugly. But we want to support IPv4 and IPv6 here, so we 00125 // reserve enough space for the "bigger" address. 00126 sockaddr* from = (sockaddr*) new sockaddr_in; 00127 socklen_t addrlen = sizeof(sockaddr_in); 00128 00129 // FIXME: Ugly... 00130 getsockname(netw_fd, from, &addrlen); 00131 if ( from->sa_family != SOCK_DGRAM ) { 00132 delete from; 00133 from = 0; 00134 addrlen = 0; 00135 // use read() for TUN device 00136 nBytes = read(netw_fd, buf, buffersize); 00137 } else { 00138 addrlen = sizeof(sockaddr_in); 00139 nBytes = recvfrom(netw_fd, buf, buffersize, 0, from, &addrlen); 00140 } 00141 00142 if (nBytes < 0) { 00143 ev << "[RealtimeScheduler::receiveWithTimeout()]\n" 00144 << " Error reading from network: " << strerror(sock_errno()) 00145 << endl; 00146 delete[] buf; 00147 buf = NULL; 00148 opp_error("Read from network device returned an error"); 00149 } else if (nBytes == 0) { 00150 ev << "[RealtimeScheduler::receiveWithTimeout()]\n" 00151 << " Received 0 byte long UDP packet!" << endl; 00152 delete[] buf; 00153 buf = NULL; 00154 } else { 00155 // write data to buffer 00156 ev << "[RealtimeScheduler::receiveWithTimeout()]\n" 00157 << " Received " << nBytes << " bytes" 00158 << endl; 00159 packetBuffer->push_back(PacketBufferEntry(buf, nBytes, from, addrlen)); 00160 // schedule notificationMsg for the interface module 00161 sendNotificationMsg(notificationMsg, module); 00162 newEvent = true; 00163 } 00164 } else if ( fd == apptun_fd ) { 00165 // Data on application TUN FD 00166 char* buf = new char[appBuffersize]; 00167 // use read() for TUN device 00168 int nBytes = read(fd, buf, appBuffersize); 00169 00170 if (nBytes < 0) { 00171 ev << "[RealtimeScheduler::receiveWithTimeout()]\n" 00172 << " Error reading from application TUN socket: " 00173 << strerror(sock_errno()) 00174 << endl; 00175 delete[] buf; 00176 buf = NULL; 00177 opp_error("Read from application TUN socket returned " 00178 "an error"); 00179 } else if (nBytes == 0) { 00180 ev << "[RealtimeScheduler::receiveWithTimeout()]\n" 00181 << " Received 0 byte long UDP packet!" << endl; 00182 delete[] buf; 00183 buf = NULL; 00184 } else { 00185 // write data to buffer 00186 ev << "[RealtimeScheduler::receiveWithTimeout()]\n" 00187 << " Received " << nBytes << " bytes" 00188 << endl; 00189 00190 appPacketBuffer->push_back(PacketBufferEntry(buf, 00191 nBytes, PacketBufferEntry::PACKET_APPTUN_DATA, fd)); 00192 00193 // schedule notificationMsg for the interface module 00194 sendNotificationMsg(appNotificationMsg, appModule); 00195 newEvent = true; 00196 } 00197 } else if ( fd == additional_fd ) { 00198 // Data on additional FD 00199 additionalFD(); 00200 newEvent = true; 00201 } else { 00202 // Data on app FD 00203 char* buf = new char[appBuffersize]; 00204 int nBytes = recv(fd, buf, appBuffersize, 0); 00205 if (nBytes < 0) { 00206 delete[] buf; 00207 buf = NULL; 00208 ev << "[RealtimeScheduler::receiveWithTimeout()]\n" 00209 << " Read error from application socket: " 00210 << strerror(sock_errno()) << endl; 00211 opp_error("Read from network device returned an error (App)"); 00212 } else if (nBytes == 0) { 00213 // Application closed Socket 00214 ev << "[RealtimeScheduler::receiveWithTimeout()]\n" 00215 << " Application closed socket" 00216 << endl; 00217 delete[] buf; 00218 buf = NULL; 00219 closeAppSocket(fd); 00220 newEvent = true; 00221 } else { 00222 // write data to buffer 00223 ev << "[RealtimeScheduler::receiveWithTimeout()]\n" 00224 << " Received " << nBytes << " bytes" 00225 << endl; 00226 appPacketBuffer->push_back(PacketBufferEntry(buf, nBytes, PacketBufferEntry::PACKET_DATA, fd)); 00227 // schedule notificationMsg for the interface module 00228 sendNotificationMsg(appNotificationMsg, appModule); 00229 newEvent = true; 00230 } 00231 } 00232 } 00233 } 00234 } 00235 return newEvent; 00236 }
ssize_t RealtimeScheduler::sendBytes | ( | const char * | buf, | |
size_t | numBytes, | |||
sockaddr * | addr = 0 , |
|||
socklen_t | addrlen = 0 , |
|||
bool | isApp = false , |
|||
SOCKET | fd = INVALID_SOCKET | |||
) | [virtual] |
Send data to network.
buf | A pointer to the data to be send | |
numBytes | the length of the data | |
isApp | set to "true" if called from a realworldApp | |
addr | If needed, the destination address | |
addrlen | The length of the address | |
fd | If connected to more than one external app, set to the corresponding FD. If left to default and multiple apps are connected, the data will be send to one arbitrarily chosen app. |
Definition at line 338 of file realtimescheduler.cc.
Referenced by XmlRpcInterface::deliverTunneledMessage(), SimpleGameClient::handleLowerMessage(), SimpleGameClient::handleRealworldPacket(), SimpleGameClient::handleTimerEvent(), RealworldConnector::transmitToNetwork(), SimpleGameClient::updateNeighbors(), and XmlRpcInterface::writeResponse().
00344 { 00345 if (!buf) { 00346 ev << "[RealtimeScheduler::sendBytes()]\n" 00347 << " Error sending packet: buf = NULL" 00348 << endl; 00349 return -1; 00350 } 00351 if (!isApp) { 00352 if( numBytes > buffersize ) { 00353 ev << "[RealtimeScheduler::sendBytes()]\n" 00354 << " Trying to send oversized packet: size " << numBytes << " mtu " << buffersize 00355 << endl; 00356 opp_error("Can't send packet: too large"); //FIXME: Throw exception instead 00357 } 00358 00359 if ( netw_fd == INVALID_SOCKET ) { 00360 ev << "[RealtimeScheduler::sendBytes()]\n" 00361 << " Can't send packet to network: no tun/udp socket" 00362 << endl; 00363 return 0; 00364 } 00365 int nBytes; 00366 if (addr) { 00367 nBytes = sendto(netw_fd, buf, numBytes, 0, addr, addrlen); 00368 } else { 00369 // TUN 00370 nBytes = write(netw_fd, buf, numBytes); 00371 } 00372 if (nBytes < 0) { 00373 ev << "[RealtimeScheduler::sendBytes()]\n" 00374 << " Error sending data to network: " << strerror(sock_errno()) << "\n" 00375 << " FD = " << netw_fd << ", numBytes = " << numBytes << ", addrlen = " << addrlen 00376 << endl; 00377 } 00378 return nBytes; 00379 00380 } else { 00381 if (numBytes > appBuffersize) { 00382 ev << "[RealtimeScheduler::sendBytes()]\n" 00383 << " Trying to send oversized packet: size " << numBytes << "\n" 00384 << " mtu " << appBuffersize 00385 << endl; 00386 opp_error("Can't send packet: too large"); //FIXME: Throw exception instead 00387 } 00388 // If no fd is given, select a "random" one 00389 if (fd == INVALID_SOCKET) { 00390 for (fd = 0; fd <= maxfd; fd++) { 00391 if (fd == netw_fd) continue; 00392 if (fd == additional_fd) continue; 00393 if (FD_ISSET(fd, &all_fds)) break; 00394 } 00395 if (fd > maxfd) { 00396 throw cRuntimeError("Can't send packet to Application: no socket"); 00397 } 00398 } 00399 if (fd == apptun_fd) { 00400 // Application TUN FD 00401 return write(fd, buf, numBytes); 00402 } else { 00403 return send(fd, buf, numBytes, 0); 00404 } 00405 } 00406 // TBD check for errors 00407 }
void RealtimeScheduler::sendNotificationMsg | ( | cMessage * | msg, | |
cModule * | mod | |||
) |
send notification msg to module
msg | The notification Message | |
mod | The destination |
Definition at line 321 of file realtimescheduler.cc.
Referenced by UdpOutScheduler::additionalFD(), TunOutScheduler::additionalFD(), AppTunOutScheduler::additionalFD(), closeAppSocket(), and receiveWithTimeout().
00322 { 00323 if (msg->isScheduled()) return; // Notification already scheduled 00324 timeval curTime; 00325 gettimeofday(&curTime, NULL); 00326 curTime = timeval_substract(curTime, baseTime); 00327 simtime_t t = curTime.tv_sec + curTime.tv_usec*1e-6; 00328 00329 // if t < simTime, clock would go backwards. this would be bad... 00330 // (this could happen as timeval has a lower number of digits that simtime_t) 00331 if (t < simTime()) t = simTime(); 00332 00333 msg->setSentFrom(mod, -1, simTime()); 00334 msg->setArrival(mod,-1,t); 00335 simulation.msgQueue.insert(msg); 00336 }
void RealtimeScheduler::setInterfaceModule | ( | cModule * | module, | |
cMessage * | notificationMsg, | |||
PacketBuffer * | buffer, | |||
int | mtu, | |||
bool | isApp = false | |||
) | [virtual] |
To be called from the module which wishes to receive data from the tun device.
The method must be called from the module's initialize() function.
module | Pointer to the module that wants to receive the data | |
notificationMsg | A pointer to a message that will be scheduled if there is data to read | |
buffer | A pointer to the buffer the data will be written into | |
mtu | Max allowed packet size | |
isApp | set to "true" if called from a realworldApp |
Definition at line 74 of file realtimescheduler.cc.
Referenced by RealworldConnector::initialize(), and XmlRpcInterface::initializeApp().
00077 { 00078 if (!mod || !notifMsg || !buffer) { 00079 throw cRuntimeError("RealtimeScheduler: setInterfaceModule(): " 00080 "arguments must be non-NULL"); 00081 } 00082 00083 if (!isApp) { 00084 if (module) { 00085 throw cRuntimeError("RealtimeScheduler: setInterfaceModule() " 00086 "already called"); 00087 } 00088 module = mod; 00089 notificationMsg = notifMsg; 00090 packetBuffer = buffer; 00091 buffersize = mtu; 00092 } else { 00093 if (appModule) { 00094 throw cRuntimeError("RealtimeScheduler: setInterfaceModule() " 00095 "already called"); 00096 } 00097 appModule = mod; 00098 appNotificationMsg = notifMsg; 00099 appPacketBuffer = buffer; 00100 appBuffersize = mtu; 00101 } 00102 }
void RealtimeScheduler::startRun | ( | ) | [virtual] |
Called at the beginning of a simulation run.
Definition at line 46 of file realtimescheduler.cc.
00047 { 00048 if (initsocketlibonce()!=0) 00049 throw cRuntimeError("RealtimeScheduler: Cannot initialize socket library"); 00050 00051 gettimeofday(&baseTime, NULL); 00052 00053 appModule = NULL; 00054 appNotificationMsg = NULL; 00055 module = NULL; 00056 notificationMsg = NULL; 00057 00058 appConnectionLimit = ev.getConfig()->getAsInt(CFGID_EXTERNALAPP_CONNECTION_LIMIT, 0); 00059 00060 if (initializeNetwork()) { 00061 opp_error("realtimeScheduler error: initializeNetwork failed\n"); 00062 } 00063 }
SOCKET RealtimeScheduler::additional_fd [protected] |
Definition at line 86 of file realtimescheduler.h.
Referenced by UdpOutScheduler::additionalFD(), TunOutScheduler::additionalFD(), AppTunOutScheduler::additionalFD(), UdpOutScheduler::initializeNetwork(), TunOutScheduler::initializeNetwork(), AppTunOutScheduler::initializeNetwork(), RealtimeScheduler(), receiveWithTimeout(), sendBytes(), AppTunOutScheduler::~AppTunOutScheduler(), TunOutScheduler::~TunOutScheduler(), and UdpOutScheduler::~UdpOutScheduler().
fd_set RealtimeScheduler::all_fds [protected] |
Definition at line 68 of file realtimescheduler.h.
Referenced by UdpOutScheduler::additionalFD(), TunOutScheduler::additionalFD(), AppTunOutScheduler::additionalFD(), closeAppSocket(), UdpOutScheduler::initializeNetwork(), TunOutScheduler::initializeNetwork(), AppTunOutScheduler::initializeNetwork(), RealtimeScheduler(), receiveWithTimeout(), and sendBytes().
size_t RealtimeScheduler::appBuffersize [protected] |
Definition at line 83 of file realtimescheduler.h.
Referenced by receiveWithTimeout(), sendBytes(), and setInterfaceModule().
int RealtimeScheduler::appConnectionLimit [protected] |
Definition at line 84 of file realtimescheduler.h.
Referenced by UdpOutScheduler::additionalFD(), TunOutScheduler::additionalFD(), AppTunOutScheduler::additionalFD(), and startRun().
cModule* RealtimeScheduler::appModule [protected] |
Definition at line 80 of file realtimescheduler.h.
Referenced by UdpOutScheduler::additionalFD(), TunOutScheduler::additionalFD(), AppTunOutScheduler::additionalFD(), closeAppSocket(), receiveWithTimeout(), setInterfaceModule(), and startRun().
cMessage* RealtimeScheduler::appNotificationMsg [protected] |
Definition at line 81 of file realtimescheduler.h.
Referenced by UdpOutScheduler::additionalFD(), TunOutScheduler::additionalFD(), AppTunOutScheduler::additionalFD(), closeAppSocket(), receiveWithTimeout(), setInterfaceModule(), and startRun().
PacketBuffer* RealtimeScheduler::appPacketBuffer [protected] |
Definition at line 82 of file realtimescheduler.h.
Referenced by UdpOutScheduler::additionalFD(), TunOutScheduler::additionalFD(), AppTunOutScheduler::additionalFD(), closeAppSocket(), receiveWithTimeout(), and setInterfaceModule().
SOCKET RealtimeScheduler::apptun_fd [protected] |
Definition at line 73 of file realtimescheduler.h.
Referenced by getAppTunFd(), AppTunOutScheduler::initializeNetwork(), RealtimeScheduler(), receiveWithTimeout(), and sendBytes().
timeval RealtimeScheduler::baseTime [protected] |
Definition at line 89 of file realtimescheduler.h.
Referenced by executionResumed(), getNextEvent(), sendNotificationMsg(), and startRun().
size_t RealtimeScheduler::buffersize [protected] |
Definition at line 77 of file realtimescheduler.h.
Referenced by receiveWithTimeout(), sendBytes(), and setInterfaceModule().
SOCKET RealtimeScheduler::maxfd [protected] |
Definition at line 69 of file realtimescheduler.h.
Referenced by UdpOutScheduler::additionalFD(), TunOutScheduler::additionalFD(), AppTunOutScheduler::additionalFD(), UdpOutScheduler::initializeNetwork(), TunOutScheduler::initializeNetwork(), AppTunOutScheduler::initializeNetwork(), RealtimeScheduler(), receiveWithTimeout(), and sendBytes().
cModule* RealtimeScheduler::module [protected] |
Definition at line 74 of file realtimescheduler.h.
Referenced by getNextEvent(), receiveWithTimeout(), setInterfaceModule(), and startRun().
SOCKET RealtimeScheduler::netw_fd [protected] |
Definition at line 72 of file realtimescheduler.h.
Referenced by UdpOutScheduler::additionalFD(), TunOutScheduler::additionalFD(), AppTunOutScheduler::additionalFD(), UdpOutScheduler::initializeNetwork(), TunOutScheduler::initializeNetwork(), AppTunOutScheduler::initializeNetwork(), RealtimeScheduler(), receiveWithTimeout(), and sendBytes().
cMessage* RealtimeScheduler::notificationMsg [protected] |
Definition at line 75 of file realtimescheduler.h.
Referenced by receiveWithTimeout(), setInterfaceModule(), and startRun().
PacketBuffer* RealtimeScheduler::packetBuffer [protected] |
Definition at line 76 of file realtimescheduler.h.
Referenced by receiveWithTimeout(), and setInterfaceModule().