EtherMACBase Class Reference

#include <EtherMACBase.h>

Inheritance diagram for EtherMACBase:

INotifiable EtherMAC EtherMAC2

List of all members.


Detailed Description

Base class for ethernet MAC implementations.

Public Member Functions

 EtherMACBase ()
virtual ~EtherMACBase ()
virtual long getQueueLength ()
virtual MACAddress getMACAddress ()

Protected Member Functions

virtual void initialize ()
virtual void initializeTxrate ()=0
virtual void initializeFlags ()
virtual void initializeMACAddress ()
virtual void initializeQueueModule ()
virtual void initializeNotificationBoard ()
virtual void initializeStatistics ()
virtual void registerInterface (double txrate)
virtual bool checkDestinationAddress (EtherFrame *frame)
virtual void calculateParameters ()
virtual void printParameters ()
virtual void finish ()
virtual void processFrameFromUpperLayer (EtherFrame *msg)
virtual void processMsgFromNetwork (cPacket *msg)
virtual void processMessageWhenNotConnected (cMessage *msg)
virtual void processMessageWhenDisabled (cMessage *msg)
virtual void handleEndIFGPeriod ()
virtual void handleEndTxPeriod ()
virtual void handleEndPausePeriod ()
virtual void scheduleEndIFGPeriod ()
virtual void scheduleEndTxPeriod (cPacket *)
virtual void scheduleEndPausePeriod (int pauseUnits)
virtual bool checkAndScheduleEndPausePeriod ()
virtual void fireChangeNotification (int type, cPacket *msg)
virtual void beginSendFrames ()
virtual void frameReceptionComplete (EtherFrame *frame)
virtual void processReceivedDataFrame (EtherFrame *frame)
virtual void processPauseCommand (int pauseUnits)
virtual void updateDisplayString ()
virtual void updateConnectionColor (int txState)
virtual void updateHasSubcribers ()=0
virtual void receiveChangeNotification (int category, const cPolymorphic *details)

Protected Attributes

bool connected
bool disabled
bool promiscuous
MACAddress address
int txQueueLimit
bool duplexMode
bool carrierExtension
bool frameBursting
double txrate
simtime_t bitTime
simtime_t slotTime
simtime_t interFrameGap
simtime_t jamDuration
simtime_t shortestFrameDuration
int transmitState
int receiveState
int pauseUnitsRequested
cQueue txQueue
IPassiveQueuequeueModule
cGate * physOutGate
InterfaceEntryinterfaceEntry
NotificationBoardnb
TxNotifDetails notifDetails
bool hasSubscribers
cMessage * endTxMsg
cMessage * endIFGMsg
cMessage * endPauseMsg
int framesSentInBurst
int bytesSentInBurst
unsigned long numFramesSent
unsigned long numFramesReceivedOK
unsigned long numBytesSent
unsigned long numBytesReceivedOK
unsigned long numFramesFromHL
unsigned long numDroppedIfaceDown
unsigned long numDroppedBitError
unsigned long numDroppedNotForUs
unsigned long numFramesPassedToHL
unsigned long numPauseFramesRcvd
unsigned long numPauseFramesSent
cOutVector numFramesSentVector
cOutVector numFramesReceivedOKVector
cOutVector numBytesSentVector
cOutVector numBytesReceivedOKVector
cOutVector numDroppedIfaceDownVector
cOutVector numDroppedBitErrorVector
cOutVector numDroppedNotForUsVector
cOutVector numFramesPassedToHLVector
cOutVector numPauseFramesRcvdVector
cOutVector numPauseFramesSentVector

Constructor & Destructor Documentation

EtherMACBase::EtherMACBase (  ) 

00030 {
00031     nb = NULL;
00032     queueModule = NULL;
00033     interfaceEntry = NULL;
00034     endTxMsg = endIFGMsg = endPauseMsg = NULL;
00035 }

EtherMACBase::~EtherMACBase (  )  [virtual]

00038 {
00039     cancelAndDelete(endTxMsg);
00040     cancelAndDelete(endIFGMsg);
00041     cancelAndDelete(endPauseMsg);
00042 }


Member Function Documentation

virtual long EtherMACBase::getQueueLength (  )  [inline, virtual]

00130 {return txQueue.length();}

virtual MACAddress EtherMACBase::getMACAddress (  )  [inline, virtual]

00131 {return address;}

void EtherMACBase::initialize (  )  [protected, virtual]

