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

Implements the LLC sub-layer of the Datalink Layer in Ethernet networks. More...

#include <EtherLLC.h>

Inheritance diagram for inet::EtherLLC:
inet::ILifecycle

Public Member Functions

virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Types

typedef std::map< int, int > DsapToPortMap
 

Protected Member Functions

virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void processPacketFromHigherLayer (cPacket *msg)
 
virtual void processFrameFromMAC (EtherFrameWithLLC *msg)
 
virtual void handleRegisterSAP (cMessage *msg)
 
virtual void handleDeregisterSAP (cMessage *msg)
 
virtual void handleSendPause (cMessage *msg)
 
virtual int findPortForSAP (int sap)
 
virtual void start ()
 
virtual void stop ()
 
virtual void refreshDisplay () const override
 

Protected Attributes

int seqNum
 
DsapToPortMap dsapToPort
 
bool isUp
 
long dsapsRegistered
 
long totalFromHigherLayer
 
long totalFromMAC
 
long totalPassedUp
 
long droppedUnknownDSAP
 

Static Protected Attributes

static simsignal_t dsapSignal = registerSignal("dsap")
 
static simsignal_t encapPkSignal = registerSignal("encapPk")
 
static simsignal_t decapPkSignal = registerSignal("decapPk")
 
static simsignal_t passedUpPkSignal = registerSignal("passedUpPk")
 
static simsignal_t droppedPkUnknownDSAPSignal = registerSignal("droppedPkUnknownDSAP")
 
static simsignal_t pauseSentSignal = registerSignal("pauseSent")
 

Detailed Description

Implements the LLC sub-layer of the Datalink Layer in Ethernet networks.

Member Typedef Documentation

typedef std::map<int, int> inet::EtherLLC::DsapToPortMap
protected

Member Function Documentation

int inet::EtherLLC::findPortForSAP ( int  sap)
protectedvirtual

Referenced by processFrameFromMAC().

195 {
196  auto it = dsapToPort.find(dsap);
197  return (it == dsapToPort.end()) ? -1 : it->second;
198 }
DsapToPortMap dsapToPort
Definition: EtherLLC.h:40
void inet::EtherLLC::handleDeregisterSAP ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

220 {
221  Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->getControlInfo());
222  if (!etherctrl)
223  throw cRuntimeError("packet `%s' from higher layer received without Ieee802Ctrl", msg->getName());
224  int dsap = etherctrl->getDsap();
225 
226  EV << "Deregistering higher layer with DSAP=" << dsap << "\n";
227 
228  if (dsapToPort.find(dsap) == dsapToPort.end())
229  throw cRuntimeError("DSAP=%d not registered with port=%d", dsap, dsapToPort[dsap]);
230 
231  // delete from table (don't care if it's not in there)
232  dsapToPort.erase(dsapToPort.find(dsap));
233  dsapsRegistered = dsapToPort.size();
234  emit(dsapSignal, -1L);
235  delete msg;
236 }
DsapToPortMap dsapToPort
Definition: EtherLLC.h:40
long dsapsRegistered
Definition: EtherLLC.h:46
static simsignal_t dsapSignal
Definition: EtherLLC.h:51
void inet::EtherLLC::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
63 {
64  if (!isUp) {
65  EV << "EtherLLC is down -- discarding message\n";
66  delete msg;
67  return;
68  }
69 
70  if (msg->arrivedOn("lowerLayerIn")) {
71  // frame received from lower layer
72  EtherFrameWithLLC *etherFrameWithLLC = dynamic_cast<EtherFrameWithLLC *>(msg);
73  if (etherFrameWithLLC) {
74  processFrameFromMAC(etherFrameWithLLC);
75  }
76  else {
77  EV << "Drop received " << msg->getClassName() << " msg.\n";
78  delete msg;
79  }
80  }
81  else {
82  switch (msg->getKind()) {
83  case IEEE802CTRL_DATA:
84  // data received from higher layer
86  break;
87 
89  // higher layer registers itself
90  handleRegisterSAP(msg);
91  break;
92 
94  // higher layer deregisters itself
96  break;
97 
99  // higher layer want MAC to send PAUSE frame
100  handleSendPause(msg);
101  break;
102 
103  default:
104  throw cRuntimeError("Received message `%s' with unknown message kind %d",
105  msg->getName(), msg->getKind());
106  }
107  }
108 }
virtual void handleRegisterSAP(cMessage *msg)
Definition: EtherLLC.cc:200
Definition: Ieee802Ctrl_m.h:54
bool isUp
Definition: EtherLLC.h:43
Definition: Ieee802Ctrl_m.h:57
virtual void processFrameFromMAC(EtherFrameWithLLC *msg)
Definition: EtherLLC.cc:157
virtual void processPacketFromHigherLayer(cPacket *msg)
Definition: EtherLLC.cc:122
virtual void handleDeregisterSAP(cMessage *msg)
Definition: EtherLLC.cc:219
#define PK(msg)
Definition: INETDefs.h:92
Definition: Ieee802Ctrl_m.h:55
virtual void handleSendPause(cMessage *msg)
Definition: EtherLLC.cc:238
Definition: Ieee802Ctrl_m.h:56
bool inet::EtherLLC::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overridevirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

