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
00024 #include "MACRelayUnitPP.h"
00025
00026 #include "EtherFrame_m.h"
00027 #include "utils.h"
00028 #include "Ethernet.h"
00029 #include "MACAddress.h"
00030
00031
00032
00033 Define_Module( MACRelayUnitPP );
00034
00035
00036
00037 #ifndef OPP3
00038 static cEnvir& operator<< (cEnvir& ev, const MACAddress& addr)
00039 {
00040 char buf[20];
00041 EV << addr.toHexString(buf);
00042 return ev;
00043 }
00044 #endif
00045
00046 static cEnvir& operator<< (cEnvir& ev, cMessage *msg)
00047 {
00048 ev.printf("(%s)%s",msg->className(),msg->fullName());
00049 return ev;
00050 }
00051
00052
00053 void MACRelayUnitPP::initialize()
00054 {
00055 MACRelayUnitBase::initialize();
00056
00057 bufferLevel.setName("buffer level");
00058
00059 numProcessedFrames = numDroppedFrames = 0;
00060 WATCH(numProcessedFrames);
00061 WATCH(numDroppedFrames);
00062
00063 processingTime = par("processingTime");
00064 bufferSize = par("bufferSize");
00065 highWatermark = par("highWatermark");
00066 pauseUnits = par("pauseUnits");
00067
00068
00069
00070 pauseInterval = pauseUnits*512.0/100000.0;
00071
00072 pauseLastSent = 0;
00073 WATCH(pauseLastSent);
00074
00075 bufferUsed = 0;
00076 WATCH(bufferUsed);
00077
00078 buffer = new PortBuffer[numPorts];
00079 for (int i = 0; i < numPorts; ++i)
00080 {
00081 buffer[i].port = i;
00082 buffer[i].cpuBusy = false;
00083
00084 char qname[20];
00085 sprintf(qname,"portQueue%d",i);
00086 buffer[i].queue.setName(qname);
00087 }
00088
00089 EV << "Parameters of (" << className() << ") " << fullPath() << "\n";
00090 EV << "processing time: " << processingTime << "\n";
00091 EV << "ports: " << numPorts << "\n";
00092 EV << "buffer size: " << bufferSize << "\n";
00093 EV << "address table size: " << addressTableSize << "\n";
00094 EV << "aging time: " << agingTime << "\n";
00095 EV << "high watermark: " << highWatermark << "\n";
00096 EV << "pause time: " << pauseUnits << "\n";
00097 EV << "\n";
00098 }
00099
00100 void MACRelayUnitPP::handleMessage(cMessage *msg)
00101 {
00102 if (!msg->isSelfMessage())
00103 {
00104
00105 if (msg->kind()!=ETH_FRAME)
00106 error("Unknown incoming frame");
00107
00108 handleIncomingFrame((EtherFrame *)msg);
00109 }
00110 else
00111 {
00112
00113 processFrame(msg);
00114 }
00115 }
00116
00117 void MACRelayUnitPP::handleIncomingFrame(EtherFrame *frame)
00118 {
00119
00120
00121 long length = frame->length()/8;
00122 if (length + bufferUsed < bufferSize)
00123 {
00124 int inputport = frame->arrivalGate()->index();
00125 buffer[inputport].queue.insert(frame);
00126 buffer[inputport].port = inputport;
00127 bufferUsed += length;
00128
00129
00130 if (pauseUnits>0 && highWatermark>0 && bufferUsed>=highWatermark && pauseLastSent-simTime()>pauseInterval)
00131 {
00132
00133 for (int i=0; i<numPorts; i++)
00134 sendPauseFrame(i, pauseUnits);
00135 pauseLastSent = simTime();
00136 }
00137
00138 if (buffer[inputport].cpuBusy)
00139 {
00140 EV << "Port CPU " << inputport << " busy, incoming frame " << frame << " enqueued for later processing\n";
00141 }
00142 else
00143 {
00144 EV << "Port CPU " << inputport << " free, begin processing of incoming frame " << frame << endl;
00145 buffer[inputport].cpuBusy = true;
00146 cMessage *msg = new cMessage("endProcessing");
00147 msg->setContextPointer(&buffer[inputport]);
00148 scheduleAt(simTime() + processingTime, msg);
00149 }
00150 }
00151
00152 else
00153 {
00154 EV << "Buffer full, dropping frame " << frame << endl;
00155 delete frame;
00156 ++numDroppedFrames;
00157 }
00158
00159
00160 bufferLevel.record(bufferUsed);
00161 }
00162
00163 void MACRelayUnitPP::processFrame(cMessage *msg)
00164 {
00165
00166 PortBuffer *pBuff = (PortBuffer*)msg->contextPointer();
00167 EtherFrame *frame = (EtherFrame*)pBuff->queue.pop();
00168 long length = frame->length()/8;
00169 int inputport = pBuff->port;
00170
00171 EV << "Port CPU " << inputport << " completed processing of frame " << frame << endl;
00172
00173 handleAndDispatchFrame(frame, inputport);
00174 printAddressTable();
00175
00176 bufferUsed -= length;
00177 bufferLevel.record(bufferUsed);
00178
00179 numProcessedFrames++;
00180
00181
00182 if (!pBuff->queue.empty())
00183 {
00184 EV << "Begin processing of next frame\n";
00185 scheduleAt(simTime()+processingTime, msg);
00186 }
00187 else
00188 {
00189 EV << "Port CPU idle\n";
00190 pBuff->cpuBusy = false;
00191 delete msg;
00192 }
00193 }
00194
00195 void MACRelayUnitPP::finish()
00196 {
00197 if (par("writeScalars").boolValue())
00198 {
00199 recordScalar("processed frames", numProcessedFrames);
00200 recordScalar("dropped frames", numDroppedFrames);
00201 }
00202 }
00203