Reimplemented in EtherMAC, and EtherMAC2.

Referenced by EtherMAC2::initialize(), and EtherMAC::initialize().

00045 {
00046     physOutGate = gate("phys$o");
00047 
00048     initializeFlags();
00049 
00050     initializeTxrate();
00051     WATCH(txrate);
00052 
00053     initializeMACAddress();
00054     initializeQueueModule();
00055     initializeNotificationBoard();
00056     initializeStatistics();
00057 
00058     registerInterface(txrate); // needs MAC address
00059 
00060     // initialize queue
00061     txQueue.setName("txQueue");
00062 
00063     // initialize self messages
00064     endTxMsg = new cMessage("EndTransmission", ENDTRANSMISSION);
00065     endIFGMsg = new cMessage("EndIFG", ENDIFG);
00066     endPauseMsg = new cMessage("EndPause", ENDPAUSE);
00067 
00068     // initialize states
00069     transmitState = TX_IDLE_STATE;
00070     receiveState = RX_IDLE_STATE;
00071     WATCH(transmitState);
00072     WATCH(receiveState);
00073 
00074     // initalize pause
00075     pauseUnitsRequested = 0;
00076     WATCH(pauseUnitsRequested);
00077 
00078     // initialize queue limit
00079     txQueueLimit = par("txQueueLimit");
00080     WATCH(txQueueLimit);
00081 }

virtual void EtherMACBase::initializeTxrate (  )  [protected, pure virtual]

Implemented in EtherMAC, and EtherMAC2.

Referenced by initialize().

void EtherMACBase::initializeFlags (  )  [protected, virtual]

Referenced by initialize().

00124 {
00125     // initialize connected flag
00126     connected = physOutGate->getPathEndGate()->isConnected();
00127     if (!connected)
00128         EV << "MAC not connected to a network.\n";
00129     WATCH(connected);
00130 
00131     // TODO: this should be settable from the gui
00132     // initialize disabled flag
00133     // Note: it is currently not supported to enable a disabled MAC at runtime.
00134     // Difficulties: (1) autoconfig (2) how to pick up channel state (free, tx, collision etc)
00135     disabled = false;
00136     WATCH(disabled);
00137 
00138     // initialize promiscuous flag
00139     promiscuous = par("promiscuous");
00140     WATCH(promiscuous);
00141 }

void EtherMACBase::initializeMACAddress (  )  [protected, virtual]

Referenced by initialize().

00095 {
00096     const char *addrstr = par("address");
00097 
00098     if (!strcmp(addrstr,"auto"))
00099     {
00100         // assign automatic address
00101         address = MACAddress::generateAutoAddress();
00102 
00103         // change module parameter from "auto" to concrete address
00104         par("address").setStringValue(address.str().c_str());
00105     }
00106     else
00107     {
00108         address.setAddress(addrstr);
00109     }
00110 }

void EtherMACBase::initializeQueueModule (  )  [protected, virtual]

Referenced by initialize().

00084 {
00085     if (par("queueModule").stringValue()[0])
00086     {
00087         cModule *module = getParentModule()->getSubmodule(par("queueModule").stringValue());
00088         queueModule = check_and_cast<IPassiveQueue *>(module);
00089         EV << "Requesting first frame from queue module\n";
00090         queueModule->requestPacket();
00091     }
00092 }

void EtherMACBase::initializeNotificationBoard (  )  [protected, virtual]

Referenced by initialize().

00113 {
00114     hasSubscribers = false;
00115     if (interfaceEntry) {
00116         nb = NotificationBoardAccess().getIfExists();
00117         notifDetails.setInterfaceEntry(interfaceEntry);
00118         nb->subscribe(this, NF_SUBSCRIBERLIST_CHANGED);
00119         updateHasSubcribers();
00120     }
00121 }

void EtherMACBase::initializeStatistics (  )  [protected, virtual]

Referenced by initialize().

