TTEthernet Model for INET Framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
TTEthernetModel::TTEOutput Class Reference

Represents the part of a port that sends messages (TX) More...

#include <TTEOutput.h>

Inheritance diagram for TTEthernetModel::TTEOutput:

Public Member Functions

 TTEOutput ()
 Constructor. More...
 
 ~TTEOutput ()
 Destructor. More...
 
virtual void handleParameterChange (const char *parname)
 Indicates a parameter has changed. More...
 
virtual void addListener (IPassiveQueueListener *listener)
 Implementation of IPassiveQueue::addListener(). More...
 
virtual void removeListener (IPassiveQueueListener *listener)
 Implementation of IPassiveQueue::removeListener(). More...
 

Protected Member Functions

virtual void initialize ()
 Initialization of the module. More...
 
virtual void handleMessage (cMessage *msg)
 Forwards the messages from the different buffers and LLC according to the TTEthernet specification. More...
 
virtual void requestPacket ()
 this method is invoked when the underlying mac is idle. More...
 
virtual int getNumPendingRequests ()
 Returns number of requested messages. More...
 
virtual bool isEmpty ()
 Returns true when there are no pending messages. More...
 
virtual void clear ()
 Clears all queued packets and stored requests. More...
 
void notifyListeners ()
 

Static Protected Attributes

static simsignal_t ttQueueLengthSignal = SIMSIGNAL_NULL
 Signal that is emitted when the queue length of time-triggered messages changes. More...
 
static simsignal_t beQueueLengthSignal = SIMSIGNAL_NULL
 Signal that is emitted when the queue length of best-effort messages changes. More...
 
static simsignal_t pcfQueueLengthSignal = SIMSIGNAL_NULL
 Signal that is emitted when the queue length of protocol control messages changes. More...
 

Private Member Functions

virtual bool isTransmissionAllowed (EtherFrame *message)
 Helper function to check whether a Messages is allowed to be transmitted. More...
 
virtual void setTransparentClock (PCFrame *pcf)
 Sets the transparent clock field in a protocol control frame according to the actual sending time. More...
 
virtual void registerTTBuffer (TTBuffer *buffer)
 Registers a time-triggered buffer that feeds the module. More...
 

Private Attributes

cChannel * outChannel
 Outgoing Channel used to calculate transmission duration. More...
 
unsigned int framesRequested
 Number of frames that were requested from lower layer. More...
 
cQueue ttQueue
 Queue for TT-Messages. More...
 
cQueue rcQueue [NUM_RC_PRIORITIES]
 Dedicated queue for each priority of rate-constrained messages. More...
 
cQueue beQueue
 Queue for best-effort messages. More...
 
cQueue pcfQueue
 Queue for protocol control messages. More...
 
std::vector< TTBuffer * > ttBuffers
 Vector of TTBuffers. More...
 
std::list
< IPassiveQueueListener * > 
listeners
 List of TTBuffers. More...
 
size_t ttBuffersPos
 Current position of the next Buffer (action time) in the ttBuffers vector. More...
 

Detailed Description

Represents the part of a port that sends messages (TX)

Definition at line 20 of file TTEOutput.h.

Constructor & Destructor Documentation

TTEOutput::TTEOutput ( )

Constructor.

Definition at line 21 of file TTEOutput.cc.

22 {
23  framesRequested = 0;
24  ttBuffersPos = 0;
25 
26  ttQueue.setName("TT Messages");
27  for (unsigned int i = 0; i < NUM_RC_PRIORITIES; i++)
28  {
29  char strBuf[64];
30  snprintf(strBuf,64,"RC Priority %d Messages", i);
31  rcQueue[i].setName(strBuf);
32  }
33  beQueue.setName("BE Messages");
34  pcfQueue.setName("PCF Messages");
35 }
TTEOutput::~TTEOutput ( )

Destructor.

Definition at line 37 of file TTEOutput.cc.

38 {
39  ttQueue.clear();
40  for (unsigned int i = 0; i < NUM_RC_PRIORITIES; i++)
41  {
42  rcQueue[i].clear();
43  }
44  beQueue.clear();
45  pcfQueue.clear();
46 }

Member Function Documentation

void TTEOutput::addListener ( IPassiveQueueListener *  listener)
virtual

Implementation of IPassiveQueue::addListener().

Definition at line 58 of file TTEOutput.cc.

58  {
59  std::list<IPassiveQueueListener*>::iterator it = find(listeners.begin(), listeners.end(), listener);
60  if (it == listeners.end())
61  listeners.push_back(listener);
62 }
void TTEOutput::clear ( )
protectedvirtual

