EtherMAC Class Reference

#include <EtherMAC.h>

Inheritance diagram for EtherMAC:

EtherMACBase INotifiable

List of all members.


Detailed Description

Ethernet MAC module.

Public Member Functions

 EtherMAC ()
virtual ~EtherMAC ()

Protected Member Functions

virtual void initialize ()
virtual void initializeTxrate ()
virtual void handleMessage (cMessage *msg)
virtual void finish ()
virtual void processFrameFromUpperLayer (EtherFrame *msg)
virtual void processMsgFromNetwork (cPacket *msg)
virtual void handleEndIFGPeriod ()
virtual void handleEndTxPeriod ()
virtual void handleEndRxPeriod ()
virtual void handleEndBackoffPeriod ()
virtual void handleEndJammingPeriod ()
virtual void startAutoconfig ()
virtual void handleAutoconfigMessage (cMessage *msg)
virtual void printState ()
virtual void scheduleEndRxPeriod (cPacket *)
virtual void sendJamSignal ()
virtual void handleRetransmission ()
virtual void startFrameTransmission ()
virtual void updateHasSubcribers ()

Protected Attributes

bool autoconfigInProgress
double lowestTxrateSuggested
bool duplexVetoed
int backoffs
int numConcurrentTransmissions
EtherFrame * frameBeingReceived
cMessage * endRxMsg
cMessage * endBackoffMsg
cMessage * endJammingMsg
simtime_t totalCollisionTime
simtime_t totalSuccessfulRxTxTime
simtime_t channelBusySince
unsigned long numCollisions
unsigned long numBackoffs
cOutVector numCollisionsVector
cOutVector numBackoffsVector

Constructor & Destructor Documentation

EtherMAC::EtherMAC (  ) 

00037 {
00038     frameBeingReceived = NULL;
00039     endJammingMsg = endRxMsg = endBackoffMsg = NULL;
00040 }

EtherMAC::~EtherMAC (  )  [virtual]

00043 {
00044     delete frameBeingReceived;
00045     cancelAndDelete(endRxMsg);
00046     cancelAndDelete(endBackoffMsg);
00047     cancelAndDelete(endJammingMsg);
00048 }


Member Function Documentation

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

Reimplemented from EtherMACBase.

00051 {
00052     EtherMACBase::initialize();
00053 
00054     endRxMsg = new cMessage("EndReception", ENDRECEPTION);
00055     endBackoffMsg = new cMessage("EndBackoff", ENDBACKOFF);
00056     endJammingMsg = new cMessage("EndJamming", ENDJAMMING);
00057 
00058     // check: datarate is forbidden with EtherMAC -- module's txrate must be used
00059     cGate *g = physOutGate;
00060     while (g)
00061     {
00062         cDatarateChannel *chan = dynamic_cast<cDatarateChannel*>(g->getChannel());
00063         if (chan && chan->par("datarate").doubleValue()>0)
00064             error("connection on gate %s has data rate set: using data rate with EtherMAC "
00065                   "is forbidden, module's txrate parameter must be used instead",
00066                   g->getFullPath().c_str());
00067         g = g->getNextGate();
00068     }
00069 
00070     // launch autoconfig process
00071     bool performAutoconfig = true;
00072     if (!disabled && connected && performAutoconfig)
00073     {
00074         startAutoconfig();
00075     }
00076     else
00077     {
00078         autoconfigInProgress = false;
00079         duplexMode = par("duplexEnabled");
00080         calculateParameters();
00081     }
00082     WATCH(autoconfigInProgress);
00083 
00084     // initialize state info
00085     backoffs = 0;
00086     numConcurrentTransmissions = 0;
00087 
00088     WATCH(backoffs);
00089     WATCH(numConcurrentTransmissions);
00090 
00091     // initialize statistics
00092     totalCollisionTime = 0.0;
00093     totalSuccessfulRxTxTime = 0.0;
00094     numCollisions = numBackoffs = 0;
00095 
00096     WATCH(numCollisions);
00097     WATCH(numBackoffs);
00098 
00099     numCollisionsVector.setName("collisions");
00100     numBackoffsVector.setName("backoffs");
00101 }