00144 {
00145     framesSentInBurst = 0;
00146     bytesSentInBurst = 0;
00147 
00148     numFramesSent = numFramesReceivedOK = numBytesSent = numBytesReceivedOK = 0;
00149     numFramesPassedToHL = numDroppedBitError = numDroppedNotForUs = 0;
00150     numFramesFromHL = numDroppedIfaceDown = 0;
00151     numPauseFramesRcvd = numPauseFramesSent = 0;
00152 
00153     WATCH(framesSentInBurst);
00154     WATCH(bytesSentInBurst);
00155 
00156     WATCH(numFramesSent);
00157     WATCH(numFramesReceivedOK);
00158     WATCH(numBytesSent);
00159     WATCH(numBytesReceivedOK);
00160     WATCH(numFramesFromHL);
00161     WATCH(numDroppedIfaceDown);
00162     WATCH(numDroppedBitError);
00163     WATCH(numDroppedNotForUs);
00164     WATCH(numFramesPassedToHL);
00165     WATCH(numPauseFramesRcvd);
00166     WATCH(numPauseFramesSent);
00167 
00168     numFramesSentVector.setName("framesSent");
00169     numFramesReceivedOKVector.setName("framesReceivedOK");
00170     numBytesSentVector.setName("bytesSent");
00171     numBytesReceivedOKVector.setName("bytesReceivedOK");
00172     numDroppedIfaceDownVector.setName("framesDroppedIfaceDown");
00173     numDroppedBitErrorVector.setName("framesDroppedBitError");
00174     numDroppedNotForUsVector.setName("framesDroppedNotForUs");
00175     numFramesPassedToHLVector.setName("framesPassedToHL");
00176     numPauseFramesRcvdVector.setName("pauseFramesRcvd");
00177     numPauseFramesSentVector.setName("pauseFramesSent");
00178 }

void EtherMACBase::registerInterface ( double  txrate  )  [protected, virtual]

Referenced by initialize().

00181 {
00182     IInterfaceTable *ift = InterfaceTableAccess().getIfExists();
00183     if (!ift)
00184         return;
00185 
00186     interfaceEntry = new InterfaceEntry();
00187 
00188     // interface name: our module name without special characters ([])
00189     char *interfaceName = new char[strlen(getParentModule()->getFullName())+1];
00190     char *d=interfaceName;
00191     for (const char *s=getParentModule()->getFullName(); *s; s++)
00192         if (isalnum(*s))
00193             *d++ = *s;
00194     *d = '\0';
00195 
00196     interfaceEntry->setName(interfaceName);
00197     delete [] interfaceName;
00198 
00199     // data rate
00200     interfaceEntry->setDatarate(txrate);
00201 
00202     // generate a link-layer address to be used as interface token for IPv6
00203     interfaceEntry->setMACAddress(address);
00204     interfaceEntry->setInterfaceToken(address.formInterfaceIdentifier());
00205     //InterfaceToken token(0, simulation.getUniqueNumber(), 64);
00206     //interfaceEntry->setInterfaceToken(token);
00207 
00208     // MTU: typical values are 576 (Internet de facto), 1500 (Ethernet-friendly),
00209     // 4000 (on some point-to-point links), 4470 (Cisco routers default, FDDI compatible)
00210     interfaceEntry->setMtu(par("mtu"));
00211 
00212     // capabilities
00213     interfaceEntry->setMulticast(true);
00214     interfaceEntry->setBroadcast(true);
00215 
00216     // add
00217     ift->addInterface(interfaceEntry, this);
00218 }

bool EtherMACBase::checkDestinationAddress ( EtherFrame *  frame  )  [protected, virtual]

Referenced by EtherMAC2::processMsgFromNetwork(), and processReceivedDataFrame().

00222 {
00223     // If not set to promiscuous = on, then checks if received frame contains destination MAC address
00224     // matching port's MAC address, also checks if broadcast bit is set
00225     if (!promiscuous && !frame->getDest().isBroadcast() && !frame->getDest().equals(address))
00226     {
00227         EV << "Frame `" << frame->getName() <<"' not destined to us, discarding\n";
00228         numDroppedNotForUs++;
00229         numDroppedNotForUsVector.record(numDroppedNotForUs);
00230         delete frame;
00231 
00232         return false;
00233     }
00234 
00235     return true;
00236 }

void EtherMACBase::calculateParameters (  )  [protected, virtual]

Referenced by EtherMAC::handleAutoconfigMessage(), EtherMAC2::initialize(), and EtherMAC::initialize().

