00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "csma.h"
00029 #include "FWMath.h"
00030 #include <cassert>
00031 #include <BaseDecider.h>
00032 #include <DeciderResult802154Narrow.h>
00033 #include <BaseArp.h>
00034 #include <MacToPhyControlInfo.h>
00035 #include <PhyToMacControlInfo.h>
00036 #include <NetwToMacControlInfo.h>
00037 #include <MacToNetwControlInfo.h>
00038 #include <SimpleAddress.h>
00039 #include <BasePhyLayer.h>
00040
00041 #include <BaseConnectionManager.h>
00042
00043
00044 Define_Module(csma);
00045
00051 void csma::initialize(int stage) {
00052 BaseMacLayer::initialize(stage);
00053
00054 if (stage == 0) {
00055
00056 useMACAcks = par("useMACAcks").boolValue();
00057 queueLength = par("queueLength");
00058 sifs = par("sifs");
00059 transmissionAttemptInterruptedByRx = false;
00060 nbTxFrames = 0;
00061 nbRxFrames = 0;
00062 nbMissedAcks = 0;
00063 nbTxAcks = 0;
00064 nbRecvdAcks = 0;
00065 nbDroppedFrames = 0;
00066 nbDuplicates = 0;
00067 nbBackoffs = 0;
00068 backoffValues = 0;
00069 stats = par("stats");
00070 trace = par("trace");
00071 macMaxCSMABackoffs = par("macMaxCSMABackoffs");
00072 macMaxFrameRetries = par("macMaxFrameRetries");
00073 macAckWaitDuration = par("macAckWaitDuration").doubleValue();
00074 aUnitBackoffPeriod = par("aUnitBackoffPeriod");
00075 ccaDetectionTime = par("ccaDetectionTime").doubleValue();
00076 rxSetupTime = par("rxSetupTime").doubleValue();
00077 aTurnaroundTime = par("aTurnaroundTime").doubleValue();
00078 bitrate = par("bitrate");
00079 ackLength = par("ackLength");
00080 ackMessage = NULL;
00081
00082
00083 std::string backoffMethodStr = par("backoffMethod").stdstringValue();
00084 if(backoffMethodStr == "exponential") {
00085 backoffMethod = EXPONENTIAL;
00086 macMinBE = par("macMinBE");
00087 macMaxBE = par("macMaxBE");
00088 }
00089 else {
00090 if(backoffMethodStr == "linear") {
00091 backoffMethod = LINEAR;
00092 }
00093 else if (backoffMethodStr == "constant") {
00094 backoffMethod = CONSTANT;
00095 }
00096 else {
00097 error("Unknown backoff method \"%s\".\
00098 Use \"constant\", \"linear\" or \"\
00099 \"exponential\".", backoffMethodStr.c_str());
00100 }
00101 initialCW = par("contentionWindow");
00102 }
00103 NB = 0;
00104
00105 txPower = par("txPower").doubleValue();
00106
00107 droppedPacket.setReason(DroppedPacket::NONE);
00108 nicId = getParentModule()->getId();
00109
00110 catDroppedPacket = utility->getCategory(&droppedPacket);
00111
00112
00113 backoffTimer = new cMessage("timer-backoff");
00114 ccaTimer = new cMessage("timer-cca");
00115 sifsTimer = new cMessage("timer-sifs");
00116 rxAckTimer = new cMessage("timer-rxAck");
00117 macState = IDLE_1;
00118 txAttempts = 0;
00119
00120
00121 cModule* phyModule = FindModule<BasePhyLayer*>
00122 ::findSubModule(getParentModule());
00123
00124
00125
00126 if(phyModule->hasPar("timeRXToTX")) {
00127 simtime_t rxToTx = phyModule->par("timeRXToTX").doubleValue();
00128 if( rxToTx > aTurnaroundTime)
00129 {
00130 opp_warning("Parameter \"aTurnaroundTime\" (%f) does not match"
00131 " the radios RX to TX switching time (%f)! It"
00132 " should be equal or bigger",
00133 aTurnaroundTime.dbl(), rxToTx.dbl());
00134 }
00135 }
00136
00137 } else if(stage == 1) {
00138 BaseConnectionManager* cc = getConnectionManager();
00139
00140 if(cc->hasPar("pMax") && txPower > cc->par("pMax").doubleValue())
00141 opp_error("TranmitterPower can't be bigger than pMax in ConnectionManager! "
00142 "Please adjust your omnetpp.ini file accordingly");
00143
00144 debugEV << "queueLength = " << queueLength
00145 << " bitrate = " << bitrate
00146 << " backoff method = " << par("backoffMethod").stringValue() << endl;
00147
00148 debugEV << "finished csma init stage 1." << endl;
00149 }
00150 }
00151
00152 void csma::finish() {
00153 if (stats) {
00154 recordScalar("nbTxFrames", nbTxFrames);
00155 recordScalar("nbRxFrames", nbRxFrames);
00156 recordScalar("nbDroppedFrames", nbDroppedFrames);
00157 recordScalar("nbMissedAcks", nbMissedAcks);
00158 recordScalar("nbRecvdAcks", nbRecvdAcks);
00159 recordScalar("nbTxAcks", nbTxAcks);
00160 recordScalar("nbDuplicates", nbDuplicates);
00161 if (nbBackoffs > 0) {
00162 recordScalar("meanBackoff", backoffValues / nbBackoffs);
00163 } else {
00164 recordScalar("meanBackoff", 0);
00165 }
00166 recordScalar("nbBackoffs", nbBackoffs);
00167 recordScalar("backoffDurations", backoffValues);
00168 }
00169 }
00170
00171 csma::~csma() {
00172 cancelAndDelete(backoffTimer);
00173 cancelAndDelete(ccaTimer);
00174 cancelAndDelete(sifsTimer);
00175 cancelAndDelete(rxAckTimer);
00176 if (ackMessage)
00177 delete ackMessage;
00178 MacQueue::iterator it;
00179 for (it = macQueue.begin(); it != macQueue.end(); ++it) {
00180 delete (*it);
00181 }
00182 }
00183
00188 void csma::handleUpperMsg(cMessage *msg) {
00189
00190 MacPkt *macPkt = new MacPkt(msg->getName());
00191 macPkt->setBitLength(headerLength);
00192 NetwToMacControlInfo* cInfo =
00193 static_cast<NetwToMacControlInfo*> (msg->removeControlInfo());
00194 debugEV<<"CSMA received a message from upper layer, name is " << msg->getName() <<", CInfo removed, mac addr="<< cInfo->getNextHopMac()<<endl;
00195 int dest = cInfo->getNextHopMac();
00196 macPkt->setDestAddr(dest);
00197 delete cInfo;
00198 macPkt->setSrcAddr(myMacAddr);
00199
00200 if(useMACAcks) {
00201 if(SeqNrParent.find(dest) == SeqNrParent.end()) {
00202
00203 SeqNrParent[dest] = 1;
00204 macPkt->setSequenceId(0);
00205 debugEV << "Adding a new parent to the map of Sequence numbers:" << dest << endl;
00206 }
00207 else {
00208 macPkt->setSequenceId(SeqNrParent[dest]);
00209 debugEV << "Packet send with sequence number = " << SeqNrParent[dest] << endl;
00210 SeqNrParent[dest]++;
00211 }
00212 }
00213
00214
00215
00216 assert(static_cast<cPacket*>(msg));
00217 macPkt->encapsulate(static_cast<cPacket*>(msg));
00218 debugEV <<"pkt encapsulated, length: " << macPkt->getBitLength() << "\n";
00219 executeMac(EV_SEND_REQUEST, macPkt);
00220 }
00221
00222 void csma::updateStatusIdle(t_mac_event event, cMessage *msg) {
00223 switch (event) {
00224 case EV_SEND_REQUEST:
00225 if (macQueue.size() <= queueLength) {
00226 macQueue.push_back(static_cast<MacPkt *> (msg));
00227 debugEV<<"(1) FSM State IDLE_1, EV_SEND_REQUEST and [TxBuff avail]: startTimerBackOff -> BACKOFF." << endl;
00228 updateMacState(BACKOFF_2);
00229 NB = 0;
00230
00231 startTimer(TIMER_BACKOFF);
00232 } else {
00233
00234 debugEV << "(12) FSM State IDLE_1, EV_SEND_REQUEST and [TxBuff not avail]: dropping packet -> IDLE." << endl;
00235 msg->setName("MAC ERROR");
00236 msg->setKind(PACKET_DROPPED);
00237 sendControlUp(msg);
00238 droppedPacket.setReason(DroppedPacket::QUEUE);
00239 utility->publishBBItem(catDroppedPacket, &droppedPacket, nicId);
00240 updateMacState(IDLE_1);
00241 }
00242 break;
00243 case EV_DUPLICATE_RECEIVED:
00244 debugEV << "(15) FSM State IDLE_1, EV_DUPLICATE_RECEIVED: setting up radio tx -> WAITSIFS." << endl;
00245
00246 delete msg;
00247
00248 if(useMACAcks) {
00249 phy->setRadioState(Radio::TX);
00250 updateMacState(WAITSIFS_6);
00251 startTimer(TIMER_SIFS);
00252 }
00253 break;
00254
00255 case EV_FRAME_RECEIVED:
00256 debugEV << "(15) FSM State IDLE_1, EV_FRAME_RECEIVED: setting up radio tx -> WAITSIFS." << endl;
00257 sendUp(decapsMsg(static_cast<MacPkt *>(msg)));
00258 nbRxFrames++;
00259 delete msg;
00260
00261 if(useMACAcks) {
00262 phy->setRadioState(Radio::TX);
00263 updateMacState(WAITSIFS_6);
00264 startTimer(TIMER_SIFS);
00265 }
00266 break;
00267
00268 case EV_BROADCAST_RECEIVED:
00269 debugEV << "(23) FSM State IDLE_1, EV_BROADCAST_RECEIVED: Nothing to do." << endl;
00270 nbRxFrames++;
00271 sendUp(decapsMsg(static_cast<MacPkt *>(msg)));
00272 delete msg;
00273 break;
00274 default:
00275 fsmError(event, msg);
00276 }
00277 }
00278
00279 void csma::updateStatusBackoff(t_mac_event event, cMessage *msg) {
00280 switch (event) {
00281 case EV_TIMER_BACKOFF:
00282 debugEV<< "(2) FSM State BACKOFF, EV_TIMER_BACKOFF:"
00283 << " starting CCA timer." << endl;
00284 startTimer(TIMER_CCA);
00285 updateMacState(CCA_3);
00286 phy->setRadioState(Radio::RX);
00287 break;
00288 case EV_DUPLICATE_RECEIVED:
00289
00290
00291
00292 debugEV << "(28) FSM State BACKOFF, EV_DUPLICATE_RECEIVED:";
00293 if(useMACAcks) {
00294 debugEV << "suspending current transmit tentative and transmitting ack";
00295 transmissionAttemptInterruptedByRx = true;
00296 cancelEvent(backoffTimer);
00297 phy->setRadioState(Radio::TX);
00298 updateMacState(WAITSIFS_6);
00299 startTimer(TIMER_SIFS);
00300 } else {
00301 debugEV << "Nothing to do.";
00302 }
00303
00304 delete msg;
00305
00306 break;
00307 case EV_FRAME_RECEIVED:
00308
00309
00310
00311 debugEV << "(28) FSM State BACKOFF, EV_FRAME_RECEIVED:";
00312 if(useMACAcks) {
00313 debugEV << "suspending current transmit tentative and transmitting ack";
00314 transmissionAttemptInterruptedByRx = true;
00315 cancelEvent(backoffTimer);
00316
00317 phy->setRadioState(Radio::TX);
00318 updateMacState(WAITSIFS_6);
00319 startTimer(TIMER_SIFS);
00320 } else {
00321 debugEV << "sending frame up and resuming normal operation.";
00322 }
00323 sendUp(decapsMsg(static_cast<MacPkt *>(msg)));
00324 delete msg;
00325 break;
00326 case EV_BROADCAST_RECEIVED:
00327 debugEV << "(29) FSM State BACKOFF, EV_BROADCAST_RECEIVED:"
00328 << "sending frame up and resuming normal operation." <<endl;
00329 sendUp(decapsMsg(static_cast<MacPkt *>(msg)));
00330 delete msg;
00331 break;
00332 default:
00333 fsmError(event, msg);
00334 }
00335 }
00336
00337 void csma::attachSignal(MacPkt* mac, simtime_t startTime) {
00338 simtime_t duration = (mac->getBitLength() + phyHeaderLength)/bitrate;
00339 Signal* s = createSignal(startTime, duration, txPower, bitrate);
00340 MacToPhyControlInfo* cinfo = new MacToPhyControlInfo(s);
00341
00342 mac->setControlInfo(cinfo);
00343 }
00344
00345 void csma::updateStatusCCA(t_mac_event event, cMessage *msg) {
00346 switch (event) {
00347 case EV_TIMER_CCA:
00348 {
00349 debugEV<< "(25) FSM State CCA_3, EV_TIMER_CCA" << endl;
00350 bool isIdle = phy->getChannelState().isIdle();
00351 if(isIdle) {
00352 debugEV << "(3) FSM State CCA_3, EV_TIMER_CCA, [Channel Idle]: -> TRANSMITFRAME_4." << endl;
00353 updateMacState(TRANSMITFRAME_4);
00354 phy->setRadioState(Radio::TX);
00355 MacPkt * mac = check_and_cast<MacPkt *>(macQueue.front()->dup());
00356 attachSignal(mac, simTime()+aTurnaroundTime);
00357
00358
00359 sendDelayed(mac, aTurnaroundTime, lowerGateOut);
00360 nbTxFrames++;
00361 } else {
00362
00363 debugEV << "(7) FSM State CCA_3, EV_TIMER_CCA, [Channel Busy]: "
00364 << " increment counters." << endl;
00365 NB = NB+1;
00366
00367
00368
00369 if(NB> macMaxCSMABackoffs) {
00370
00371 debugEV << "Tried " << NB << " backoffs, all reported a busy "
00372 << "channel. Dropping the packet." << endl;
00373 cMessage * mac = macQueue.front();
00374 macQueue.pop_front();
00375 txAttempts = 0;
00376 nbDroppedFrames++;
00377 mac->setName("MAC ERROR");
00378 mac->setKind(PACKET_DROPPED);
00379 sendControlUp(mac);
00380 manageQueue();
00381 } else {
00382
00383 updateMacState(BACKOFF_2);
00384 startTimer(TIMER_BACKOFF);
00385 }
00386 }
00387 break;
00388 }
00389 case EV_DUPLICATE_RECEIVED:
00390 debugEV << "(26) FSM State CCA_3, EV_DUPLICATE_RECEIVED:";
00391 if(useMACAcks) {
00392 debugEV << " setting up radio tx -> WAITSIFS." << endl;
00393
00394
00395
00396 transmissionAttemptInterruptedByRx = true;
00397 cancelEvent(ccaTimer);
00398
00399 phy->setRadioState(Radio::TX);
00400 updateMacState(WAITSIFS_6);
00401 startTimer(TIMER_SIFS);
00402 } else {
00403 debugEV << " Nothing to do." << endl;
00404 }
00405
00406 delete msg;
00407 break;
00408
00409 case EV_FRAME_RECEIVED:
00410 debugEV << "(26) FSM State CCA_3, EV_FRAME_RECEIVED:";
00411 if(useMACAcks) {
00412 debugEV << " setting up radio tx -> WAITSIFS." << endl;
00413
00414
00415
00416 transmissionAttemptInterruptedByRx = true;
00417 cancelEvent(ccaTimer);
00418 phy->setRadioState(Radio::TX);
00419 updateMacState(WAITSIFS_6);
00420 startTimer(TIMER_SIFS);
00421 } else {
00422 debugEV << " Nothing to do." << endl;
00423 }
00424 sendUp(decapsMsg(static_cast<MacPkt *>(msg)));
00425 delete msg;
00426 break;
00427 case EV_BROADCAST_RECEIVED:
00428 debugEV << "(24) FSM State BACKOFF, EV_BROADCAST_RECEIVED:"
00429 << " Nothing to do." << endl;
00430 sendUp(decapsMsg(static_cast<MacPkt *>(msg)));
00431 delete msg;
00432 break;
00433 default:
00434 fsmError(event, msg);
00435 }
00436 }
00437
00438 void csma::updateStatusTransmitFrame(t_mac_event event, cMessage *msg) {
00439 if (event == EV_FRAME_TRANSMITTED) {
00440
00441 MacPkt * packet = macQueue.front();
00442 phy->setRadioState(Radio::RX);
00443
00444 bool expectAck = useMACAcks;
00445 if (packet->getDestAddr() != L2BROADCAST) {
00446
00447 debugEV << "(4) FSM State TRANSMITFRAME_4, "
00448 << "EV_FRAME_TRANSMITTED [Unicast]: ";
00449 } else {
00450
00451 debugEV << "(27) FSM State TRANSMITFRAME_4, EV_FRAME_TRANSMITTED "
00452 << " [Broadcast]";
00453 expectAck = false;
00454 }
00455
00456 if(expectAck) {
00457 debugEV << "RadioSetupRx -> WAITACK." << endl;
00458 updateMacState(WAITACK_5);
00459 startTimer(TIMER_RX_ACK);
00460 } else {
00461 debugEV << ": RadioSetupRx, manageQueue..." << endl;
00462 macQueue.pop_front();
00463 delete packet;
00464 manageQueue();
00465 }
00466 } else {
00467 fsmError(event, msg);
00468 }
00469 }
00470
00471 void csma::updateStatusWaitAck(t_mac_event event, cMessage *msg) {
00472 assert(useMACAcks);
00473
00474 cMessage * mac;
00475 switch (event) {
00476 case EV_ACK_RECEIVED:
00477 debugEV<< "(5) FSM State WAITACK_5, EV_ACK_RECEIVED: "
00478 << " ProcessAck, manageQueue..." << endl;
00479 if(rxAckTimer->isScheduled())
00480 cancelEvent(rxAckTimer);
00481 mac = static_cast<cMessage *>(macQueue.front());
00482 macQueue.pop_front();
00483 txAttempts = 0;
00484 mac->setName("MAC SUCCESS");
00485 mac->setKind(TX_OVER);
00486 sendControlUp(mac);
00487 delete msg;
00488 manageQueue();
00489 break;
00490 case EV_ACK_TIMEOUT:
00491 debugEV << "(12) FSM State WAITACK_5, EV_ACK_TIMEOUT:"
00492 << " incrementCounter/dropPacket, manageQueue..." << endl;
00493 manageMissingAck(event, msg);
00494 break;
00495 case EV_BROADCAST_RECEIVED:
00496 case EV_FRAME_RECEIVED:
00497 sendUp(decapsMsg(static_cast<MacPkt*>(msg)));
00498 case EV_DUPLICATE_RECEIVED:
00499 debugEV << "Error ! Received a frame during SIFS !" << endl;
00500 delete msg;
00501 break;
00502 default:
00503 fsmError(event, msg);
00504 }
00505
00506 }
00507
00508 void csma::manageMissingAck(t_mac_event event, cMessage *msg) {
00509 if (txAttempts < macMaxFrameRetries + 1) {
00510
00511 txAttempts++;
00512 debugEV<< "I will retransmit this packet (I already tried "
00513 << txAttempts << " times)." << endl;
00514 } else {
00515
00516 debugEV << "Packet was transmitted " << txAttempts
00517 << " times and I never got an Ack. I drop the packet." << endl;
00518 cMessage * mac = macQueue.front();
00519 macQueue.pop_front();
00520 txAttempts = 0;
00521 mac->setName("MAC ERROR");
00522 mac->setKind(PACKET_DROPPED);
00523 sendControlUp(mac);
00524 }
00525 manageQueue();
00526 }
00527 void csma::updateStatusSIFS(t_mac_event event, cMessage *msg) {
00528 assert(useMACAcks);
00529
00530 switch (event) {
00531 case EV_TIMER_SIFS:
00532 debugEV<< "(17) FSM State WAITSIFS_6, EV_TIMER_SIFS:"
00533 << " sendAck -> TRANSMITACK." << endl;
00534 updateMacState(TRANSMITACK_7);
00535 attachSignal(ackMessage, simTime());
00536 sendDown(ackMessage);
00537 nbTxAcks++;
00538
00539 ackMessage = NULL;
00540 break;
00541 case EV_TIMER_BACKOFF:
00542
00543
00544 debugEV << "(16) FSM State WAITSIFS_6, EV_TIMER_BACKOFF. "
00545 << "Restart backoff timer and don't move." << endl;
00546 startTimer(TIMER_BACKOFF);
00547 break;
00548 case EV_BROADCAST_RECEIVED:
00549 case EV_FRAME_RECEIVED:
00550 EV << "Error ! Received a frame during SIFS !" << endl;
00551 sendUp(decapsMsg(static_cast<MacPkt*>(msg)));
00552 delete msg;
00553 break;
00554 default:
00555 fsmError(event, msg);
00556 }
00557 }
00558
00559 void csma::updateStatusTransmitAck(t_mac_event event, cMessage *msg) {
00560 assert(useMACAcks);
00561
00562 if (event == EV_FRAME_TRANSMITTED) {
00563 debugEV<< "(19) FSM State TRANSMITACK_7, EV_FRAME_TRANSMITTED:"
00564 << " ->manageQueue." << endl;
00565 phy->setRadioState(Radio::RX);
00566
00567 manageQueue();
00568 } else {
00569 fsmError(event, msg);
00570 }
00571 }
00572
00573 void csma::updateStatusNotIdle(cMessage *msg) {
00574 debugEV<< "(20) FSM State NOT IDLE, EV_SEND_REQUEST. Is a TxBuffer available ?" << endl;
00575 if (macQueue.size() <= queueLength) {
00576 macQueue.push_back(static_cast<MacPkt *>(msg));
00577 debugEV << "(21) FSM State NOT IDLE, EV_SEND_REQUEST"
00578 <<" and [TxBuff avail]: enqueue packet and don't move." << endl;
00579 } else {
00580
00581 debugEV << "(22) FSM State NOT IDLE, EV_SEND_REQUEST"
00582 << " and [TxBuff not avail]: dropping packet and don't move."
00583 << endl;
00584 msg->setName("MAC ERROR");
00585 msg->setKind(PACKET_DROPPED);
00586 sendControlUp(msg);
00587 droppedPacket.setReason(DroppedPacket::QUEUE);
00588 utility->publishBBItem(catDroppedPacket, &droppedPacket, nicId);
00589 }
00590
00591 }
00595 void csma::executeMac(t_mac_event event, cMessage *msg) {
00596 debugEV<< "In executeMac" << endl;
00597 if(macState != IDLE_1 && event == EV_SEND_REQUEST) {
00598 updateStatusNotIdle(msg);
00599 } else {
00600 switch(macState) {
00601 case IDLE_1:
00602 updateStatusIdle(event, msg);
00603 break;
00604 case BACKOFF_2:
00605 updateStatusBackoff(event, msg);
00606 break;
00607 case CCA_3:
00608 updateStatusCCA(event, msg);
00609 break;
00610 case TRANSMITFRAME_4:
00611 updateStatusTransmitFrame(event, msg);
00612 break;
00613 case WAITACK_5:
00614 updateStatusWaitAck(event, msg);
00615 break;
00616 case WAITSIFS_6:
00617 updateStatusSIFS(event, msg);
00618 break;
00619 case TRANSMITACK_7:
00620 updateStatusTransmitAck(event, msg);
00621 break;
00622 default:
00623 EV << "Error in CSMA FSM: an unknown state has been reached. macState=" << macState << endl;
00624 }
00625 }
00626 }
00627
00628 void csma::manageQueue() {
00629 if (macQueue.size() != 0) {
00630 debugEV<< "(manageQueue) there are " << macQueue.size() << " packets to send, entering backoff wait state." << endl;
00631 if( transmissionAttemptInterruptedByRx) {
00632
00633
00634 transmissionAttemptInterruptedByRx = false;
00635 } else {
00636
00637
00638 NB = 0;
00639
00640 }
00641 if(! backoffTimer->isScheduled()) {
00642 startTimer(TIMER_BACKOFF);
00643 }
00644 updateMacState(BACKOFF_2);
00645 } else {
00646 debugEV << "(manageQueue) no packets to send, entering IDLE state." << endl;
00647 updateMacState(IDLE_1);
00648 }
00649 }
00650
00651 void csma::updateMacState(t_mac_states newMacState) {
00652 macState = newMacState;
00653 }
00654
00655
00656
00657
00658 void csma::fsmError(t_mac_event event, cMessage *msg) {
00659 EV<< "FSM Error ! In state " << macState << ", received unknown event:" << event << "." << endl;
00660 if (msg != NULL)
00661 delete msg;
00662 }
00663
00664 void csma::startTimer(t_mac_timer timer) {
00665 if (timer == TIMER_BACKOFF) {
00666 scheduleAt(scheduleBackoff(), backoffTimer);
00667 } else if (timer == TIMER_CCA) {
00668 simtime_t ccaTime = rxSetupTime + ccaDetectionTime;
00669 debugEV<< "(startTimer) ccaTimer value=" << ccaTime
00670 << "(rxSetupTime,ccaDetectionTime:" << rxSetupTime
00671 << "," << ccaDetectionTime <<")." << endl;
00672 scheduleAt(simTime()+rxSetupTime+ccaDetectionTime, ccaTimer);
00673 } else if (timer==TIMER_SIFS) {
00674 assert(useMACAcks);
00675 debugEV << "(startTimer) sifsTimer value=" << sifs << endl;
00676 scheduleAt(simTime()+sifs, sifsTimer);
00677 } else if (timer==TIMER_RX_ACK) {
00678 assert(useMACAcks);
00679 debugEV << "(startTimer) rxAckTimer value=" << macAckWaitDuration << endl;
00680 scheduleAt(simTime()+macAckWaitDuration, rxAckTimer);
00681 } else {
00682 EV << "Unknown timer requested to start:" << timer << endl;
00683 }
00684 }
00685
00686 simtime_t csma::scheduleBackoff() {
00687
00688 simtime_t backoffTime;
00689
00690 switch(backoffMethod) {
00691 case EXPONENTIAL:
00692 {
00693 int BE = std::min(macMinBE + NB, macMaxBE);
00694 double d = std::pow((double) 2, (int) BE);
00695 int v = (int) d - 1;
00696 int r = intuniform(0, v, 0);
00697 backoffTime = r * aUnitBackoffPeriod;
00698
00699 debugEV<< "(startTimer) backoffTimer value=" << backoffTime
00700 << " (BE=" << BE << ", 2^BE-1= " << v << "r="
00701 << r << ")" << endl;
00702 break;
00703 }
00704 case LINEAR:
00705 {
00706 int slots = intuniform(1, initialCW + NB, 0);
00707 backoffTime = slots * aUnitBackoffPeriod;
00708 debugEV<< "(startTimer) backoffTimer value=" << backoffTime << endl;
00709 break;
00710 }
00711 case CONSTANT:
00712 {
00713 int slots = intuniform(1, initialCW, 0);
00714 backoffTime = slots * aUnitBackoffPeriod;
00715 debugEV<< "(startTimer) backoffTimer value=" << backoffTime << endl;
00716 break;
00717 }
00718 default:
00719 error("Unknown backoff method!");
00720 }
00721
00722 nbBackoffs = nbBackoffs + 1;
00723 backoffValues = backoffValues + backoffTime.dbl();
00724
00725 return backoffTime + simTime();
00726 }
00727
00728
00729
00730
00731 void csma::handleSelfMsg(cMessage *msg) {
00732 debugEV<< "timer routine." << endl;
00733 if(msg==backoffTimer)
00734 executeMac(EV_TIMER_BACKOFF, msg);
00735 else if(msg==ccaTimer)
00736 executeMac(EV_TIMER_CCA, msg);
00737 else if(msg==sifsTimer)
00738 executeMac(EV_TIMER_SIFS, msg);
00739 else if(msg==rxAckTimer) {
00740 nbMissedAcks++;
00741 executeMac(EV_ACK_TIMEOUT, msg);
00742 } else
00743 EV << "CSMA Error: unknown timer fired:" << msg << endl;
00744 }
00745
00750 void csma::handleLowerMsg(cMessage *msg) {
00751 MacPkt *macPkt = static_cast<MacPkt *> (msg);
00752 long src = macPkt->getSrcAddr();
00753 long dest = macPkt->getDestAddr();
00754 long ExpectedNr = 0;
00755
00756 debugEV<< "Received frame name= " << macPkt->getName()
00757 << ", myState=" << macState << " src=" << macPkt->getSrcAddr()
00758 << " dst=" << macPkt->getDestAddr() << " myAddr="
00759 << myMacAddr << endl;
00760
00761 if(macPkt->getDestAddr() == myMacAddr)
00762 {
00763 if(!useMACAcks) {
00764 debugEV << "Received a data packet addressed to me." << endl;
00765
00766 executeMac(EV_FRAME_RECEIVED, macPkt);
00767 }
00768 else {
00769 long SeqNr = macPkt->getSequenceId();
00770
00771 if(strcmp(macPkt->getName(), "CSMA-Ack") != 0) {
00772
00773
00774
00775
00776 debugEV << "Received a data packet addressed to me,"
00777 << " preparing an ack..." << endl;
00778
00779
00780
00781 if(ackMessage != NULL)
00782 delete ackMessage;
00783 ackMessage = new MacPkt("CSMA-Ack");
00784 ackMessage->setSrcAddr(myMacAddr);
00785 ackMessage->setDestAddr(macPkt->getSrcAddr());
00786 ackMessage->setBitLength(ackLength);
00787
00788 if(SeqNrChild.find(src) == SeqNrChild.end()) {
00789
00790 SeqNrChild[src] = SeqNr + 1;
00791 debugEV << "Adding a new child to the map of Sequence numbers:" << src << endl;
00792 executeMac(EV_FRAME_RECEIVED, macPkt);
00793 }
00794 else {
00795 ExpectedNr = SeqNrChild[src];
00796 debugEV << "Expected Sequence number is " << ExpectedNr <<
00797 " and number of packet is " << SeqNr << endl;
00798 if(SeqNr < ExpectedNr) {
00799
00800 nbDuplicates++;
00801 executeMac(EV_DUPLICATE_RECEIVED, macPkt);
00802 }
00803 else {
00804 SeqNrChild[src] = SeqNr + 1;
00805 executeMac(EV_FRAME_RECEIVED, macPkt);
00806 }
00807 }
00808
00809 } else if(macQueue.size() != 0) {
00810
00811
00812
00813 MacPkt * firstPacket = static_cast<MacPkt *>(macQueue.front());
00814 if(macPkt->getSrcAddr() == firstPacket->getDestAddr()) {
00815 nbRecvdAcks++;
00816 executeMac(EV_ACK_RECEIVED, macPkt);
00817 } else {
00818 EV << "Error! Received an ack from an unexpected source: src=" << macPkt->getSrcAddr() << ", I was expecting from node addr=" << firstPacket->getDestAddr() << endl;
00819 delete macPkt;
00820 }
00821 } else {
00822 EV << "Error! Received an Ack while my send queue was empty. src=" << macPkt->getSrcAddr() << "." << endl;
00823 delete macPkt;
00824 }
00825 }
00826 }
00827 else if (dest == L2BROADCAST) {
00828 executeMac(EV_BROADCAST_RECEIVED, macPkt);
00829 } else {
00830 debugEV << "packet not for me, deleting...\n";
00831 delete macPkt;
00832 }
00833 }
00834
00835 void csma::handleLowerControl(cMessage *msg) {
00836 if (msg->getKind() == MacToPhyInterface::TX_OVER) {
00837 executeMac(EV_FRAME_TRANSMITTED, msg);
00838 } else if (msg->getKind() == BaseDecider::PACKET_DROPPED) {
00839 debugEV<< "control message: PACKED DROPPED" << endl;
00840 } else if (msg->getKind() == MacToPhyInterface::RADIO_SWITCHING_OVER) {
00841 debugEV<< "control message: RADIO_SWITCHING_OVER" << endl;
00842 } else {
00843 EV << "Invalid control message type (type=NOTHING) : name="
00844 << msg->getName() << " modulesrc="
00845 << msg->getSenderModule()->getFullPath()
00846 << "." << endl;
00847 }
00848 delete msg;
00849 }
00850
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 cPacket *csma::decapsMsg(MacPkt * macPkt) {
00872 cPacket * msg = macPkt->decapsulate();
00873 MacToNetwControlInfo* info = new MacToNetwControlInfo(macPkt->getSrcAddr());
00874
00875 msg->setControlInfo(info);
00876 return msg;
00877 }
00878