EtherLLC Class Reference

#include <EtherLLC.h>

List of all members.


Detailed Description

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

Protected Member Functions

virtual void initialize ()
virtual void handleMessage (cMessage *msg)
virtual void finish ()
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 updateDisplayString ()

Protected Attributes

int seqNum
std::map< int, int > dsapToPort
long dsapsRegistered
long totalFromHigherLayer
long totalFromMAC
long totalPassedUp
long droppedUnknownDSAP

Member Function Documentation

void EtherLLC::initialize (  )  [protected, virtual]

00025 {
00026     seqNum = 0;
00027     WATCH(seqNum);
00028 
00029     dsapsRegistered = totalFromHigherLayer = totalFromMAC = totalPassedUp = droppedUnknownDSAP = 0;
00030     WATCH(dsapsRegistered);
00031     WATCH(totalFromHigherLayer);
00032     WATCH(totalFromMAC);
00033     WATCH(totalPassedUp);
00034     WATCH(droppedUnknownDSAP);
00035 }

void EtherLLC::handleMessage ( cMessage *  msg  )  [protected, virtual]

00038 {
00039     if (msg->arrivedOn("lowerLayerIn"))
00040     {
00041         // frame received from lower layer
00042         processFrameFromMAC(check_and_cast<EtherFrameWithLLC *>(msg));
00043     }
00044     else
00045     {
00046         switch (msg->getKind())
00047         {
00048           case IEEE802CTRL_DATA:
00049             // data received from higher layer
00050             processPacketFromHigherLayer(PK(msg));
00051             break;
00052 
00053           case IEEE802CTRL_REGISTER_DSAP:
00054             // higher layer registers itself
00055             handleRegisterSAP(msg);
00056             break;
00057 
00058           case IEEE802CTRL_DEREGISTER_DSAP:
00059             // higher layer deregisters itself
00060             handleDeregisterSAP(msg);
00061             break;
00062 
00063           case IEEE802CTRL_SENDPAUSE:
00064             // higher layer want MAC to send PAUSE frame
00065             handleSendPause(msg);
00066             break;
00067 
00068           default:
00069             error("received message `%s' with unknown message kind %d",
00070                   msg->getName(), msg->getKind());
00071         }
00072     }
00073 
00074     if (ev.isGUI())
00075         updateDisplayString();
00076 }

void EtherLLC::finish (  )  [protected, virtual]

00223 {
00224     recordScalar("dsaps registered", dsapsRegistered);
00225     recordScalar("packets from higher layer", totalFromHigherLayer);
00226     recordScalar("frames from MAC", totalFromMAC);
00227     recordScalar("packets passed up", totalPassedUp);
00228     recordScalar("packets dropped - unknown DSAP", droppedUnknownDSAP);
00229 }

void EtherLLC::processPacketFromHigherLayer ( cPacket *  msg  )  [protected, virtual]

Referenced by handleMessage().

00090 {
00091     if (msg->getByteLength() > (MAX_ETHERNET_DATA-ETHER_LLC_HEADER_LENGTH))
00092         error("packet from higher layer (%d bytes) plus LLC header exceed maximum Ethernet payload length (%d)", msg->getByteLength(), MAX_ETHERNET_DATA);
00093 
00094     totalFromHigherLayer++;
00095 
00096     // Creates MAC header information and encapsulates received higher layer data
00097     // with this information and transmits resultant frame to lower layer
00098 
00099     // create Ethernet frame, fill it in from Ieee802Ctrl and encapsulate msg in it
00100     EV << "Encapsulating higher layer packet `" << msg->getName() <<"' for MAC\n";
00101     EV << "Sent from " << simulation.getModule(msg->getSenderModuleId())->getFullPath() << " at " << msg->getSendingTime() << " and was created " << msg->getCreationTime() <<  "\n";
00102 
00103     Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->removeControlInfo());
00104     if (!etherctrl)
00105         error("packet `%s' from higher layer received without Ieee802Ctrl", msg->getName());
00106 
00107     EtherFrameWithLLC *frame = new EtherFrameWithLLC(msg->getName());
00108 
00109     frame->setControl(0);
00110     frame->setSsap(etherctrl->getSsap());
00111     frame->setDsap(etherctrl->getDsap());
00112     frame->setDest(etherctrl->getDest()); // src address is filled in by MAC
00113     frame->setByteLength(ETHER_MAC_FRAME_BYTES+ETHER_LLC_HEADER_LENGTH);
00114     delete etherctrl;
00115 
00116     frame->encapsulate(msg);
00117     if (frame->getByteLength() < MIN_ETHERNET_FRAME)
00118         frame->setByteLength(MIN_ETHERNET_FRAME);
00119 
00120     send(frame, "lowerLayerOut");
00121 }

void EtherLLC::processFrameFromMAC ( EtherFrameWithLLC *  msg  )  [protected, virtual]

Referenced by handleMessage().

