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 <stdio.h>
00019 #include "EtherEncap.h"
00020 #include "EtherFrame_m.h"
00021 #include "Ieee802Ctrl_m.h"
00022 #include "IInterfaceTable.h"
00023 #include "InterfaceTableAccess.h"
00024 #include "EtherMAC.h"
00025
00026
00027 Define_Module(EtherEncap);
00028
00029 void EtherEncap::initialize()
00030 {
00031 seqNum = 0;
00032 WATCH(seqNum);
00033
00034 totalFromHigherLayer = totalFromMAC = totalPauseSent = 0;
00035 WATCH(totalFromHigherLayer);
00036 WATCH(totalFromMAC);
00037 WATCH(totalPauseSent);
00038 }
00039
00040 void EtherEncap::handleMessage(cMessage *msg)
00041 {
00042 if (msg->arrivedOn("lowerLayerIn"))
00043 {
00044 processFrameFromMAC(check_and_cast<EtherFrame *>(msg));
00045 }
00046 else
00047 {
00048
00049 switch(msg->getKind())
00050 {
00051 case IEEE802CTRL_DATA:
00052 case 0:
00053 processPacketFromHigherLayer(PK(msg));
00054 break;
00055
00056 case IEEE802CTRL_SENDPAUSE:
00057
00058 handleSendPause(msg);
00059 break;
00060
00061 default:
00062 error("received message `%s' with unknown message kind %d", msg->getName(), msg->getKind());
00063 }
00064 }
00065
00066 if (ev.isGUI())
00067 updateDisplayString();
00068 }
00069
00070 void EtherEncap::updateDisplayString()
00071 {
00072 char buf[80];
00073 sprintf(buf, "passed up: %ld\nsent: %ld", totalFromMAC, totalFromHigherLayer);
00074 getDisplayString().setTagArg("t",0,buf);
00075 }
00076
00077 void EtherEncap::processPacketFromHigherLayer(cPacket *msg)
00078 {
00079 if (msg->getByteLength() > MAX_ETHERNET_DATA)
00080 error("packet from higher layer (%d bytes) exceeds maximum Ethernet payload length (%d)", (int)msg->getByteLength(), MAX_ETHERNET_DATA);
00081
00082 totalFromHigherLayer++;
00083
00084
00085
00086
00087
00088 EV << "Encapsulating higher layer packet `" << msg->getName() <<"' for MAC\n";
00089
00090 Ieee802Ctrl *etherctrl = check_and_cast<Ieee802Ctrl*>(msg->removeControlInfo());
00091 EthernetIIFrame *frame = new EthernetIIFrame(msg->getName());
00092
00093 frame->setSrc(etherctrl->getSrc());
00094 frame->setDest(etherctrl->getDest());
00095 frame->setEtherType(etherctrl->getEtherType());
00096 frame->setByteLength(ETHER_MAC_FRAME_BYTES);
00097 delete etherctrl;
00098
00099 frame->encapsulate(msg);
00100 if (frame->getByteLength() < MIN_ETHERNET_FRAME)
00101 frame->setByteLength(MIN_ETHERNET_FRAME);
00102
00103 send(frame, "lowerLayerOut");
00104 }
00105
00106 void EtherEncap::processFrameFromMAC(EtherFrame *frame)
00107 {
00108 totalFromMAC++;
00109
00110
00111 cPacket *higherlayermsg = frame->decapsulate();
00112
00113
00114 Ieee802Ctrl *etherctrl = new Ieee802Ctrl();
00115 etherctrl->setSrc(frame->getSrc());
00116 etherctrl->setDest(frame->getDest());
00117 higherlayermsg->setControlInfo(etherctrl);
00118
00119 EV << "Decapsulating frame `" << frame->getName() <<"', passing up contained "
00120 "packet `" << higherlayermsg->getName() << "' to higher layer\n";
00121
00122
00123 send(higherlayermsg, "upperLayerOut");
00124 delete frame;
00125 }
00126
00127 void EtherEncap::handleSendPause(cMessage *msg)
00128 {
00129 Ieee802Ctrl *etherctrl = dynamic_cast<Ieee802Ctrl*>(msg->removeControlInfo());
00130 if (!etherctrl)
00131 error("PAUSE command `%s' from higher layer received without Ieee802Ctrl", msg->getName());
00132 int pauseUnits = etherctrl->getPauseUnits();
00133 delete etherctrl;
00134
00135 EV << "Creating and sending PAUSE frame, with duration=" << pauseUnits << " units\n";
00136
00137
00138 char framename[30];
00139 sprintf(framename, "pause-%d-%d", getId(), seqNum++);
00140 EtherPauseFrame *frame = new EtherPauseFrame(framename);
00141 frame->setPauseTime(pauseUnits);
00142
00143 frame->setByteLength(ETHER_MAC_FRAME_BYTES+ETHER_PAUSE_COMMAND_BYTES);
00144 if (frame->getByteLength() < MIN_ETHERNET_FRAME)
00145 frame->setByteLength(MIN_ETHERNET_FRAME);
00146
00147 send(frame, "lowerLayerOut");
00148 delete msg;
00149
00150 totalPauseSent++;
00151 }
00152
00153 void EtherEncap::finish()
00154 {
00155 recordScalar("packets from higher layer", totalFromHigherLayer);
00156 recordScalar("frames from MAC", totalFromMAC);
00157 }
00158
00159