void EtherMAC::initializeTxrate (  )  [protected, virtual]

Implements EtherMACBase.

00104 {
00105     txrate = par("txrate");
00106 }

void EtherMAC::handleMessage ( cMessage *  msg  )  [protected, virtual]

00203 {
00204     if (disabled)
00205     {
00206         EV << "MAC is disabled -- dropping message " << msg << "\n";
00207         delete msg;
00208         return;
00209     }
00210     if (autoconfigInProgress)
00211     {
00212         handleAutoconfigMessage(msg);
00213         return;
00214     }
00215 
00216     printState();
00217     // some consistency check
00218     if (!duplexMode && transmitState==TRANSMITTING_STATE && receiveState!=RX_IDLE_STATE)
00219         error("Inconsistent state -- transmitting and receiving at the same time");
00220 
00221     if (!msg->isSelfMessage())
00222     {
00223         // either frame from upper layer, or frame/jam signal from the network
00224         if (msg->getArrivalGate() == gate("upperLayerIn"))
00225             processFrameFromUpperLayer(check_and_cast<EtherFrame *>(msg));
00226         else
00227             processMsgFromNetwork(PK(msg));
00228     }
00229     else
00230     {
00231         // Process different self-messages (timer signals)
00232         EV << "Self-message " << msg << " received\n";
00233         switch (msg->getKind())
00234         {
00235             case ENDIFG:
00236                 handleEndIFGPeriod();
00237                 break;
00238 
00239             case ENDTRANSMISSION:
00240                 handleEndTxPeriod();
00241                 break;
00242 
00243             case ENDRECEPTION:
00244                 handleEndRxPeriod();
00245                 break;
00246 
00247             case ENDBACKOFF:
00248                 handleEndBackoffPeriod();
00249                 break;
00250 
00251             case ENDJAMMING:
00252                 handleEndJammingPeriod();
00253                 break;
00254 
00255             case ENDPAUSE:
00256                 handleEndPausePeriod();
00257                 break;
00258 
00259             default:
00260                 error("self-message with unexpected message kind %d", msg->getKind());
00261         }
00262     }
00263     printState();
00264 
00265     if (ev.isGUI())
00266         updateDisplayString();
00267 }

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

Reimplemented from EtherMACBase.

00625 {
00626     EtherMACBase::finish();
00627 
00628     simtime_t t = simTime();
00629     simtime_t totalChannelIdleTime = t - totalSuccessfulRxTxTime - totalCollisionTime;
00630     recordScalar("rx channel idle (%)", 100*(totalChannelIdleTime/t));
00631     recordScalar("rx channel utilization (%)", 100*(totalSuccessfulRxTxTime/t));
00632     recordScalar("rx channel collision (%)", 100*(totalCollisionTime/t));
00633     recordScalar("collisions",     numCollisions);
00634     recordScalar("backoffs",       numBackoffs);
00635 }

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

Reimplemented from EtherMACBase.

Referenced by handleAutoconfigMessage(), and handleMessage().

00271 {
00272     EtherMACBase::processFrameFromUpperLayer(frame);
00273 
00274     if (!autoconfigInProgress && (duplexMode || receiveState==RX_IDLE_STATE) && transmitState==TX_IDLE_STATE)
00275     {
00276         EV << "No incoming carrier signals detected, frame clear to send, wait IFG first\n";
00277         scheduleEndIFGPeriod();
00278     }
00279 }

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

Reimplemented from EtherMACBase.

Referenced by handleMessage().