Clears all queued packets and stored requests.

Definition at line 376 of file TTEOutput.cc.

377 {
378  beQueue.clear();
379  for (unsigned int i = 0; i < NUM_RC_PRIORITIES; i++)
380  {
381  rcQueue[i].clear();
382  }
383  ttQueue.clear();
384  framesRequested = 0;
385 }
int TTEOutput::getNumPendingRequests ( )
protectedvirtual

Returns number of requested messages.

Definition at line 360 of file TTEOutput.cc.

361 {
362  return framesRequested;
363 }
void TTEOutput::handleMessage ( cMessage *  msg)
protectedvirtual

Forwards the messages from the different buffers and LLC according to the TTEthernet specification.

Time-triggered messages are send immediately, rate-constrained and best-effort messages are delayed if they do not fit in the gap until the next time-triggered message. If the lower layer is idle messages are picked from the queues according to the priorities. Time-triggered buffers can free the bandwidth reservation mechanism by sending a TTBufferEmpty message.

Parameters
msgthe incoming message

Definition at line 75 of file TTEOutput.cc.

76 {
77  if (msg->arrivedOn("PCFin"))
78  {
79  if (framesRequested)
80  {
82  PCFrame *pcf = dynamic_cast<PCFrame*>(msg);
83  if(pcf){
85  }
86  send(msg, gateBaseId("out"));
87 
88  }
89  else
90  {
91  pcfQueue.insert(msg);
93  emit(pcfQueueLengthSignal, pcfQueue.length());
94  }
95  }
96  else if (msg->arrivedOn("TTin"))
97  {
98  if(ttBuffers.size()>0){
99  ttBuffersPos = ((ttBuffersPos + 1) % ttBuffers.size());
100  }
101 
102  //If we have an empty message allow other frame to be sent
103  if (dynamic_cast<TTBufferEmpty *> (msg))
104  {
105  if (framesRequested)
106  {
107  framesRequested--;
108  requestPacket();
109  }
110  delete msg;
111  }
112  //Else send frame
113  else
114  {
115  if (framesRequested)
116  {
117  framesRequested--;
118  send(msg, gateBaseId("out"));
119  }
120  else
121  {
122  EV << "There might be a configuration issue (TTBuffer not registered in Output module), or shuffling was enabled for a TTBuffer or a TTFrame was delayed by a PCF" << endl;
123  ttQueue.insert(msg);
124  notifyListeners();
125  emit(ttQueueLengthSignal, ttQueue.length());
126  }
127  }
128  }
129  else if (msg->arrivedOn("RCin"))
130  {
131  if (framesRequested && isTransmissionAllowed((EtherFrame*) msg))
132  {
133  framesRequested--;
134 
135  //Reset Bag
136  RCBuffer *rcBuffer = dynamic_cast<RCBuffer*> (msg->getSenderModule());
137  if (rcBuffer)
138  rcBuffer->resetBag();
139  PCFrame *pcf = dynamic_cast<PCFrame*> (msg);
140  if(pcf){
141  setTransparentClock(pcf);
142  }
143  send(msg, gateBaseId("out"));
144  }
145  else
146  {
147  int priority = msg->getSenderModule()->par("priority").longValue();
148  if (priority > 0 && priority < NUM_RC_PRIORITIES)
149  {
150  rcQueue[priority].insert(msg);
151  notifyListeners();
152  }
153  else
154  {
155  rcQueue[0].insert(msg);
156  notifyListeners();
157  ev << "Priority missing!" << endl;
158  }
159  }
160  }
161  //Frames arrived on in are best-effort frames
162  else if (msg->arrivedOn("in"))
163  {
164  // If there are framesRequested the MAC layer is currently idle
165  if (framesRequested && isTransmissionAllowed((EtherFrame*) msg))
166  {
167  framesRequested--;
168  send(msg, gateBaseId("out"));
169  }
170  else
171  {
172  beQueue.insert(msg);
173  notifyListeners();
174  emit(beQueueLengthSignal, beQueue.length());
175  }
176  }
177 }
void TTEOutput::handleParameterChange ( const char *  parname)
virtual

Indicates a parameter has changed.

Parameters
parnameName of the changed parameter or NULL if multiple parameter changed.

Definition at line 211 of file TTEOutput.cc.