00239 {
00240     if (disabled || !connected)
00241     {
00242         bitTime = slotTime = interFrameGap = jamDuration = shortestFrameDuration = 0;
00243         carrierExtension = frameBursting = false;
00244         return;
00245     }
00246 
00247     if (txrate != ETHERNET_TXRATE && txrate != FAST_ETHERNET_TXRATE &&
00248         txrate != GIGABIT_ETHERNET_TXRATE && txrate != FAST_GIGABIT_ETHERNET_TXRATE)
00249     {
00250         error("nonstandard transmission rate %g, must be %g, %g, %g or %g bit/sec",
00251             txrate, ETHERNET_TXRATE, FAST_ETHERNET_TXRATE, GIGABIT_ETHERNET_TXRATE, FAST_GIGABIT_ETHERNET_TXRATE);
00252     }
00253 
00254     bitTime = 1/(double)txrate;
00255 
00256     // set slot time
00257     if (txrate==ETHERNET_TXRATE || txrate==FAST_ETHERNET_TXRATE)
00258         slotTime = SLOT_TIME;
00259     else
00260         slotTime = GIGABIT_SLOT_TIME;
00261 
00262     // only if Gigabit Ethernet
00263     frameBursting = (txrate==GIGABIT_ETHERNET_TXRATE || txrate==FAST_GIGABIT_ETHERNET_TXRATE);
00264     carrierExtension = (slotTime == GIGABIT_SLOT_TIME && !duplexMode);
00265 
00266     interFrameGap = INTERFRAME_GAP_BITS/(double)txrate;
00267     jamDuration = 8*JAM_SIGNAL_BYTES*bitTime;
00268     shortestFrameDuration = carrierExtension ? GIGABIT_MIN_FRAME_WITH_EXT : MIN_ETHERNET_FRAME;
00269 }

void EtherMACBase::printParameters (  )  [protected, virtual]

00272 {
00273     // Dump parameters
00274     EV << "MAC address: " << address << (promiscuous ? ", promiscuous mode" : "") << endl;
00275     EV << "txrate: " << txrate << ", " << (duplexMode ? "duplex" : "half-duplex") << endl;
00276 #if 0
00277     EV << "bitTime: " << bitTime << endl;
00278     EV << "carrierExtension: " << carrierExtension << endl;
00279     EV << "frameBursting: " << frameBursting << endl;
00280     EV << "slotTime: " << slotTime << endl;
00281     EV << "interFrameGap: " << interFrameGap << endl;
00282     EV << endl;
00283 #endif
00284 }

void EtherMACBase::finish (  )  [protected, virtual]

Reimplemented in EtherMAC.

Referenced by EtherMAC::finish().

00567 {
00568     if (!disabled)
00569     {
00570         simtime_t t = simTime();
00571         recordScalar("simulated time", t);
00572         recordScalar("txrate (Mb)", txrate/1000000);
00573         recordScalar("full duplex", duplexMode);
00574         recordScalar("frames sent",    numFramesSent);
00575         recordScalar("frames rcvd",    numFramesReceivedOK);
00576         recordScalar("bytes sent",     numBytesSent);
00577         recordScalar("bytes rcvd",     numBytesReceivedOK);
00578         recordScalar("frames from higher layer", numFramesFromHL);
00579         recordScalar("frames from higher layer dropped (iface down)", numDroppedIfaceDown);
00580         recordScalar("frames dropped (bit error)",  numDroppedBitError);
00581         recordScalar("frames dropped (not for us)", numDroppedNotForUs);
00582         recordScalar("frames passed up to HL", numFramesPassedToHL);
00583         recordScalar("PAUSE frames sent",  numPauseFramesSent);
00584         recordScalar("PAUSE frames rcvd",  numPauseFramesRcvd);
00585 
00586         if (t>0)
00587         {
00588             recordScalar("frames/sec sent", numFramesSent/t);
00589             recordScalar("frames/sec rcvd", numFramesReceivedOK/t);
00590             recordScalar("bits/sec sent",   8*numBytesSent/t);
00591             recordScalar("bits/sec rcvd",   8*numBytesReceivedOK/t);
00592         }
00593     }
00594 }

void EtherMACBase::processFrameFromUpperLayer ( EtherFrame *  msg  )  [protected, virtual]

Reimplemented in EtherMAC, and EtherMAC2.

Referenced by EtherMAC2::processFrameFromUpperLayer(), and EtherMAC::processFrameFromUpperLayer().