00283 {
00284     EtherMACBase::processMsgFromNetwork(msg);
00285 
00286     simtime_t endRxTime = simTime() + msg->getBitLength()*bitTime;
00287 
00288     if (!duplexMode && transmitState==TRANSMITTING_STATE)
00289     {
00290         // since we're halfduplex, receiveState must be RX_IDLE_STATE (asserted at top of handleMessage)
00291         if (dynamic_cast<EtherJam*>(msg) != NULL)
00292             error("Stray jam signal arrived while transmitting (usual cause is cable length exceeding allowed maximum)");
00293 
00294         EV << "Transmission interrupted by incoming frame, handling collision\n";
00295         cancelEvent(endTxMsg);
00296 
00297         EV << "Transmitting jam signal\n";
00298         sendJamSignal(); // backoff will be executed when jamming finished
00299 
00300         // set receive state and schedule end of reception
00301         receiveState = RX_COLLISION_STATE;
00302         numConcurrentTransmissions++;
00303         simtime_t endJamTime = simTime()+jamDuration;
00304         scheduleAt(endRxTime<endJamTime ? endJamTime : endRxTime, endRxMsg);
00305         delete msg;
00306 
00307         numCollisions++;
00308         numCollisionsVector.record(numCollisions);
00309     }
00310     else if (receiveState==RX_IDLE_STATE)
00311     {
00312         if (dynamic_cast<EtherJam*>(msg) != NULL)
00313             error("Stray jam signal arrived (usual cause is cable length exceeding allowed maximum)");
00314 
00315         EV << "Start reception of frame\n";
00316         numConcurrentTransmissions++;
00317         if (frameBeingReceived)
00318             error("frameBeingReceived!=0 in RX_IDLE_STATE");
00319         frameBeingReceived = (EtherFrame *)msg;
00320         scheduleEndRxPeriod(msg);
00321         channelBusySince = simTime();
00322     }
00323     else if (receiveState==RECEIVING_STATE && dynamic_cast<EtherJam*>(msg)==NULL && endRxMsg->getArrivalTime()-simTime()<bitTime)
00324     {
00325         // With the above condition we filter out "false" collisions that may occur with
00326         // back-to-back frames. That is: when "beginning of frame" message (this one) occurs
00327         // BEFORE "end of previous frame" event (endRxMsg) -- same simulation time,
00328         // only wrong order.
00329 
00330         EV << "Back-to-back frames: completing reception of current frame, starting reception of next one\n";
00331 
00332         // complete reception of previous frame
00333         cancelEvent(endRxMsg);
00334         EtherFrame *frame = frameBeingReceived;
00335         frameBeingReceived = NULL;
00336         frameReceptionComplete(frame);
00337 
00338         // start receiving next frame
00339         frameBeingReceived = (EtherFrame *)msg;
00340         scheduleEndRxPeriod(msg);
00341     }
00342     else // (receiveState==RECEIVING_STATE || receiveState==RX_COLLISION_STATE)
00343     {
00344         // handle overlapping receptions
00345         if (dynamic_cast<EtherJam*>(msg) != NULL)
00346         {
00347             if (numConcurrentTransmissions<=0)
00348                 error("numConcurrentTransmissions=%d on jam arrival (stray jam?)",numConcurrentTransmissions);
00349 
00350             numConcurrentTransmissions--;
00351             EV << "Jam signal received, this marks end of one transmission\n";
00352 
00353             // by the time jamming ends, all transmissions will have been aborted
00354             if (numConcurrentTransmissions==0)
00355             {
00356                 EV << "Last jam signal received, collision will ends when jam ends\n";
00357                 cancelEvent(endRxMsg);
00358                 scheduleAt(endRxTime, endRxMsg);
00359             }
00360         }
00361         else // EtherFrame or EtherPauseFrame
00362         {
00363             numConcurrentTransmissions++;
00364             if (endRxMsg->getArrivalTime() < endRxTime)
00365             {
00366                 // otherwise just wait until the end of the longest transmission
00367                 EV << "Overlapping receptions -- setting collision state and extending collision period\n";
00368                 cancelEvent(endRxMsg);
00369                 scheduleAt(endRxTime, endRxMsg);
00370             }
00371             else
00372             {
00373                 EV << "Overlapping receptions -- setting collision state\n";
00374             }
00375         }
00376 
00377         // delete collided frames: arrived frame as well as the one we're currently receiving
00378         delete msg;
00379         if (receiveState==RECEIVING_STATE)
00380         {
00381             delete frameBeingReceived;
00382             frameBeingReceived = NULL;
00383 
00384             numCollisions++;
00385             numCollisionsVector.record(numCollisions);
00386         }
00387 
00388         // go to collision state
00389         receiveState = RX_COLLISION_STATE;
00390     }
00391 }

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