211  {
212  ttBuffers.clear();
213  if(ev.isGUI()){
214  //TODO check why this does not work
215  //getDisplayString().setTagArg("i2", 0, "");
216  //getDisplayString().setTagArg("tt", 0, "");
217  }
218  std::string ttBuffersString = par("tt_buffers").stdstringValue();
219  std::vector<std::string> ttBufferPaths;
220  split(ttBuffersString,',',ttBufferPaths);
221  for(std::vector<std::string>::iterator ttBufferPath = ttBufferPaths.begin();
222  ttBufferPath!=ttBufferPaths.end();ttBufferPath++){
223  cModule* module = simulation.getModuleByPath((*ttBufferPath).c_str());
224  if(module){
225  TTBuffer *ttBuffer = dynamic_cast<TTBuffer*> (module);
226  if(ttBuffer){
227  registerTTBuffer(ttBuffer);
228  }
229  }
230  else{
231  if(ev.isGUI()){
232  ev<<"Configuration problem: Module "<<(*ttBufferPath)<<" could not be resolved or is no TT-Buffer!"<<endl;
233  getDisplayString().setTagArg("i2", 0, "status/excl3");
234  getDisplayString().setTagArg("tt", 0, "WARNING: Configuration Problem outgoing TT-Buffer!");
235  }
236  }
237  }
238 }
void TTEOutput::initialize ( )
protectedvirtual

Initialization of the module.

Definition at line 48 of file TTEOutput.cc.

49 {
50  cGate *physOutGate = getParentModule()->getSubmodule("mac")->gate("phys$o");
51  outChannel = physOutGate->findTransmissionChannel();
52 
53  ttQueueLengthSignal = registerSignal("ttQueueLength");
54  beQueueLengthSignal = registerSignal("beQueueLength");
55  pcfQueueLengthSignal = registerSignal("pcfQueueLength");
56 }
bool TTEOutput::isEmpty ( )
protectedvirtual

Returns true when there are no pending messages.

Returns
true if all queues are empty.

Definition at line 365 of file TTEOutput.cc.

Referenced by requestPacket().

366 {
367  bool empty = true;
368  empty &= ttQueue.isEmpty();
369  for (unsigned int i = 0; i < NUM_RC_PRIORITIES; i++)
370  {
371  empty &= rcQueue[i].isEmpty();
372  }
373  empty &= beQueue.isEmpty();
374  return empty;
375 }
bool TTEOutput::isTransmissionAllowed ( EtherFrame *  message)
privatevirtual

Helper function to check whether a Messages is allowed to be transmitted.

The function checks whether a message fits in the gap until the next TT-message should be transmitted. It uses the message length to calculate the transmission duration.

Parameters
messageThe message that should be transmitted
Returns
true if transmission is allowed else false

Definition at line 292 of file TTEOutput.cc.

Referenced by handleMessage(), and requestPacket().

293 {
294  if (!outChannel)
295  {
296  return false;
297  }
298  //If there are no ttBuffers everything is fine
299  if (ttBuffers.size() == 0)
300  {
301  return true;
302  }
303  TTEScheduler *scheduler = (TTEScheduler*) getParentModule()->getParentModule()->getSubmodule("tteScheduler");
304  //SimTime sendTime = (message->getBitLength()+INTERFRAME_GAP_BITS)/txRate;
305  SimTime sendTime = outChannel->calculateDuration(message);
306  //Don't know if that is right, but it works!
307  sendTime += (INTERFRAME_GAP_BITS + ((PREAMBLE_BYTES + SFD_BYTES) * 8)) / outChannel->getNominalDatarate();
308  unsigned long sendTicks = ceil((sendTime / scheduler->par("tick")).dbl());
309  unsigned long startTicks = ttBuffers[ttBuffersPos]->par("sendWindowStart").longValue();
310  unsigned long endTicks = ttBuffers[ttBuffersPos]->par("sendWindowEnd").longValue();
311 
312  //Send Window Start is in next cycle
313  if (scheduler->getTicks() > startTicks)
314  {
315  long cycleTicks = scheduler->par("cycle_ticks").longValue();
316  startTicks += cycleTicks;
317  endTicks += cycleTicks;
318  }
319  //Send Window End is in next cycle
320  else if (scheduler->getTicks() > endTicks)
321  {
322  endTicks += scheduler->par("cycle_ticks").longValue();
323  }
324 
325  //TODO: Perhaps more complex calculations needed?
326  if ((scheduler->getTicks() + sendTicks) >= startTicks)
327  {
328  ev << "transmission not allowed!" << endl;
329  return false;
330  }
331  return true;
332 }
void TTEOutput::notifyListeners ( )
protected

Definition at line 69 of file TTEOutput.cc.

Referenced by handleMessage().

70 {
71  for (std::list<IPassiveQueueListener*>::iterator it = listeners.begin(); it != listeners.end(); ++it)
72  (*it)->packetEnqueued(this);
73 }
void TTEOutput::registerTTBuffer ( TTBuffer buffer)
privatevirtual