00287 {
00288     EV << "Received frame from upper layer: " << frame << endl;
00289 
00290     if (frame->getDest().equals(address))
00291     {
00292         error("logic error: frame %s from higher layer has local MAC address as dest (%s)",
00293               frame->getFullName(), frame->getDest().str().c_str());
00294     }
00295 
00296     if (frame->getByteLength() > MAX_ETHERNET_FRAME)
00297         error("packet from higher layer (%d bytes) exceeds maximum Ethernet frame size (%d)", frame->getByteLength(), MAX_ETHERNET_FRAME);
00298 
00299     // must be EtherFrame (or EtherPauseFrame) from upper layer
00300     bool isPauseFrame = (dynamic_cast<EtherPauseFrame*>(frame)!=NULL);
00301     if (!isPauseFrame)
00302     {
00303         numFramesFromHL++;
00304 
00305         if (txQueueLimit && txQueue.length()>txQueueLimit)
00306             error("txQueue length exceeds %d -- this is probably due to "
00307                   "a bogus app model generating excessive traffic "
00308                   "(or if this is normal, increase txQueueLimit!)",
00309                   txQueueLimit);
00310 
00311         // fill in src address if not set
00312         if (frame->getSrc().isUnspecified())
00313             frame->setSrc(address);
00314 
00315         // store frame and possibly begin transmitting
00316         EV << "Packet " << frame << " arrived from higher layers, enqueueing\n";
00317         txQueue.insert(frame);
00318     }
00319     else
00320     {
00321         EV << "PAUSE received from higher layer\n";
00322 
00323         // PAUSE frames enjoy priority -- they're transmitted before all other frames queued up
00324         if (!txQueue.empty())
00325             txQueue.insertBefore(txQueue.front(), frame);  // front() frame is probably being transmitted
00326         else
00327             txQueue.insert(frame);
00328     }
00329 
00330 }

void EtherMACBase::processMsgFromNetwork ( cPacket *  msg  )  [protected, virtual]

Reimplemented in EtherMAC, and EtherMAC2.

Referenced by EtherMAC2::processMsgFromNetwork(), and EtherMAC::processMsgFromNetwork().

00333 {
00334     EV << "Received frame from network: " << frame << endl;
00335 
00336     // frame must be EtherFrame or EtherJam
00337     if (dynamic_cast<EtherFrame*>(frame)==NULL && dynamic_cast<EtherJam*>(frame)==NULL)
00338         error("message with unexpected message class '%s' arrived from network (name='%s')",
00339                 frame->getClassName(), frame->getFullName());
00340 
00341     // detect cable length violation in half-duplex mode
00342     if (!duplexMode && simTime()-frame->getSendingTime()>=shortestFrameDuration)
00343         error("very long frame propagation time detected, maybe cable exceeds maximum allowed length? "
00344               "(%lgs corresponds to an approx. %lgm cable)",
00345               SIMTIME_STR(simTime() - frame->getSendingTime()),
00346               SIMTIME_STR((simTime() - frame->getSendingTime())*SPEED_OF_LIGHT));
00347 }

void EtherMACBase::processMessageWhenNotConnected ( cMessage *  msg  )  [protected, virtual]

Referenced by EtherMAC2::handleMessage().

00486 {
00487     EV << "Interface is not connected -- dropping packet " << msg << endl;
00488     delete msg;
00489     numDroppedIfaceDown++;
00490 }

void EtherMACBase::processMessageWhenDisabled ( cMessage *  msg  )  [protected, virtual]

Referenced by EtherMAC2::handleMessage().

00493 {
00494     EV << "MAC is disabled -- dropping message " << msg << endl;
00495     delete msg;
00496 }

void EtherMACBase::handleEndIFGPeriod (  )  [protected, virtual]

Reimplemented in EtherMAC, and EtherMAC2.

Referenced by EtherMAC2::handleEndIFGPeriod(), and EtherMAC::handleEndIFGPeriod().

00423 {
00424     if (transmitState!=WAIT_IFG_STATE)
00425         error("Not in WAIT_IFG_STATE at the end of IFG period");
00426 
00427     if (txQueue.empty())
00428         error("End of IFG and no frame to transmit");
00429 
00430     // End of IFG period, okay to transmit, if Rx idle OR duplexMode
00431     cPacket *frame = (cPacket *)txQueue.front();
00432     EV << "IFG elapsed, now begin transmission of frame " << frame << endl;
00433 
00434     // Perform carrier extension if in Gigabit Ethernet
00435     if (carrierExtension && frame->getByteLength() < GIGABIT_MIN_FRAME_WITH_EXT)
00436     {
00437         EV << "Performing carrier extension of small frame\n";
00438         frame->setByteLength(GIGABIT_MIN_FRAME_WITH_EXT);
00439     }
00440 
00441     // start frame burst, if enabled
00442     if (frameBursting)
00443     {
00444         EV << "Starting frame burst\n";
00445         framesSentInBurst = 0;
00446         bytesSentInBurst = 0;
00447     }
00448 }