Reimplemented from EtherMACBase.

Referenced by handleMessage().

00395 {
00396     EtherMACBase::handleEndIFGPeriod();
00397 
00398     // End of IFG period, okay to transmit, if Rx idle OR duplexMode
00399     cPacket *frame = (cPacket *)txQueue.front();
00400 
00401     // Perform carrier extension if in Gigabit Ethernet
00402     if (carrierExtension && frame->getByteLength() < GIGABIT_MIN_FRAME_WITH_EXT)
00403     {
00404         EV << "Performing carrier extension of small frame\n";
00405         frame->setByteLength(GIGABIT_MIN_FRAME_WITH_EXT);
00406     }
00407 
00408     // send frame to network
00409     startFrameTransmission();
00410 }

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

Reimplemented from EtherMACBase.

Referenced by handleMessage().

00466 {
00467     EtherMACBase::handleEndTxPeriod();
00468 
00469     // only count transmissions in totalSuccessfulRxTxTime if channel is half-duplex
00470     if (!duplexMode)
00471     {
00472         simtime_t dt = simTime()-channelBusySince;
00473         totalSuccessfulRxTxTime += dt;
00474     }
00475 
00476     backoffs = 0;
00477 
00478     // check for and obey received PAUSE frames after each transmission
00479     if (checkAndScheduleEndPausePeriod())
00480         return;
00481 
00482     // Gigabit Ethernet: now decide if we transmit next frame right away (burst) or wait IFG
00483     // FIXME! this is not entirely correct, there must be IFG between burst frames too
00484     bool burstFrame=false;
00485     if (frameBursting && !txQueue.empty())
00486     {
00487         // check if max bytes for burst not exceeded
00488         if (bytesSentInBurst<GIGABIT_MAX_BURST_BYTES)
00489         {
00490              burstFrame=true;
00491              EV << "Transmitting next frame in current burst\n";
00492         }
00493         else
00494         {
00495              EV << "Next frame does not fit in current burst\n";
00496         }
00497     }
00498 
00499     if (burstFrame)
00500         startFrameTransmission();
00501     else
00502         beginSendFrames();
00503 }

void EtherMAC::handleEndRxPeriod (  )  [protected, virtual]

Referenced by handleMessage().

00506 {
00507     EV << "Frame reception complete\n";
00508     simtime_t dt = simTime()-channelBusySince;
00509     if (receiveState==RECEIVING_STATE) // i.e. not RX_COLLISION_STATE
00510     {
00511         EtherFrame *frame = frameBeingReceived;
00512         frameBeingReceived = NULL;
00513         frameReceptionComplete(frame);
00514         totalSuccessfulRxTxTime += dt;
00515     }
00516     else
00517     {
00518         totalCollisionTime += dt;
00519     }
00520 
00521     receiveState = RX_IDLE_STATE;
00522     numConcurrentTransmissions = 0;
00523 
00524     if (transmitState==TX_IDLE_STATE && !txQueue.empty())
00525     {
00526         EV << "Receiver now idle, can transmit frames in output buffer after IFG period\n";
00527         scheduleEndIFGPeriod();
00528     }
00529 }

