00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef _MSC_VER
00020 #pragma warning(disable:4786)
00021 #endif
00022
00023 #include <stdio.h>
00024 #include <omnetpp.h>
00025
00026 #include "Ethernet.h"
00027 #include "EtherFrame_m.h"
00028 #include "EtherCtrl_m.h"
00029 #include "utils.h"
00030
00031
00035 class EtherEncap : public cSimpleModule
00036 {
00037 protected:
00038 int seqNum;
00039
00040
00041 long totalFromHigherLayer;
00042 long totalFromMAC;
00043 long totalPauseSent;
00044
00045 public:
00046 Module_Class_Members(EtherEncap,cSimpleModule,0);
00047
00048 virtual void initialize();
00049 virtual void handleMessage(cMessage *msg);
00050 virtual void finish();
00051
00052 virtual void processPacketFromHigherLayer(cMessage *msg);
00053 virtual void processFrameFromMAC(EtherFrame *msg);
00054 virtual void handleSendPause(cMessage *msg);
00055
00056 };
00057
00058 Define_Module(EtherEncap);
00059
00060 void EtherEncap::initialize()
00061 {
00062 seqNum = 0;
00063 WATCH(seqNum);
00064
00065 totalFromHigherLayer = totalFromMAC = totalPauseSent = 0;
00066 WATCH(totalFromHigherLayer);
00067 WATCH(totalFromMAC);
00068 WATCH(totalPauseSent);
00069 }
00070
00071 void EtherEncap::handleMessage(cMessage *msg)
00072 {
00073 if (msg->arrivedOn("lowerLayerIn"))
00074 {
00075 processFrameFromMAC(check_and_cast<EtherFrame *>(msg));
00076 }
00077 else
00078 {
00079
00080 switch(msg->kind())
00081 {
00082 case 0:
00083 case ETHCTRL_DATA:
00084 processPacketFromHigherLayer(msg);
00085 break;
00086
00087 case ETHCTRL_SENDPAUSE:
00088
00089 handleSendPause(msg);
00090 break;
00091
00092 default:
00093 error("received message `%s' with unknown message kind %d", msg->name(), msg->kind());
00094 }
00095 }
00096 }
00097
00098 void EtherEncap::processPacketFromHigherLayer(cMessage *msg)
00099 {
00100 if (msg->length()>8*MAX_ETHERNET_DATA)
00101 error("packet from higher layer (%d bytes) exceeds maximum Ethernet payload length (%d)", msg->length()/8, MAX_ETHERNET_DATA);
00102
00103 totalFromHigherLayer++;
00104
00105
00106
00107
00108
00109 EV << "Encapsulating higher layer packet `" << msg->name() <<"' for MAC\n";
00110 EV << "Sent from " << simulation.module(msg->senderModuleId())->fullPath() << " at " << msg->sendingTime() << " and was created " << msg->creationTime() << "\n";
00111
00112 EtherCtrl *etherctrl = check_and_cast<EtherCtrl*>(M30(msg)->removeControlInfo());
00113 EthernetIIFrame *frame = new EthernetIIFrame(msg->name(), ETH_FRAME);
00114
00115 frame->setSrc(etherctrl->getSrc());
00116 frame->setDest(etherctrl->getDest());
00117 frame->setEtherType(etherctrl->getEtherType());
00118 frame->setLength(8*ETHER_MAC_FRAME_BYTES);
00119 delete etherctrl;
00120
00121 frame->encapsulate(msg);
00122 if (frame->length() < 8*MIN_ETHERNET_FRAME)
00123 frame->setLength(8*MIN_ETHERNET_FRAME);
00124
00125 send(frame, "lowerLayerOut");
00126 }
00127
00128 void EtherEncap::processFrameFromMAC(EtherFrame *frame)
00129 {
00130 totalFromMAC++;
00131
00132
00133 cMessage *higherlayermsg = frame->decapsulate();
00134
00135
00136 EtherCtrl *etherctrl = new EtherCtrl();
00137 etherctrl->setSrc(frame->getSrc());
00138 etherctrl->setDest(frame->getDest());
00139 M30(higherlayermsg)->setControlInfo(etherctrl);
00140
00141 EV << "Decapsulating frame `" << frame->name() <<"', passing up contained "
00142 "packet `" << higherlayermsg->name() << "' to higher layer\n";
00143
00144
00145 send(higherlayermsg, "upperLayerOut");
00146 delete frame;
00147 }
00148
00149 void EtherEncap::handleSendPause(cMessage *msg)
00150 {
00151 EtherCtrl *etherctrl = check_and_cast<EtherCtrl*>(M30(msg)->removeControlInfo());
00152 int pauseUnits = etherctrl->getPauseUnits();
00153 delete etherctrl;
00154
00155 EV << "Creating and sending PAUSE frame, with duration=" << pauseUnits << " units\n";
00156
00157
00158 char framename[30];
00159 sprintf(framename, "pause-%d-%d", id(), seqNum++);
00160 EtherPauseFrame *frame = new EtherPauseFrame(framename, ETH_PAUSE);
00161 frame->setPauseTime(pauseUnits);
00162
00163 frame->setLength(8*(ETHER_MAC_FRAME_BYTES+ETHER_PAUSE_COMMAND_BYTES));
00164 if (frame->length() < 8*MIN_ETHERNET_FRAME)
00165 frame->setLength(8*MIN_ETHERNET_FRAME);
00166
00167 send(frame, "lowerLayerOut");
00168 delete msg;
00169
00170 totalPauseSent++;
00171 }
00172
00173 void EtherEncap::finish()
00174 {
00175 if (par("writeScalars").boolValue())
00176 {
00177 recordScalar("packets from higher layer", totalFromHigherLayer);
00178 recordScalar("frames from MAC", totalFromMAC);
00179 }
00180 }
00181