#include <EtherMAC.h>
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 |
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 }
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] |
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 }
bool EtherMAC::autoconfigInProgress [protected] |
Referenced by handleAutoconfigMessage(), handleMessage(), initialize(), processFrameFromUpperLayer(), and startAutoconfig().
double EtherMAC::lowestTxrateSuggested [protected] |
Referenced by handleAutoconfigMessage(), and startAutoconfig().
bool EtherMAC::duplexVetoed [protected] |
Referenced by handleAutoconfigMessage(), and startAutoconfig().
int EtherMAC::backoffs [protected] |
Referenced by handleEndTxPeriod(), handleRetransmission(), initialize(), and printState().
int EtherMAC::numConcurrentTransmissions [protected] |
Referenced by handleEndRxPeriod(), initialize(), printState(), and processMsgFromNetwork().
EtherFrame* EtherMAC::frameBeingReceived [protected] |
Referenced by EtherMAC(), handleEndRxPeriod(), processMsgFromNetwork(), startFrameTransmission(), and ~EtherMAC().
cMessage* EtherMAC::endRxMsg [protected] |
Referenced by EtherMAC(), initialize(), processMsgFromNetwork(), scheduleEndRxPeriod(), and ~EtherMAC().
cMessage * EtherMAC::endBackoffMsg [protected] |
Referenced by EtherMAC(), handleRetransmission(), initialize(), and ~EtherMAC().
cMessage * EtherMAC::endJammingMsg [protected] |
Referenced by EtherMAC(), initialize(), sendJamSignal(), and ~EtherMAC().
simtime_t EtherMAC::totalCollisionTime [protected] |
Referenced by finish(), handleEndRxPeriod(), and initialize().
simtime_t EtherMAC::totalSuccessfulRxTxTime [protected] |
Referenced by finish(), handleEndRxPeriod(), handleEndTxPeriod(), and initialize().
simtime_t EtherMAC::channelBusySince [protected] |
Referenced by handleEndRxPeriod(), handleEndTxPeriod(), processMsgFromNetwork(), and startFrameTransmission().
unsigned long EtherMAC::numCollisions [protected] |
Referenced by finish(), initialize(), processMsgFromNetwork(), and startFrameTransmission().
unsigned long EtherMAC::numBackoffs [protected] |
Referenced by finish(), handleRetransmission(), and initialize().
cOutVector EtherMAC::numCollisionsVector [protected] |
Referenced by initialize(), processMsgFromNetwork(), and startFrameTransmission().
cOutVector EtherMAC::numBackoffsVector [protected] |
Referenced by handleRetransmission(), and initialize().