265 {
266  Enter_Method_Silent();
267  if (dynamic_cast<NodeStartOperation *>(operation)) {
269  start();
270  }
271  else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
273  stop();
274  }
275  else if (dynamic_cast<NodeCrashOperation *>(operation)) {
277  stop();
278  }
279  return true;
280 }
Definition: NodeOperations.h:50
Stage
Definition: NodeOperations.h:71
Stage
Definition: NodeOperations.h:126
virtual void start()
Definition: EtherLLC.cc:282
Stage
Definition: NodeOperations.h:46
Definition: NodeOperations.h:127
virtual void stop()
Definition: EtherLLC.cc:289
void inet::EtherLLC::handleRegisterSAP ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

201 {
202  int port = msg->getArrivalGate()->getIndex();
203  Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->getControlInfo());
204  if (!etherctrl)
205  throw cRuntimeError("packet `%s' from higher layer received without Ieee802Ctrl", msg->getName());
206  int dsap = etherctrl->getDsap();
207 
208  EV << "Registering higher layer with DSAP=" << dsap << " on port=" << port << "\n";
209 
210  if (dsapToPort.find(dsap) != dsapToPort.end())
211  throw cRuntimeError("DSAP=%d already registered with port=%d", dsap, dsapToPort[dsap]);
212 
213  dsapToPort[dsap] = port;
214  dsapsRegistered = dsapToPort.size();
215  emit(dsapSignal, 1L);
216  delete msg;
217 }
DsapToPortMap dsapToPort
Definition: EtherLLC.h:40
long dsapsRegistered
Definition: EtherLLC.h:46
static simsignal_t dsapSignal
Definition: EtherLLC.h:51
void inet::EtherLLC::handleSendPause ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

239 {
240  Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->getControlInfo());
241  if (!etherctrl)
242  throw cRuntimeError("PAUSE command `%s' from higher layer received without Ieee802Ctrl", msg->getName());
243 
244  int pauseUnits = etherctrl->getPauseUnits();
245  EV << "Creating and sending PAUSE frame, with duration=" << pauseUnits << " units\n";
246 
247  // create Ethernet frame
248  char framename[40];
249  sprintf(framename, "pause-%d-%d", getId(), seqNum++);
250  EtherPauseFrame *frame = new EtherPauseFrame(framename);
251  frame->setPauseTime(pauseUnits);
252  MACAddress dest = etherctrl->getDest();
253  if (dest.isUnspecified())
255  frame->setDest(dest);
256  frame->setByteLength(ETHER_PAUSE_COMMAND_PADDED_BYTES);
257 
258  send(frame, "lowerLayerOut");
259  emit(pauseSentSignal, pauseUnits);
260 
261  delete msg;
262 }
static const MACAddress MULTICAST_PAUSE_ADDRESS
The special multicast PAUSE MAC address, 01:80:C2:00:00:01.
Definition: MACAddress.h:63
static simsignal_t pauseSentSignal
Definition: EtherLLC.h:56
int seqNum
Definition: EtherLLC.h:38
#define ETHER_PAUSE_COMMAND_PADDED_BYTES
Definition: Ethernet.h:53
void inet::EtherLLC::initialize ( int  stage)
overrideprotectedvirtual
38 {
39  cSimpleModule::initialize(stage);
40 
41  if (stage == INITSTAGE_LOCAL) {
42  seqNum = 0;
43  WATCH(seqNum);
44 
46 
47  WATCH(dsapsRegistered);
48  WATCH(totalFromHigherLayer);
49  WATCH(totalFromMAC);
50  WATCH(totalPassedUp);
51  WATCH(droppedUnknownDSAP);
52  }
53  else if (stage == INITSTAGE_LINK_LAYER) {
54  // lifecycle
55  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
56  isUp = !nodeStatus || nodeStatus->getState() == NodeStatus::UP;
57  if (isUp)
58  start();
59  }
60 }
bool isUp
Definition: EtherLLC.h:43
long totalFromHigherLayer
Definition: EtherLLC.h:47
int seqNum
Definition: EtherLLC.h:38
long dsapsRegistered
Definition: EtherLLC.h:46
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Local initializations.
Definition: InitStages.h:35
Initialization of link-layer protocols.
Definition: InitStages.h:59
virtual void start()
Definition: EtherLLC.cc:282
long totalPassedUp
Definition: EtherLLC.h:49
long totalFromMAC
Definition: EtherLLC.h:48
long droppedUnknownDSAP
Definition: EtherLLC.h:50
Definition: NodeStatus.h:40
virtual int inet::EtherLLC::numInitStages ( ) const
inlineoverrideprotectedvirtual
60 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::EtherLLC::processFrameFromMAC ( EtherFrameWithLLC msg)
protectedvirtual

