|
INET Framework for OMNeT++/OMNEST
|
00001 /* 00002 * Copyright (C) 2003 Andras Varga; CTIE, Monash University, Australia 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this program; if not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include "EtherLLC.h" 00019 #include "Ieee802Ctrl_m.h" 00020 00021 00022 Define_Module(EtherLLC); 00023 00024 void EtherLLC::initialize() 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 } 00036 00037 void EtherLLC::handleMessage(cMessage *msg) 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 } 00077 00078 void EtherLLC::updateDisplayString() 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 } 00088 00089 void EtherLLC::processPacketFromHigherLayer(cPacket *msg) 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)", (int)(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 } 00122 00123 void EtherLLC::processFrameFromMAC(EtherFrameWithLLC *frame) 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 } 00155 00156 int EtherLLC::findPortForSAP(int dsap) 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 } 00163 00164 void EtherLLC::handleRegisterSAP(cMessage *msg) 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 } 00181 00182 void EtherLLC::handleDeregisterSAP(cMessage *msg) 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 } 00196 00197 00198 void EtherLLC::handleSendPause(cMessage *msg) 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 } 00221 00222 void EtherLLC::finish() 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 } 00230