void EtherMAC::handleEndBackoffPeriod (  )  [protected, virtual]

Referenced by handleMessage().

00532 {
00533     if (transmitState != BACKOFF_STATE)
00534         error("At end of BACKOFF not in BACKOFF_STATE!");
00535     if (txQueue.empty())
00536         error("At end of BACKOFF and buffer empty!");
00537 
00538     if (receiveState==RX_IDLE_STATE)
00539     {
00540         EV << "Backoff period ended, wait IFG\n";
00541         scheduleEndIFGPeriod();
00542     }
00543     else
00544     {
00545         EV << "Backoff period ended but channel not free, idling\n";
00546         transmitState = TX_IDLE_STATE;
00547     }
00548 }

void EtherMAC::handleEndJammingPeriod (  )  [protected, virtual]

Referenced by handleMessage().

00551 {
00552     if (transmitState != JAMMING_STATE)
00553         error("At end of JAMMING not in JAMMING_STATE!");
00554     EV << "Jamming finished, executing backoff\n";
00555     handleRetransmission();
00556 }

void EtherMAC::startAutoconfig (  )  [protected, virtual]

Referenced by initialize().

00109 {
00110     autoconfigInProgress = true;
00111     lowestTxrateSuggested = 0;  // none suggested
00112     duplexVetoed = false;
00113 
00114     double initialTxrate = par("txrate");
00115     bool duplexEnabled = par("duplexEnabled");
00116     txrate = 0;
00117     duplexMode = duplexEnabled;
00118     if (!duplexEnabled || initialTxrate>0)
00119     {
00120         EV << "Autoconfig: advertising our settings: " << initialTxrate/1000000 << "Mb, "
00121            << (duplexMode ? "duplex" : "half-duplex") << endl;
00122 
00123         EtherAutoconfig *autoconf = new EtherAutoconfig("autoconf");
00124         if (!duplexEnabled)
00125             autoconf->setHalfDuplex(true);
00126         if (initialTxrate>0)
00127             autoconf->setTxrate(initialTxrate);
00128         send(autoconf, physOutGate);
00129     }
00130     scheduleAt(simTime()+AUTOCONFIG_PERIOD, new cMessage("EndAutoconfig",ENDAUTOCONFIG));
00131 }

void EtherMAC::handleAutoconfigMessage ( cMessage *  msg  )  [protected, virtual]

Referenced by handleMessage().