Referenced by handleMessage().

158 {
159  // check SAP
160  int sap = frame->getDsap();
161  int port = findPortForSAP(sap);
162  if (port < 0) {
163  EV << "No higher layer registered for DSAP=" << sap << ", discarding frame `" << frame->getName() << "'\n";
165  emit(droppedPkUnknownDSAPSignal, frame);
166  delete frame;
167  return;
168  }
169 
170  // decapsulate it and pass up to higher layer
171  cPacket *higherlayermsg = frame->decapsulate();
172 
173  Ieee802Ctrl *etherctrl = new Ieee802Ctrl();
174  etherctrl->setSsap(frame->getSsap());
175  etherctrl->setDsap(frame->getDsap());
176  etherctrl->setSrc(frame->getSrc());
177  etherctrl->setDest(frame->getDest());
178  higherlayermsg->setControlInfo(etherctrl);
179 
180  EV << "Decapsulating frame `" << frame->getName() << "', "
181  "passing up contained packet `" << higherlayermsg->getName() << "' "
182  "to higher layer " << port << "\n";
183 
184  totalFromMAC++;
185  emit(decapPkSignal, higherlayermsg);
186 
187  // pass up to higher layer
188  totalPassedUp++;
189  emit(passedUpPkSignal, higherlayermsg);
190  send(higherlayermsg, "upperLayerOut", port);
191  delete frame;
192 }
static simsignal_t passedUpPkSignal
Definition: EtherLLC.h:54
static simsignal_t droppedPkUnknownDSAPSignal
Definition: EtherLLC.h:55
virtual int findPortForSAP(int sap)
Definition: EtherLLC.cc:194
static simsignal_t decapPkSignal
Definition: EtherLLC.h:53
long totalPassedUp
Definition: EtherLLC.h:49
long totalFromMAC
Definition: EtherLLC.h:48
long droppedUnknownDSAP
Definition: EtherLLC.h:50
void inet::EtherLLC::processPacketFromHigherLayer ( cPacket *  msg)
protectedvirtual

Referenced by handleMessage().