Registers a time-triggered buffer that feeds the module.

Definition at line 179 of file TTEOutput.cc.

Referenced by handleParameterChange().

180 {
181  Enter_Method("registerTTBuffer(%s)", ttBuffer->getName());
182  uint32_t sendWindowStart = ttBuffer->par("sendWindowStart");
183  for (std::vector<TTBuffer*>::iterator buffer = ttBuffers.begin(); buffer != ttBuffers.end();)
184  {
185  uint32_t buf_sendWindowStart = (*buffer)->par("sendWindowStart").longValue();
186  if (buffer == ttBuffers.end() || buf_sendWindowStart > sendWindowStart)
187  {
188  ttBuffers.insert(buffer, ttBuffer);
189  //Now doublecheck that the schedule is not overlapping for this port
190  for (std::vector<TTBuffer*>::iterator buffer2 = ttBuffers.begin(); buffer2 != ttBuffers.end();)
191  {
192  Buffer *tmpBuffer = *buffer2;
193  ++buffer2;
194  if (buffer2 != ttBuffers.end() && (tmpBuffer->par("sendWindowEnd").longValue() > (*buffer2)->par(
195  "sendWindowStart").longValue()))
196  {
197  opp_error("Port cannot be scheduled due to overlapping schedules: %s (End: %d) and %s (Start: %d)", tmpBuffer->getName(),
198  tmpBuffer->par("sendWindowEnd").longValue(),
199  (*buffer2)->getName(),
200  (*buffer2)->par("sendWindowStart").longValue());
201  }
202  }
203  return;
204  }
205  ++buffer;
206  }
207  //This should only happen if buffer was empty
208  ttBuffers.push_back(ttBuffer);
209 }
void TTEOutput::removeListener ( IPassiveQueueListener *  listener)
virtual

Implementation of IPassiveQueue::removeListener().

Definition at line 63 of file TTEOutput.cc.

63  {
64  std::list<IPassiveQueueListener*>::iterator it = find(listeners.begin(), listeners.end(), listener);
65  if (it != listeners.end())
66  listeners.erase(it);
67 }
void TTEOutput::requestPacket ( )
protectedvirtual

this method is invoked when the underlying mac is idle.

When this method is invoked the module sends a new message when there is one. Else it saves the state and sends the message immediately when it is received.

Definition at line 240 of file TTEOutput.cc.

Referenced by handleMessage().

241 {
242  Enter_Method("requestPacket()");
243  //Feed the MAC layer with the next frame
244  framesRequested++;
245 
246  //TTFrames
247  if (!ttQueue.isEmpty())
248  {
249  framesRequested--;
250  cMessage *msg = (cMessage*) ttQueue.pop();
251  emit(ttQueueLengthSignal, ttQueue.length());
252 
253  //TODO Update buffers:
254  if(ttBuffers.size()>0){
255  ttBuffersPos = (ttBuffersPos + 1) % ttBuffers.size();
256  }
257 
258  send(msg, gateBaseId("out"));
259  return;
260  }
261  //RCFrames
262  for (unsigned int i = 0; i < NUM_RC_PRIORITIES; i++)
263  {
264  if (!rcQueue[i].isEmpty() && isTransmissionAllowed((EtherFrame*) rcQueue[i].front()))
265  {
266  framesRequested--;
267  EtherFrame *message = (EtherFrame*) rcQueue[i].pop();
268  //Reset Bag
269  RCBuffer *rcBuffer = dynamic_cast<RCBuffer*> (message->getSenderModule());
270  if (rcBuffer)
271  rcBuffer->resetBag();
272 
273  PCFrame *pcf = dynamic_cast<PCFrame*> (message);
274  if(pcf){
275  setTransparentClock(pcf);
276  }
277  send(message, gateBaseId("out"));
278  return;
279  }
280  }
281  //BEFrames
282  if (!beQueue.isEmpty() && isTransmissionAllowed((EtherFrame*) beQueue.front()))
283  {
284  framesRequested--;
285  cMessage* message = (cMessage*) beQueue.pop();
286  send(message, gateBaseId("out"));
287  emit(beQueueLengthSignal, beQueue.length());
288  return;
289  }
290 }
void TTEOutput::setTransparentClock ( PCFrame pcf)
privatevirtual

Sets the transparent clock field in a protocol control frame according to the actual sending time.

Parameters
pcfthe protocol control frame

Definition at line 334 of file TTEOutput.cc.

Referenced by handleMessage(), and requestPacket().

