Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

EtherLLC Class Reference

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 (cMessage *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)
void updateDisplayString ()

Protected Attributes

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


Member Function Documentation

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

00196 {
00197     // here we actually do two lookups, but what the hell...
00198     if (dsapToPort.find(dsap)==dsapToPort.end())
00199         return -1;
00200     return dsapToPort[dsap];
00201 }

void EtherLLC::finish  )  [protected, virtual]
 

00262 {
00263     if (par("writeScalars").boolValue())
00264     {
00265         recordScalar("dsaps registered", dsapsRegistered);
00266         recordScalar("packets from higher layer", totalFromHigherLayer);
00267         recordScalar("frames from MAC", totalFromMAC);
00268         recordScalar("packets passed up", totalPassedUp);
00269         recordScalar("packets dropped - unknown DSAP", droppedUnknownDSAP);
00270     }
00271 }

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

00222 {
00223     Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->removeControlInfo());
00224     if (!etherctrl)
00225         error("packet `%s' from higher layer received without Ieee802Ctrl", msg->name());
00226     int dsap = etherctrl->getDsap();
00227 
00228     EV << "Deregistering higher layer with DSAP=" << dsap << "\n";
00229 
00230     // delete from table (don't care if it's not in there)
00231     dsapToPort.erase(dsapToPort.find(dsap));
00232     dsapsRegistered = dsapToPort.size();
00233     delete msg;
00234 }

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

00080 {
00081     switch (msg->kind())
00082     {
00083       case IEEE802CTRL_DATA:
00084         // data received from higher layer
00085         processPacketFromHigherLayer(msg);
00086         break;
00087 
00088       case ETH_FRAME:
00089         // frame received from lower layer
00090         processFrameFromMAC(check_and_cast<EtherFrameWithLLC *>(msg));
00091         break;
00092 
00093       case IEEE802CTRL_REGISTER_DSAP:
00094         // higher layer registers itself
00095         handleRegisterSAP(msg);
00096         break;
00097 
00098       case IEEE802CTRL_DEREGISTER_DSAP:
00099         // higher layer deregisters itself
00100         handleDeregisterSAP(msg);
00101         break;
00102 
00103       case IEEE802CTRL_SENDPAUSE:
00104         // higher layer want MAC to send PAUSE frame
00105         handleSendPause(msg);
00106         break;
00107 
00108       default:
00109         error("received message `%s' with unknown message kind %d",
00110               msg->name(), msg->kind());
00111     }
00112 
00113     if (ev.isGUI())
00114         updateDisplayString();
00115 }

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

00204 {
00205     int port = msg->arrivalGate()->index();
00206     Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->removeControlInfo());
00207     if (!etherctrl)
00208         error("packet `%s' from higher layer received without Ieee802Ctrl", msg->name());
00209     int dsap = etherctrl->getDsap();
00210 
00211     EV << "Registering higher layer with DSAP=" << dsap << " on port=" << port << "\n";
00212 
00213     if (dsapToPort.find(dsap)!=dsapToPort.end())
00214         error("DSAP=%d already registered with port=%d", dsap, dsapToPort[dsap]);
00215 
00216     dsapToPort[dsap] = port;
00217     dsapsRegistered = dsapToPort.size();
00218     delete msg;
00219 }

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

00238 {
00239     Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->removeControlInfo());
00240     if (!etherctrl)
00241         error("PAUSE command `%s' from higher layer received without Ieee802Ctrl", msg->name());
00242 
00243     int pauseUnits = etherctrl->getPauseUnits();
00244     EV << "Creating and sending PAUSE frame, with duration=" << pauseUnits << " units\n";
00245 
00246     // create Ethernet frame
00247     char framename[30];
00248     sprintf(framename, "pause-%d-%d", id(), seqNum++);
00249     EtherPauseFrame *frame = new EtherPauseFrame(framename, ETH_PAUSE);
00250     frame->setPauseTime(pauseUnits);
00251 
00252     frame->setByteLength(ETHER_MAC_FRAME_BYTES+ETHER_PAUSE_COMMAND_BYTES);
00253     if (frame->byteLength() < MIN_ETHERNET_FRAME)
00254         frame->setByteLength(MIN_ETHERNET_FRAME);
00255 
00256     send(frame, "lowerLayerOut");
00257 
00258     delete msg;
00259 }

void EtherLLC::initialize  )  [protected, virtual]
 