00134 {
00135     if (!msg->isSelfMessage())
00136     {
00137         if (msg->getArrivalGate() == gate("upperLayerIn"))
00138         {
00139             // from upper layer
00140             EV << "Received frame from upper layer during autoconfig period: " << msg << endl;
00141             processFrameFromUpperLayer(check_and_cast<EtherFrame *>(msg));
00142         }
00143         else
00144         {
00145             // from network: must be autoconfig message
00146             EV << "Message from network during autoconfig period: " << msg << endl;
00147             EtherAutoconfig *autoconf = check_and_cast<EtherAutoconfig *>(msg);
00148             double acTxrate = autoconf->getTxrate();
00149 
00150             EV << "Autoconfig message: ";
00151             if (acTxrate>0)
00152                 EV << acTxrate/1000000 << "Mb ";
00153             if (autoconf->getHalfDuplex())
00154                 EV << "non-duplex";
00155             EV << "\n";
00156 
00157             if (acTxrate>0 && (acTxrate<lowestTxrateSuggested || lowestTxrateSuggested==0))
00158                 lowestTxrateSuggested = acTxrate;
00159             if (!duplexVetoed && autoconf->getHalfDuplex())
00160                 duplexVetoed = true;
00161             delete msg;
00162         }
00163     }
00164     else
00165     {
00166         // self-message signals end of autoconfig period
00167         EV << "Self-message during autoconfig period: " << msg << endl;
00168 
00169         delete msg;
00170         autoconfigInProgress = false;
00171 
00172         double initialTxrate = par("txrate");
00173         bool duplexEnabled = par("duplexEnabled");
00174 
00175         txrate = (initialTxrate==0 && lowestTxrateSuggested==0) ? 100000000 /* 100 Mb */:
00176                  (initialTxrate==0) ? lowestTxrateSuggested :
00177                  (lowestTxrateSuggested==0) ? initialTxrate :
00178                  (lowestTxrateSuggested<initialTxrate) ? lowestTxrateSuggested : initialTxrate;
00179         duplexMode = (duplexEnabled && !duplexVetoed);
00180         calculateParameters();
00181 
00182         EV << "Parameters after autoconfig: txrate=" << txrate/1000000 << "Mb, " << (duplexMode ? "duplex" : "half-duplex") << endl;
00183 
00184         if (ev.isGUI())
00185         {
00186             char modestr[64];
00187             sprintf(modestr, "%dMb\n%s", int(txrate/1000000), (duplexMode ? "full duplex" : "half duplex"));
00188             getDisplayString().setTagArg("t",0,modestr);
00189             //getDisplayString().setTagArg("t",1,"r");
00190             sprintf(modestr, "%s: %dMb %s", getFullName(), int(txrate/1000000), (duplexMode ? "duplex" : "half duplex"));
00191             getParentModule()->bubble(modestr);
00192         }
00193 
00194         if (!txQueue.empty())
00195         {
00196             EV << "Autoconfig period over, starting to send frames\n";
00197             scheduleEndIFGPeriod();
00198         }
00199     }
00200 }

void EtherMAC::printState (  )  [protected, virtual]

Referenced by handleMessage().

00601 {
00602 #define CASE(x) case x: EV << #x; break
00603     EV << "transmitState: ";
00604     switch (transmitState) {
00605         CASE(TX_IDLE_STATE);
00606         CASE(WAIT_IFG_STATE);
00607         CASE(TRANSMITTING_STATE);
00608         CASE(JAMMING_STATE);
00609         CASE(BACKOFF_STATE);
00610         CASE(PAUSE_STATE);
00611     }
00612     EV << ",  receiveState: ";
00613     switch (receiveState) {
00614         CASE(RX_IDLE_STATE);
00615         CASE(RECEIVING_STATE);
00616         CASE(RX_COLLISION_STATE);
00617     }
00618     EV << ",  backoffs: " << backoffs;
00619     EV << ",  numConcurrentTransmissions: " << numConcurrentTransmissions;
00620     EV << ",  queueLength: " << txQueue.length() << endl;
00621 #undef CASE
00622 }

void EtherMAC::scheduleEndRxPeriod ( cPacket *  frame  )  [protected, virtual]

Referenced by processMsgFromNetwork().

00570 {
00571     scheduleAt(simTime()+frame->getBitLength()*bitTime, endRxMsg);
00572     receiveState = RECEIVING_STATE;
00573 }

void EtherMAC::sendJamSignal (  )  [protected, virtual]

Referenced by processMsgFromNetwork(), and startFrameTransmission().

00559 {
00560     cPacket *jam = new EtherJam("JAM_SIGNAL");
00561     jam->setByteLength(JAM_SIGNAL_BYTES);
00562     if (ev.isGUI())  updateConnectionColor(JAMMING_STATE);
00563     send(jam, physOutGate);
00564 
00565     scheduleAt(simTime()+jamDuration, endJammingMsg);
00566     transmitState = JAMMING_STATE;
00567 }

void EtherMAC::handleRetransmission (  )  [protected, virtual]

Referenced by handleEndJammingPeriod().

00576 {
00577     if (++backoffs > MAX_ATTEMPTS)
00578     {
00579         EV << "Number of retransmit attempts of frame exceeds maximum, cancelling transmission of frame\n";
00580         delete txQueue.pop();
00581 
00582         transmitState = TX_IDLE_STATE;
00583         backoffs = 0;
00584         // no beginSendFrames(), because end of jam signal sending will trigger it automatically
00585         return;
00586     }
00587 
00588     EV << "Executing backoff procedure\n";
00589     int backoffrange = (backoffs>=BACKOFF_RANGE_LIMIT) ? 1024 : (1 << backoffs);
00590     int slotNumber = intuniform(0,backoffrange-1);
00591     simtime_t backofftime = slotNumber*slotTime;
00592 
00593     scheduleAt(simTime()+backofftime, endBackoffMsg);
00594     transmitState = BACKOFF_STATE;
00595 
00596     numBackoffs++;
00597     numBackoffsVector.record(numBackoffs);
00598 }

void EtherMAC::startFrameTransmission (  )  [protected, virtual]

Referenced by handleEndIFGPeriod(), and handleEndTxPeriod().

00413 {
00414     cPacket *origFrame = (cPacket *)txQueue.front();
00415     EV << "Transmitting a copy of frame " << origFrame << endl;
00416     cPacket *frame = origFrame->dup();
00417 
00418     // add preamble and SFD (Starting Frame Delimiter), then send out
00419     frame->addByteLength(PREAMBLE_BYTES+SFD_BYTES);
00420     if (ev.isGUI())  updateConnectionColor(TRANSMITTING_STATE);
00421     send(frame, physOutGate);
00422 
00423     // update burst variables
00424     if (frameBursting)
00425     {
00426         bytesSentInBurst = frame->getByteLength();
00427         framesSentInBurst++;
00428     }
00429 
00430     // check for collisions (there might be an ongoing reception which we don't know about, see below)
00431     if (!duplexMode && receiveState!=RX_IDLE_STATE)
00432     {
00433         // During the IFG period the hardware cannot listen to the channel,
00434         // so it might happen that receptions have begun during the IFG,
00435         // and even collisions might be in progress.
00436         //
00437         // But we don't know of any ongoing transmission so we blindly
00438         // start transmitting, immediately collide and send a jam signal.
00439         //
00440         sendJamSignal();
00441         // numConcurrentTransmissions stays the same: +1 transmission, -1 jam
00442 
00443         if (receiveState==RECEIVING_STATE)
00444         {
00445             delete frameBeingReceived;
00446             frameBeingReceived = NULL;
00447 
00448             numCollisions++;
00449             numCollisionsVector.record(numCollisions);
00450         }
00451         // go to collision state
00452         receiveState = RX_COLLISION_STATE;
00453     }
00454     else
00455     {
00456         // no collision
00457         scheduleEndTxPeriod(frame);
00458 
00459         // only count transmissions in totalSuccessfulRxTxTime if channel is half-duplex
00460         if (!duplexMode)
00461             channelBusySince = simTime();
00462     }
00463 }

void EtherMAC::updateHasSubcribers (  )  [protected, virtual]

Implements EtherMACBase.

00638 {
00639     hasSubscribers = false;  // currently we don't fire any notifications
00640 }


Member Data Documentation

double EtherMAC::lowestTxrateSuggested [protected]

bool EtherMAC::duplexVetoed [protected]

int EtherMAC::backoffs [protected]

EtherFrame* EtherMAC::frameBeingReceived [protected]

cMessage* EtherMAC::endRxMsg [protected]

cMessage * EtherMAC::endBackoffMsg [protected]

cMessage * EtherMAC::endJammingMsg [protected]

simtime_t EtherMAC::totalCollisionTime [protected]

simtime_t EtherMAC::totalSuccessfulRxTxTime [protected]

simtime_t EtherMAC::channelBusySince [protected]

unsigned long EtherMAC::numCollisions [protected]

unsigned long EtherMAC::numBackoffs [protected]

cOutVector EtherMAC::numCollisionsVector [protected]

cOutVector EtherMAC::numBackoffsVector [protected]

Referenced by handleRetransmission(), and initialize().


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

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