csma.cc

00001 /* -*- mode:c++ -*- ********************************************************
00002  * file:        csma.cc
00003  *
00004  * author:      Jerome Rousselot, Marcel Steine, Amre El-Hoiydi,
00005  *        Marc Loebbers, Yosia Hadisusanto, Andreas Koepke
00006  *
00007  * copyright:   (C) 2007-2009 CSEM SA
00008  *        (C) 2009 T.U. Eindhoven
00009  *        (C) 2004,2005,2006
00010  *              Telecommunication Networks Group (TKN) at Technische
00011  *              Universitaet Berlin, Germany.
00012  *
00013  *              This program is free software; you can redistribute it
00014  *              and/or modify it under the terms of the GNU General Public
00015  *              License as published by the Free Software Foundation; either
00016  *              version 2 of the License, or (at your option) any later
00017  *              version.
00018  *              For further information see file COPYING
00019  *              in the top level directory
00020  *
00021  * Funding: This work was partially financed by the European Commission under the
00022  * Framework 6 IST Project "Wirelessly Accessible Sensor Populations"
00023  * (WASP) under contract IST-034963.
00024  ***************************************************************************
00025  * part of:    Modifications to the MF-2 framework by CSEM
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 //#include <Consts802154.h>
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     //init parameters for backoff method
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     // initialize the timers
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     //check parameters for consistency
00121     cModule* phyModule = FindModule<BasePhyLayer*>
00122 								::findSubModule(getParentModule());
00123 
00124     //aTurnaroundTime should match (be equal or bigger) the RX to TX
00125     //switching time of the radio
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   //MacPkt *macPkt = encapsMsg(msg);
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       //no record of current parent -> add next sequence number to map
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   //RadioAccNoise3PhyControlInfo *pco = new RadioAccNoise3PhyControlInfo(bitrate);
00215   //macPkt->setControlInfo(pco);
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       //BE = macMinBE;
00231       startTimer(TIMER_BACKOFF);
00232     } else {
00233       // queue is full, message has to be deleted
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     //sendUp(decapsMsg(static_cast<MacSeqPkt *>(msg)));
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     // suspend current transmission attempt,
00290     // transmit ack,
00291     // and resume transmission when entering manageQueue()
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     //sendUp(decapsMsg(static_cast<MacSeqPkt *>(msg)));
00304     delete msg;
00305 
00306     break;
00307   case EV_FRAME_RECEIVED:
00308     // suspend current transmission attempt,
00309     // transmit ack,
00310     // and resume transmission when entering manageQueue()
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       //sendDown(msg);
00358       // give time for the radio to be in Tx state before transmitting
00359       sendDelayed(mac, aTurnaroundTime, lowerGateOut);
00360       nbTxFrames++;
00361     } else {
00362       // Channel was busy, increment 802.15.4 backoff timers as specified.
00363       debugEV << "(7) FSM State CCA_3, EV_TIMER_CCA, [Channel Busy]: "
00364       << " increment counters." << endl;
00365       NB = NB+1;
00366       //BE = std::min(BE+1, macMaxBE);
00367 
00368       // decide if we go for another backoff or if we drop the frame.
00369       if(NB> macMaxCSMABackoffs) {
00370         // drop the frame
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         // redo backoff
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       // suspend current transmission attempt,
00394       // transmit ack,
00395       // and resume transmission when entering manageQueue()
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     //sendUp(decapsMsg(static_cast<MacPkt *>(msg)));
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       // suspend current transmission attempt,
00414       // transmit ack,
00415       // and resume transmission when entering manageQueue()
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     //    delete msg;
00441     MacPkt * packet = macQueue.front();
00442     phy->setRadioState(Radio::RX);
00443 
00444     bool expectAck = useMACAcks;
00445     if (packet->getDestAddr() != L2BROADCAST) {
00446       //unicast
00447       debugEV << "(4) FSM State TRANSMITFRAME_4, "
00448          << "EV_FRAME_TRANSMITTED [Unicast]: ";
00449     } else {
00450       //broadcast
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     // increment counter
00511     txAttempts++;
00512     debugEV<< "I will retransmit this packet (I already tried "
00513     << txAttempts << " times)." << endl;
00514   } else {
00515     // drop packet
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     //    sendDelayed(ackMessage, aTurnaroundTime, lowergateOut);
00539     ackMessage = NULL;
00540     break;
00541   case EV_TIMER_BACKOFF:
00542     // Backoff timer has expired while receiving a frame. Restart it
00543     // and stay here.
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     //    delete msg;
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     // queue is full, message has to be deleted
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       // resume a transmission cycle which was interrupted by
00633       // a frame reception during CCA check
00634       transmissionAttemptInterruptedByRx = false;
00635     } else {
00636       // initialize counters if we start a new transmission
00637       // cycle from zero
00638       NB = 0;
00639       //BE = macMinBE;
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  * Called by the FSM machine when an unknown transition is requested.
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  * Binds timers to events and executes FSM.
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 //      nbRxFrames++;
00766       executeMac(EV_FRAME_RECEIVED, macPkt);
00767     }
00768     else {
00769       long SeqNr = macPkt->getSequenceId();
00770 
00771       if(strcmp(macPkt->getName(), "CSMA-Ack") != 0) {
00772         // This is a data message addressed to us
00773         // and we should send an ack.
00774         // we build the ack packet here because we need to
00775         // copy data from macPkt (src).
00776         debugEV << "Received a data packet addressed to me,"
00777            << " preparing an ack..." << endl;
00778 
00779 //        nbRxFrames++;
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         //Check for duplicates by checking expected seqNr of sender
00788         if(SeqNrChild.find(src) == SeqNrChild.end()) {
00789           //no record of current child -> add expected next number to map
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             //Duplicate Packet, count and do not send to upper layer
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         // message is an ack, and it is for us.
00812         // Is it from the right node ?
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 //void csma::receiveBBItem(int category, const BBItem *details, int scopeModuleId) {
00856 //  Enter_Method_Silent();
00857 //  BasicLayer::receiveBBItem(category, details, scopeModuleId);
00858 //
00859 //  if (category == catRadioState) {
00860 //    radioState
00861 //        = static_cast<const RadioAccNoise3State *> (details)->getState();
00862 //    // radio just told us its state
00863 //  } else if (category == catRSSI) {
00864 //    rssi = static_cast<const RSSI *> (details)->getRSSI();
00865 //    if (radioState == RadioAccNoise3State::RX) {
00866 //      // we could do something here if we wanted to.
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