#include <EtherLLC.h>
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 |
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 }
int EtherLLC::seqNum [protected] |
Referenced by handleSendPause(), and initialize().
std::map<int,int> EtherLLC::dsapToPort [protected] |
Referenced by findPortForSAP(), handleDeregisterSAP(), and handleRegisterSAP().
long EtherLLC::dsapsRegistered [protected] |
Referenced by finish(), handleDeregisterSAP(), handleRegisterSAP(), and initialize().
long EtherLLC::totalFromHigherLayer [protected] |
Referenced by finish(), initialize(), processPacketFromHigherLayer(), and updateDisplayString().
long EtherLLC::totalFromMAC [protected] |
Referenced by finish(), initialize(), and processFrameFromMAC().
long EtherLLC::totalPassedUp [protected] |
Referenced by finish(), initialize(), processFrameFromMAC(), and updateDisplayString().
long EtherLLC::droppedUnknownDSAP [protected] |
Referenced by finish(), initialize(), processFrameFromMAC(), and updateDisplayString().