void EtherMACBase::handleEndTxPeriod (  )  [protected, virtual]

Reimplemented in EtherMAC, and EtherMAC2.

Referenced by EtherMAC2::handleEndTxPeriod(), and EtherMAC::handleEndTxPeriod().

00451 {
00452     // we only get here if transmission has finished successfully, without collision
00453     if (transmitState!=TRANSMITTING_STATE || (!duplexMode && receiveState!=RX_IDLE_STATE))
00454         error("End of transmission, and incorrect state detected");
00455 
00456     if (txQueue.empty())
00457         error("Frame under transmission cannot be found");
00458 
00459     // get frame from buffer
00460     cPacket *frame = (cPacket *)txQueue.pop();
00461 
00462     numFramesSent++;
00463     numBytesSent += frame->getByteLength();
00464     numFramesSentVector.record(numFramesSent);
00465     numBytesSentVector.record(numBytesSent);
00466 
00467     if (dynamic_cast<EtherPauseFrame*>(frame)!=NULL)
00468     {
00469         numPauseFramesSent++;
00470         numPauseFramesSentVector.record(numPauseFramesSent);
00471     }
00472 
00473     EV << "Transmission of " << frame << " successfully completed\n";
00474     delete frame;
00475 }

void EtherMACBase::handleEndPausePeriod (  )  [protected, virtual]

Referenced by EtherMAC2::handleMessage(), and EtherMAC::handleMessage().

00478 {
00479     if (transmitState != PAUSE_STATE)
00480         error("At end of PAUSE not in PAUSE_STATE!");
00481     EV << "Pause finished, resuming transmissions\n";
00482     beginSendFrames();
00483 }

void EtherMACBase::scheduleEndIFGPeriod (  )  [protected, virtual]

void EtherMACBase::scheduleEndTxPeriod ( cPacket *  frame  )  [protected, virtual]

Referenced by EtherMAC2::startFrameTransmission(), and EtherMAC::startFrameTransmission().

00505 {
00506     scheduleAt(simTime()+frame->getBitLength()*bitTime, endTxMsg);
00507     transmitState = TRANSMITTING_STATE;
00508 }

void EtherMACBase::scheduleEndPausePeriod ( int  pauseUnits  )  [protected, virtual]

Referenced by checkAndScheduleEndPausePeriod(), and processPauseCommand().

00511 {
00512     // length is interpreted as 512-bit-time units
00513     simtime_t pausePeriod = pauseUnits*PAUSE_BITTIME*bitTime;
00514     scheduleAt(simTime()+pausePeriod, endPauseMsg);
00515     transmitState = PAUSE_STATE;
00516 }

bool EtherMACBase::checkAndScheduleEndPausePeriod (  )  [protected, virtual]

Referenced by EtherMAC2::handleEndTxPeriod(), and EtherMAC::handleEndTxPeriod().

00519 {
00520     if (pauseUnitsRequested>0)
00521     {
00522         // if we received a PAUSE frame recently, go into PAUSE state
00523         EV << "Going to PAUSE mode for " << pauseUnitsRequested << " time units\n";
00524 
00525         scheduleEndPausePeriod(pauseUnitsRequested);
00526         pauseUnitsRequested = 0;
00527         return true;
00528     }
00529 
00530     return false;
00531 }

void EtherMACBase::fireChangeNotification ( int  type,
cPacket *  msg 
) [protected, virtual]

00559 {
00560     if (nb) {
00561         notifDetails.setPacket(msg);
00562         nb->fireChangeNotification(type, &notifDetails);
00563     }
00564 }

void EtherMACBase::beginSendFrames (  )  [protected, virtual]

Referenced by handleEndPausePeriod(), EtherMAC2::handleEndTxPeriod(), EtherMAC::handleEndTxPeriod(), and EtherMAC2::initialize().

00534 {
00535     if (!txQueue.empty())
00536     {
00537         // Other frames are queued, therefore wait IFG period and transmit next frame
00538         EV << "Transmit next frame in output queue, after IFG period\n";
00539         scheduleEndIFGPeriod();
00540     }
00541     else
00542     {
00543         transmitState = TX_IDLE_STATE;
00544         if (queueModule)
00545         {
00546             // tell queue module that we've become idle
00547             EV << "Requesting another frame from queue module\n";
00548             queueModule->requestPacket();
00549         }
00550         else
00551         {
00552             // No more frames set transmitter to idle
00553             EV << "No more frames to send, transmitter set to idle\n";
00554         }
00555     }
00556 }