334  {
335  unsigned long transparentClock = pcf->getTransparent_clock();
336 
337  //Add static delay for this port
338  transparentClock+=secondsToTransparentClock(getParentModule()->par("static_tx_delay").doubleValue());
339 
340  //Add dynamic delay for the device
341  cArray parlist = pcf->getParList();
342  unsigned long start = -1;
343  for(int i=0;i<parlist.size();i++){
344  cMsgPar *parameter = dynamic_cast<cMsgPar*>(parlist.get(i));
345  if(parameter){
346  if(strncmp(parameter->getName(),"received_total",15)==0 || strncmp(parameter->getName(),"created_total",15)==0){
347  start = parameter->longValue();
348  }
349  }
350  }
351  if(start >= 0){
352  TTEScheduler* scheduler = ((TTEScheduler*)getParentModule()->getParentModule()->getSubmodule("tteScheduler"));
353  transparentClock+=ticksToTransparentClock((scheduler->getTotalTicks()-start),scheduler->par("tick").doubleValue());
354  }
355 
356  //Set new transparent clock
357  pcf->setTransparent_clock(transparentClock);
358 }

Member Data Documentation

cQueue TTEthernetModel::TTEOutput::beQueue
private

Queue for best-effort messages.

Definition at line 71 of file TTEOutput.h.

Referenced by clear(), handleMessage(), isEmpty(), requestPacket(), TTEOutput(), and ~TTEOutput().

simsignal_t TTEOutput::beQueueLengthSignal = SIMSIGNAL_NULL
staticprotected

Signal that is emitted when the queue length of best-effort messages changes.

Definition at line 105 of file TTEOutput.h.

Referenced by handleMessage(), initialize(), and requestPacket().

unsigned int TTEthernetModel::TTEOutput::framesRequested
private

Number of frames that were requested from lower layer.

Definition at line 55 of file TTEOutput.h.

Referenced by clear(), getNumPendingRequests(), handleMessage(), requestPacket(), and TTEOutput().

std::list< IPassiveQueueListener * > TTEthernetModel::TTEOutput::listeners
private

List of TTBuffers.

The vector is ordered by action time

Definition at line 90 of file TTEOutput.h.

Referenced by addListener(), notifyListeners(), and removeListener().

cChannel* TTEthernetModel::TTEOutput::outChannel
private

Outgoing Channel used to calculate transmission duration.

Definition at line 51 of file TTEOutput.h.

Referenced by initialize(), and isTransmissionAllowed().

cQueue TTEthernetModel::TTEOutput::pcfQueue
private

Queue for protocol control messages.

Definition at line 76 of file TTEOutput.h.

Referenced by handleMessage(), TTEOutput(), and ~TTEOutput().

simsignal_t TTEOutput::pcfQueueLengthSignal = SIMSIGNAL_NULL
staticprotected

Signal that is emitted when the queue length of protocol control messages changes.

Definition at line 109 of file TTEOutput.h.

Referenced by handleMessage(), and initialize().

cQueue TTEthernetModel::TTEOutput::rcQueue[NUM_RC_PRIORITIES]
private

Dedicated queue for each priority of rate-constrained messages.

Definition at line 66 of file TTEOutput.h.

Referenced by clear(), handleMessage(), isEmpty(), requestPacket(), TTEOutput(), and ~TTEOutput().

std::vector< TTBuffer * > TTEthernetModel::TTEOutput::ttBuffers
private

Vector of TTBuffers.

The vector is ordered by action time

Definition at line 83 of file TTEOutput.h.

Referenced by handleMessage(), handleParameterChange(), isTransmissionAllowed(), registerTTBuffer(), and requestPacket().

size_t TTEthernetModel::TTEOutput::ttBuffersPos
private

Current position of the next Buffer (action time) in the ttBuffers vector.

Definition at line 95 of file TTEOutput.h.

Referenced by handleMessage(), isTransmissionAllowed(), requestPacket(), and TTEOutput().

cQueue TTEthernetModel::TTEOutput::ttQueue
private

Queue for TT-Messages.

Will be only filled when there is TT shuffling configured or there was an error in the configuration.

Definition at line 61 of file TTEOutput.h.

Referenced by clear(), handleMessage(), isEmpty(), requestPacket(), TTEOutput(), and ~TTEOutput().

simsignal_t TTEOutput::ttQueueLengthSignal = SIMSIGNAL_NULL
staticprotected

Signal that is emitted when the queue length of time-triggered messages changes.

Definition at line 100 of file TTEOutput.h.

Referenced by handleMessage(), initialize(), and requestPacket().


The documentation for this class was generated from the following files: