INET Framework for OMNeT++/OMNEST
inet::EtherHub Class Reference

Models a wiring hub. More...

#include <EtherHub.h>

Inheritance diagram for inet::EtherHub:

Protected Member Functions

virtual void initialize () override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void finish () override
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 
virtual void checkConnections (bool errorWhenAsymmetric)
 

Protected Attributes

int numPorts
 
int inputGateBaseId
 
int outputGateBaseId
 
bool dataratesDiffer
 
long numMessages
 

Static Protected Attributes

static simsignal_t pkSignal = registerSignal("pk")
 

Detailed Description

Models a wiring hub.

It simply broadcasts the received message on all other ports.

Member Function Documentation

void inet::EtherHub::checkConnections ( bool  errorWhenAsymmetric)
protectedvirtual

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

50 {
51  int numActivePorts = 0;
52  double datarate = 0.0;
53  dataratesDiffer = false;
54 
55  for (int i = 0; i < numPorts; i++) {
56  cGate *igate = gate(inputGateBaseId + i);
57  cGate *ogate = gate(outputGateBaseId + i);
58  if (!igate->isConnected() && !ogate->isConnected())
59  continue;
60 
61  if (!igate->isConnected() || !ogate->isConnected()) {
62  // half connected gate
63  if (errorWhenAsymmetric)
64  throw cRuntimeError("The input or output gate not connected at port %i", i);
65  dataratesDiffer = true;
66  EV << "The input or output gate not connected at port " << i << ".\n";
67  continue;
68  }
69 
70  numActivePorts++;
71  double drate = igate->getIncomingTransmissionChannel()->getNominalDatarate();
72 
73  if (numActivePorts == 1)
74  datarate = drate;
75  else if (datarate != drate) {
76  if (errorWhenAsymmetric)
77  throw cRuntimeError("The input datarate at port %i differs from datarates of previous ports", i);
78  dataratesDiffer = true;
79  EV << "The input datarate at port " << i << " differs from datarates of previous ports.\n";
80  }
81 
82  cChannel *outTrChannel = ogate->getTransmissionChannel();
83  drate = outTrChannel->getNominalDatarate();
84 
85  if (datarate != drate) {
86  if (errorWhenAsymmetric)
87  throw cRuntimeError("The output datarate at port %i differs from datarates of previous ports", i);
88  dataratesDiffer = true;
89  EV << "The output datarate at port " << i << " differs from datarates of previous ports.\n";
90  }
91 
92  if (!outTrChannel->isSubscribed(POST_MODEL_CHANGE, this))
93  outTrChannel->subscribe(POST_MODEL_CHANGE, this);
94  }
95 }
bool dataratesDiffer
Definition: EtherHub.h:35
int inputGateBaseId
Definition: EtherHub.h:33
int outputGateBaseId
Definition: EtherHub.h:34
int numPorts
Definition: EtherHub.h:32
void inet::EtherHub::finish ( )
overrideprotectedvirtual
181 {
182  simtime_t t = simTime();
183  recordScalar("simulated time", t);
184 
185  if (t > 0)
186  recordScalar("messages/sec", numMessages / t);
187 }
long numMessages
Definition: EtherHub.h:38
void inet::EtherHub::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
142 {
143  if (dataratesDiffer)
144  checkConnections(true);
145 
146  // Handle frame sent down from the network entity: send out on every other port
147  int arrivalPort = msg->getArrivalGate()->getIndex();
148  EV << "Frame " << msg << " arrived on port " << arrivalPort << ", broadcasting on all other ports\n";
149 
150  numMessages++;
151  emit(pkSignal, msg);
152 
153  if (numPorts <= 1) {
154  delete msg;
155  return;
156  }
157 
158  for (int i = 0; i < numPorts; i++) {
159  if (i != arrivalPort) {
160  cGate *ogate = gate(outputGateBaseId + i);
161  if (!ogate->isConnected())
162  continue;
163 
164  bool isLast = (arrivalPort == numPorts - 1) ? (i == numPorts - 2) : (i == numPorts - 1);
165  cMessage *msg2 = isLast ? msg : msg->dup();
166 
167  // stop current transmission
168  ogate->getTransmissionChannel()->forceTransmissionFinishTime(SIMTIME_ZERO);
169 
170  // send
171  send(msg2, ogate);
172 
173  if (isLast)
174  msg = nullptr; // msg sent, do not delete it.
175  }
176  }
177  delete msg;
178 }
bool dataratesDiffer
Definition: EtherHub.h:35
virtual void checkConnections(bool errorWhenAsymmetric)
Definition: EtherHub.cc:49
int outputGateBaseId
Definition: EtherHub.h:34
static simsignal_t pkSignal
Definition: EtherHub.h:39
long numMessages
Definition: EtherHub.h:38
int numPorts
Definition: EtherHub.h:32
void inet::EtherHub::initialize ( )
overrideprotectedvirtual
33 {
34  numPorts = gateSize("ethg");
35  inputGateBaseId = gateBaseId("ethg$i");
36  outputGateBaseId = gateBaseId("ethg$o");
37 
38  numMessages = 0;
39  WATCH(numMessages);
40 
41  // ensure we receive frames when their first bits arrive
42  for (int i = 0; i < numPorts; i++)
43  gate(inputGateBaseId + i)->setDeliverOnReceptionStart(true);
44  subscribe(POST_MODEL_CHANGE, this); // we'll need to do the same for dynamically added gates as well
45 
46  checkConnections(true);
47 }
int inputGateBaseId
Definition: EtherHub.h:33
virtual void checkConnections(bool errorWhenAsymmetric)
Definition: EtherHub.cc:49
int outputGateBaseId
Definition: EtherHub.h:34
long numMessages
Definition: EtherHub.h:38
int numPorts
Definition: EtherHub.h:32
void inet::EtherHub::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overrideprotectedvirtual
98 {
99  Enter_Method_Silent();
100 
101  ASSERT(signalID == POST_MODEL_CHANGE);
102 
103  // if new gates have been added, we need to call setDeliverOnReceptionStart(true) on them
104  cPostGateVectorResizeNotification *notif = dynamic_cast<cPostGateVectorResizeNotification *>(obj);
105  if (notif) {
106  if (strcmp(notif->gateName, "ethg") == 0) {
107  int newSize = gateSize("ethg");
108  for (int i = notif->oldSize; i < newSize; i++)
109  gate(inputGateBaseId + i)->setDeliverOnReceptionStart(true);
110  }
111  return;
112  }
113 
114  cPostPathCreateNotification *connNotif = dynamic_cast<cPostPathCreateNotification *>(obj);
115  if (connNotif) {
116  if ((this == connNotif->pathStartGate->getOwnerModule()) || (this == connNotif->pathEndGate->getOwnerModule()))
117  checkConnections(false);
118  return;
119  }
120 
121  cPostPathCutNotification *cutNotif = dynamic_cast<cPostPathCutNotification *>(obj);
122  if (cutNotif) {
123  if ((this == cutNotif->pathStartGate->getOwnerModule()) || (this == cutNotif->pathEndGate->getOwnerModule()))
124  checkConnections(false);
125  return;
126  }
127 
128  // note: we are subscribed to the channel object too
129  cPostParameterChangeNotification *parNotif = dynamic_cast<cPostParameterChangeNotification *>(obj);
130  if (parNotif) {
131  cChannel *channel = dynamic_cast<cDatarateChannel *>(parNotif->par->getOwner());
132  if (channel) {
133  cGate *gate = channel->getSourceGate();
134  if (gate->pathContains(this))
135  checkConnections(false);
136  }
137  return;
138  }
139 }
int inputGateBaseId
Definition: EtherHub.h:33
virtual void checkConnections(bool errorWhenAsymmetric)
Definition: EtherHub.cc:49

Member Data Documentation

bool inet::EtherHub::dataratesDiffer
protected

Referenced by checkConnections(), and handleMessage().

int inet::EtherHub::inputGateBaseId
protected
long inet::EtherHub::numMessages
protected

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

int inet::EtherHub::numPorts
protected
int inet::EtherHub::outputGateBaseId
protected
simsignal_t inet::EtherHub::pkSignal = registerSignal("pk")
staticprotected

Referenced by handleMessage().


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