Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00042 processFrameFromMAC(check_and_cast<EtherFrameWithLLC *>(msg));
00043 }
00044 else
00045 {
00046 switch (msg->getKind())
00047 {
00048 case IEEE802CTRL_DATA:
00049
00050 processPacketFromHigherLayer(PK(msg));
00051 break;
00052
00053 case IEEE802CTRL_REGISTER_DSAP:
00054
00055 handleRegisterSAP(msg);
00056 break;
00057
00058 case IEEE802CTRL_DEREGISTER_DSAP:
00059
00060 handleDeregisterSAP(msg);
00061 break;
00062
00063 case IEEE802CTRL_SENDPAUSE:
00064
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
00097
00098
00099
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());
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
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
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
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
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