00124 {
00125     totalFromMAC++;
00126 
00127     // decapsulate it and pass up to higher layers.
00128     int sap = frame->getDsap();
00129     int port = findPortForSAP(sap);
00130     if (port<0)
00131     {
00132         EV << "No higher layer registered for DSAP="<< sap <<", discarding frame `" << frame->getName() <<"'\n";
00133         droppedUnknownDSAP++;
00134         delete frame;
00135         return;
00136     }
00137 
00138     cPacket *higherlayermsg = frame->decapsulate();
00139 
00140     Ieee802Ctrl *etherctrl = new Ieee802Ctrl();
00141     etherctrl->setSsap(frame->getSsap());
00142     etherctrl->setDsap(frame->getDsap());
00143     etherctrl->setSrc(frame->getSrc());
00144     etherctrl->setDest(frame->getDest());
00145     higherlayermsg->setControlInfo(etherctrl);
00146 
00147     EV << "Decapsulating frame `" << frame->getName() <<"', "
00148           "passing up contained packet `" << higherlayermsg->getName() << "' "
00149           "to higher layer " << port << "\n";
00150 
00151     send(higherlayermsg, "upperLayerOut", port);
00152     totalPassedUp++;
00153     delete frame;
00154 }

void EtherLLC::handleRegisterSAP ( cMessage *  msg  )  [protected, virtual]

Referenced by handleMessage().

00165 {
00166     int port = msg->getArrivalGate()->getIndex();
00167     Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->removeControlInfo());
00168     if (!etherctrl)
00169         error("packet `%s' from higher layer received without Ieee802Ctrl", msg->getName());
00170     int dsap = etherctrl->getDsap();
00171 
00172     EV << "Registering higher layer with DSAP=" << dsap << " on port=" << port << "\n";
00173 
00174     if (dsapToPort.find(dsap)!=dsapToPort.end())
00175         error("DSAP=%d already registered with port=%d", dsap, dsapToPort[dsap]);
00176 
00177     dsapToPort[dsap] = port;
00178     dsapsRegistered = dsapToPort.size();
00179     delete msg;
00180 }

void EtherLLC::handleDeregisterSAP ( cMessage *  msg  )  [protected, virtual]

Referenced by handleMessage().

00183 {
00184     Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->removeControlInfo());
00185     if (!etherctrl)
00186         error("packet `%s' from higher layer received without Ieee802Ctrl", msg->getName());
00187     int dsap = etherctrl->getDsap();
00188 
00189     EV << "Deregistering higher layer with DSAP=" << dsap << "\n";
00190 
00191     // delete from table (don't care if it's not in there)
00192     dsapToPort.erase(dsapToPort.find(dsap));
00193     dsapsRegistered = dsapToPort.size();
00194     delete msg;
00195 }

void EtherLLC::handleSendPause ( cMessage *  msg  )  [protected, virtual]

Referenced by handleMessage().

00199 {
00200     Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->removeControlInfo());
00201     if (!etherctrl)
00202         error("PAUSE command `%s' from higher layer received without Ieee802Ctrl", msg->getName());
00203 
00204     int pauseUnits = etherctrl->getPauseUnits();
00205     EV << "Creating and sending PAUSE frame, with duration=" << pauseUnits << " units\n";
00206 
00207     // create Ethernet frame
00208     char framename[30];
00209     sprintf(framename, "pause-%d-%d", getId(), seqNum++);
00210     EtherPauseFrame *frame = new EtherPauseFrame(framename);
00211     frame->setPauseTime(pauseUnits);
00212 
00213     frame->setByteLength(ETHER_MAC_FRAME_BYTES+ETHER_PAUSE_COMMAND_BYTES);
00214     if (frame->getByteLength() < MIN_ETHERNET_FRAME)
00215         frame->setByteLength(MIN_ETHERNET_FRAME);
00216 
00217     send(frame, "lowerLayerOut");
00218 
00219     delete msg;
00220 }

int EtherLLC::findPortForSAP ( int  sap  )  [protected, virtual]

Referenced by processFrameFromMAC().

00157 {
00158     // here we actually do two lookups, but what the hell...
00159     if (dsapToPort.find(dsap)==dsapToPort.end())
00160         return -1;
00161     return dsapToPort[dsap];
00162 }

void EtherLLC::updateDisplayString (  )  [protected, virtual]

Referenced by handleMessage().

00079 {
00080     char buf[80];
00081     sprintf(buf, "passed up: %ld\nsent: %ld", totalPassedUp, totalFromHigherLayer);
00082     if (droppedUnknownDSAP>0)
00083     {
00084         sprintf(buf+strlen(buf), "\ndropped (wrong DSAP): %ld", droppedUnknownDSAP);
00085     }
00086     getDisplayString().setTagArg("t",0,buf);
00087 }


Member Data Documentation

int EtherLLC::seqNum [protected]

Referenced by handleSendPause(), and initialize().

std::map<int,int> EtherLLC::dsapToPort [protected]

long EtherLLC::dsapsRegistered [protected]

long EtherLLC::totalFromMAC [protected]

long EtherLLC::totalPassedUp [protected]

long EtherLLC::droppedUnknownDSAP [protected]


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

Generated on Fri Mar 20 18:51:18 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5