123 {
124  if (msg->getByteLength() > (MAX_ETHERNET_DATA_BYTES - ETHER_LLC_HEADER_LENGTH))
125  throw cRuntimeError("packet from higher layer (%d bytes) plus LLC header exceeds maximum Ethernet payload length (%d)", (int)(msg->getByteLength()), MAX_ETHERNET_DATA_BYTES);
126 
128  emit(encapPkSignal, msg);
129 
130  // Creates MAC header information and encapsulates received higher layer data
131  // with this information and transmits resultant frame to lower layer
132 
133  // create Ethernet frame, fill it in from Ieee802Ctrl and encapsulate msg in it
134  EV << "Encapsulating higher layer packet `" << msg->getName() << "' for MAC\n";
135  EV << "Sent from " << getSimulation()->getModule(msg->getSenderModuleId())->getFullPath() << " at " << msg->getSendingTime() << " and was created " << msg->getCreationTime() << "\n";
136 
137  Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->removeControlInfo());
138  if (!etherctrl)
139  throw cRuntimeError("packet `%s' from higher layer received without Ieee802Ctrl", msg->getName());
140 
141  EtherFrameWithLLC *frame = new EtherFrameWithLLC(msg->getName());
142 
143  frame->setControl(0);
144  frame->setSsap(etherctrl->getSsap());
145  frame->setDsap(etherctrl->getDsap());
146  frame->setDest(etherctrl->getDest()); // src address is filled in by MAC
147  frame->setByteLength(ETHER_MAC_FRAME_BYTES + ETHER_LLC_HEADER_LENGTH);
148  delete etherctrl;
149 
150  frame->encapsulate(msg);
151  if (frame->getByteLength() < MIN_ETHERNET_FRAME_BYTES)
152  frame->setByteLength(MIN_ETHERNET_FRAME_BYTES);
153 
154  send(frame, "lowerLayerOut");
155 }
#define MAX_ETHERNET_DATA_BYTES
Definition: Ethernet.h:29
#define ETHER_MAC_FRAME_BYTES
Definition: Ethernet.h:49
static simsignal_t encapPkSignal
Definition: EtherLLC.h:52
#define ETHER_LLC_HEADER_LENGTH
Definition: Ethernet.h:50
long totalFromHigherLayer
Definition: EtherLLC.h:47
#define MIN_ETHERNET_FRAME_BYTES
Definition: Ethernet.h:31
void inet::EtherLLC::refreshDisplay ( ) const
overrideprotectedvirtual
111 {
112  char buf[80];
113  sprintf(buf, "passed up: %ld\nsent: %ld", totalPassedUp, totalFromHigherLayer);
114 
115  if (droppedUnknownDSAP > 0) {
116  sprintf(buf + strlen(buf), "\ndropped (wrong DSAP): %ld", droppedUnknownDSAP);
117  }
118 
119  getDisplayString().setTagArg("t", 0, buf);
120 }
long totalFromHigherLayer
Definition: EtherLLC.h:47
long totalPassedUp
Definition: EtherLLC.h:49
long droppedUnknownDSAP
Definition: EtherLLC.h:50
void inet::EtherLLC::start ( )
protectedvirtual

Referenced by handleOperationStage(), and initialize().

283 {
284  dsapToPort.clear();
285  dsapsRegistered = dsapToPort.size();
286  isUp = true;
287 }
bool isUp
Definition: EtherLLC.h:43
DsapToPortMap dsapToPort
Definition: EtherLLC.h:40
long dsapsRegistered
Definition: EtherLLC.h:46
void inet::EtherLLC::stop ( )
protectedvirtual

Referenced by handleOperationStage().

290 {
291  dsapToPort.clear();
292  dsapsRegistered = dsapToPort.size();
293  isUp = false;
294 }
bool isUp
Definition: EtherLLC.h:43
DsapToPortMap dsapToPort
Definition: EtherLLC.h:40
long dsapsRegistered
Definition: EtherLLC.h:46

Member Data Documentation

simsignal_t inet::EtherLLC::decapPkSignal = registerSignal("decapPk")
staticprotected

Referenced by processFrameFromMAC().

simsignal_t inet::EtherLLC::droppedPkUnknownDSAPSignal = registerSignal("droppedPkUnknownDSAP")
staticprotected

Referenced by processFrameFromMAC().

long inet::EtherLLC::droppedUnknownDSAP
protected
simsignal_t inet::EtherLLC::dsapSignal = registerSignal("dsap")
staticprotected
long inet::EtherLLC::dsapsRegistered
protected
DsapToPortMap inet::EtherLLC::dsapToPort
protected
simsignal_t inet::EtherLLC::encapPkSignal = registerSignal("encapPk")
staticprotected
bool inet::EtherLLC::isUp
protected

Referenced by handleMessage(), initialize(), start(), and stop().

simsignal_t inet::EtherLLC::passedUpPkSignal = registerSignal("passedUpPk")
staticprotected

Referenced by processFrameFromMAC().

simsignal_t inet::EtherLLC::pauseSentSignal = registerSignal("pauseSent")
staticprotected

Referenced by handleSendPause().

int inet::EtherLLC::seqNum
protected

Referenced by handleSendPause(), and initialize().

long inet::EtherLLC::totalFromHigherLayer
protected
long inet::EtherLLC::totalFromMAC
protected

Referenced by initialize(), and processFrameFromMAC().

long inet::EtherLLC::totalPassedUp
protected

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