00067 {
00068     seqNum = 0;
00069     WATCH(seqNum);
00070 
00071     dsapsRegistered = totalFromHigherLayer = totalFromMAC = totalPassedUp = droppedUnknownDSAP = 0;
00072     WATCH(dsapsRegistered);
00073     WATCH(totalFromHigherLayer);
00074     WATCH(totalFromMAC);
00075     WATCH(totalPassedUp);
00076     WATCH(droppedUnknownDSAP);
00077 }

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

00163 {
00164     totalFromMAC++;
00165 
00166     // decapsulate it and pass up to higher layers.
00167     int sap = frame->getDsap();
00168     int port = findPortForSAP(sap);
00169     if (port<0)
00170     {
00171         EV << "No higher layer registered for DSAP="<< sap <<", discarding frame `" << frame->name() <<"'\n";
00172         droppedUnknownDSAP++;
00173         delete frame;
00174         return;
00175     }
00176 
00177     cMessage *higherlayermsg = frame->decapsulate();
00178 
00179     Ieee802Ctrl *etherctrl = new Ieee802Ctrl();
00180     etherctrl->setSsap(frame->getSsap());
00181     etherctrl->setDsap(frame->getDsap());
00182     etherctrl->setSrc(frame->getSrc());
00183     etherctrl->setDest(frame->getDest());
00184     higherlayermsg->setControlInfo(etherctrl);
00185 
00186     EV << "Decapsulating frame `" << frame->name() <<"', "
00187           "passing up contained packet `" << higherlayermsg->name() << "' "
00188           "to higher layer " << port << "\n";
00189 
00190     send(higherlayermsg, "upperLayerOut", port);
00191     totalPassedUp++;
00192     delete frame;
00193 }

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

00129 {
00130     if (msg->byteLength() > (MAX_ETHERNET_DATA-ETHER_LLC_HEADER_LENGTH))
00131         error("packet from higher layer (%d bytes) plus LLC header exceed maximum Ethernet payload length (%d)", msg->byteLength(), MAX_ETHERNET_DATA);
00132 
00133     totalFromHigherLayer++;
00134 
00135     // Creates MAC header information and encapsulates received higher layer data
00136     // with this information and transmits resultant frame to lower layer
00137 
00138     // create Ethernet frame, fill it in from Ieee802Ctrl and encapsulate msg in it
00139     EV << "Encapsulating higher layer packet `" << msg->name() <<"' for MAC\n";
00140     EV << "Sent from " << simulation.module(msg->senderModuleId())->fullPath() << " at " << msg->sendingTime() << " and was created " << msg->creationTime() <<  "\n";
00141 
00142     Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl *>(msg->removeControlInfo());
00143     if (!etherctrl)
00144         error("packet `%s' from higher layer received without Ieee802Ctrl", msg->name());
00145 
00146     EtherFrameWithLLC *frame = new EtherFrameWithLLC(msg->name(), ETH_FRAME);
00147 
00148     frame->setControl(0);
00149     frame->setSsap(etherctrl->getSsap());
00150     frame->setDsap(etherctrl->getDsap());
00151     frame->setDest(etherctrl->getDest()); // src address is filled in by MAC
00152     frame->setByteLength(ETHER_MAC_FRAME_BYTES+ETHER_LLC_HEADER_LENGTH);
00153     delete etherctrl;
00154 
00155     frame->encapsulate(msg);
00156     if (frame->byteLength() < MIN_ETHERNET_FRAME)
00157         frame->setByteLength(MIN_ETHERNET_FRAME);
00158 
00159     send(frame, "lowerLayerOut");
00160 }

void EtherLLC::updateDisplayString  )  [protected]
 

00118 {
00119     char buf[80];
00120     sprintf(buf, "passed up: %ld\nsent: %ld", totalPassedUp, totalFromHigherLayer);
00121     if (droppedUnknownDSAP>0)
00122     {
00123         sprintf(buf+strlen(buf), "\ndropped (wrong DSAP): %ld", droppedUnknownDSAP);
00124     }
00125     displayString().setTagArg("t",0,buf);
00126 }


Member Data Documentation

long EtherLLC::droppedUnknownDSAP [protected]
 

long EtherLLC::dsapsRegistered [protected]
 

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

int EtherLLC::seqNum [protected]
 

long EtherLLC::totalFromHigherLayer [protected]
 

long EtherLLC::totalFromMAC [protected]
 

long EtherLLC::totalPassedUp [protected]
 


The documentation for this class was generated from the following file:
Generated on Sat Apr 1 20:52:21 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.1