void EtherMACBase::frameReceptionComplete ( EtherFrame *  frame  )  [protected, virtual]

Referenced by EtherMAC::handleEndRxPeriod(), EtherMAC2::processMsgFromNetwork(), and EtherMAC::processMsgFromNetwork().

00350 {
00351     int pauseUnits;
00352     EtherPauseFrame *pauseFrame;
00353 
00354     if ((pauseFrame=dynamic_cast<EtherPauseFrame*>(frame))!=NULL)
00355     {
00356         pauseUnits = pauseFrame->getPauseTime();
00357         delete frame;
00358         numPauseFramesRcvd++;
00359         numPauseFramesRcvdVector.record(numPauseFramesRcvd);
00360         processPauseCommand(pauseUnits);
00361     }
00362     else
00363     {
00364         processReceivedDataFrame((EtherFrame *)frame);
00365     }
00366 }

void EtherMACBase::processReceivedDataFrame ( EtherFrame *  frame  )  [protected, virtual]

Referenced by frameReceptionComplete().

00369 {
00370     // bit errors
00371     if (frame->hasBitError())
00372     {
00373         numDroppedBitError++;
00374         numDroppedBitErrorVector.record(numDroppedBitError);
00375         delete frame;
00376         return;
00377     }
00378 
00379     // strip preamble and SFD
00380     frame->addByteLength(-PREAMBLE_BYTES-SFD_BYTES);
00381 
00382     // statistics
00383     numFramesReceivedOK++;
00384     numBytesReceivedOK += frame->getByteLength();
00385     numFramesReceivedOKVector.record(numFramesReceivedOK);
00386     numBytesReceivedOKVector.record(numBytesReceivedOK);
00387 
00388     if (!checkDestinationAddress(frame))
00389         return;
00390 
00391     numFramesPassedToHL++;
00392     numFramesPassedToHLVector.record(numFramesPassedToHL);
00393 
00394     // pass up to upper layer
00395     send(frame, "upperLayerOut");
00396 }

void EtherMACBase::processPauseCommand ( int  pauseUnits  )  [protected, virtual]

Referenced by frameReceptionComplete().

00399 {
00400     if (transmitState==TX_IDLE_STATE)
00401     {
00402         EV << "PAUSE frame received, pausing for " << pauseUnitsRequested << " time units\n";
00403         if (pauseUnits>0)
00404             scheduleEndPausePeriod(pauseUnits);
00405     }
00406     else if (transmitState==PAUSE_STATE)
00407     {
00408         EV << "PAUSE frame received, pausing for " << pauseUnitsRequested << " more time units from now\n";
00409         cancelEvent(endPauseMsg);
00410         if (pauseUnits>0)
00411             scheduleEndPausePeriod(pauseUnits);
00412     }
00413     else
00414     {
00415         // transmitter busy -- wait until it finishes with current frame (endTx)
00416         // and then it'll go to PAUSE state
00417         EV << "PAUSE frame received, storing pause request\n";
00418         pauseUnitsRequested = pauseUnits;
00419     }
00420 }

void EtherMACBase::updateDisplayString (  )  [protected, virtual]

Referenced by EtherMAC2::handleMessage(), and EtherMAC::handleMessage().

00597 {
00598     // icon coloring
00599     const char *color;
00600     if (receiveState==RX_COLLISION_STATE)
00601         color = "red";
00602     else if (transmitState==TRANSMITTING_STATE)
00603         color = "yellow";
00604     else if (transmitState==JAMMING_STATE)
00605         color = "red";
00606     else if (receiveState==RECEIVING_STATE)
00607         color = "#4040ff";
00608     else if (transmitState==BACKOFF_STATE)
00609         color = "white";
00610     else if (transmitState==PAUSE_STATE)
00611         color = "gray";
00612     else
00613         color = "";
00614     getDisplayString().setTagArg("i",1,color);
00615     if (!strcmp(getParentModule()->getClassName(),"EthernetInterface"))
00616         getParentModule()->getDisplayString().setTagArg("i",1,color);
00617 
00618     // connection coloring
00619     updateConnectionColor(transmitState);
00620 
00621 #if 0
00622     // this code works but didn't turn out to be very useful
00623     const char *txStateName;
00624     switch (transmitState) {
00625         case TX_IDLE_STATE:      txStateName="IDLE"; break;
00626         case WAIT_IFG_STATE:     txStateName="WAIT_IFG"; break;
00627         case TRANSMITTING_STATE: txStateName="TX"; break;
00628         case JAMMING_STATE:      txStateName="JAM"; break;
00629         case BACKOFF_STATE:      txStateName="BACKOFF"; break;
00630         case PAUSE_STATE:        txStateName="PAUSE"; break;
00631         default: error("wrong tx state");
00632     }
00633     const char *rxStateName;
00634     switch (receiveState) {
00635         case RX_IDLE_STATE:      rxStateName="IDLE"; break;
00636         case RECEIVING_STATE:    rxStateName="RX"; break;
00637         case RX_COLLISION_STATE: rxStateName="COLL"; break;
00638         default: error("wrong rx state");
00639     }
00640 
00641     char buf[80];
00642     sprintf(buf, "tx:%s rx: %s\n#boff:%d #cTx:%d",
00643                  txStateName, rxStateName, backoffs, numConcurrentTransmissions);
00644     getDisplayString().setTagArg("t",0,buf);
00645 #endif
00646 }

void EtherMACBase::updateConnectionColor ( int  txState  )  [protected, virtual]

Referenced by EtherMAC::sendJamSignal(), EtherMAC::startFrameTransmission(), and updateDisplayString().

00649 {
00650     const char *color;
00651     if (txState==TRANSMITTING_STATE)
00652         color = "yellow";
00653     else if (txState==JAMMING_STATE || txState==BACKOFF_STATE)
00654         color = "red";
00655     else
00656         color = "";
00657 
00658     cGate *g = physOutGate;
00659     while (g && g->getType()==cGate::OUTPUT)
00660     {
00661         g->getDisplayString().setTagArg("o",0,color);
00662         g->getDisplayString().setTagArg("o",1, color[0] ? "3" : "1");
00663         g = g->getNextGate();
00664     }
00665 }

virtual void EtherMACBase::updateHasSubcribers (  )  [protected, pure virtual]

void EtherMACBase::receiveChangeNotification ( int  category,
const cPolymorphic *  details 
) [protected, virtual]

Called by the NotificationBoard whenever a change of a category occurs to which this client has subscribed.

Implements INotifiable.

00668 {
00669     if (category==NF_SUBSCRIBERLIST_CHANGED)
00670         updateHasSubcribers();
00671 }


Member Data Documentation

bool EtherMACBase::connected [protected]

bool EtherMACBase::disabled [protected]

bool EtherMACBase::promiscuous [protected]

int EtherMACBase::txQueueLimit [protected]

bool EtherMACBase::duplexMode [protected]

bool EtherMACBase::frameBursting [protected]

double EtherMACBase::txrate [protected]

simtime_t EtherMACBase::bitTime [protected]

simtime_t EtherMACBase::slotTime [protected]

simtime_t EtherMACBase::interFrameGap [protected]

simtime_t EtherMACBase::jamDuration [protected]

simtime_t EtherMACBase::shortestFrameDuration [protected]

int EtherMACBase::transmitState [protected]

int EtherMACBase::receiveState [protected]

cQueue EtherMACBase::txQueue [protected]

cGate* EtherMACBase::physOutGate [protected]

bool EtherMACBase::hasSubscribers [protected]

cMessage* EtherMACBase::endTxMsg [protected]

cMessage * EtherMACBase::endIFGMsg [protected]

cMessage * EtherMACBase::endPauseMsg [protected]

unsigned long EtherMACBase::numFramesSent [protected]

unsigned long EtherMACBase::numFramesReceivedOK [protected]

unsigned long EtherMACBase::numBytesSent [protected]

unsigned long EtherMACBase::numBytesReceivedOK [protected]

unsigned long EtherMACBase::numFramesFromHL [protected]

unsigned long EtherMACBase::numDroppedIfaceDown [protected]

unsigned long EtherMACBase::numDroppedBitError [protected]

unsigned long EtherMACBase::numDroppedNotForUs [protected]

unsigned long EtherMACBase::numFramesPassedToHL [protected]

unsigned long EtherMACBase::numPauseFramesRcvd [protected]

unsigned long EtherMACBase::numPauseFramesSent [protected]

cOutVector EtherMACBase::numFramesSentVector [protected]

cOutVector EtherMACBase::numBytesSentVector [protected]

Referenced by initializeStatistics().


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:19 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5