Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes

csma Class Reference
[CSMA - Classes for the CSMA implementation of MiXiMmacLayer - MAC layer modules]

Generic CSMA Mac-Layer. More...

#include <csma.h>

Inherits BaseMacLayer.

Inherited by CSMA802154.

Collaboration diagram for csma:
Collaboration graph
[legend]

List of all members.

Public Member Functions

virtual void initialize (int)
 Initialization of the module and some variables.
virtual void finish ()
 Delete all dynamically allocated objects of the module.
virtual void handleLowerMsg (cMessage *)
 Handle messages from lower layer.
virtual void handleUpperMsg (cMessage *)
 Handle messages from upper layer.
virtual void handleSelfMsg (cMessage *)
 Handle self messages such as timers.
virtual void handleLowerControl (cMessage *msg)
 Handle control messages from lower layer.

Protected Types

enum  t_mac_states {
  IDLE_1 = 1, BACKOFF_2, CCA_3, TRANSMITFRAME_4,
  WAITACK_5, WAITSIFS_6, TRANSMITACK_7
}
 

MAC states see states diagram.


enum  t_mac_timer {
  TIMER_NULL = 0, TIMER_BACKOFF, TIMER_CCA, TIMER_SIFS,
  TIMER_RX_ACK
}
 

Kinds for timer messages.


enum  t_mac_event {
  EV_SEND_REQUEST = 1, EV_TIMER_BACKOFF, EV_FRAME_TRANSMITTED, EV_ACK_RECEIVED,
  EV_ACK_TIMEOUT, EV_FRAME_RECEIVED, EV_DUPLICATE_RECEIVED, EV_TIMER_SIFS,
  EV_BROADCAST_RECEIVED, EV_TIMER_CCA
}
 

MAC state machine events. See state diagram.


enum  t_csma_frame_types { DATA, ACK }
 

Types for frames sent by the CSMA.


enum  t_mac_carrier_sensed { CHANNEL_BUSY = 1, CHANNEL_FREE }
enum  t_mac_status {
  STATUS_OK = 1, STATUS_ERROR, STATUS_RX_ERROR, STATUS_RX_TIMEOUT,
  STATUS_FRAME_TO_PROCESS, STATUS_NO_FRAME_TO_PROCESS, STATUS_FRAME_TRANSMITTED
}
enum  backoff_methods { CONSTANT = 0, LINEAR, EXPONENTIAL }
 

The different back-off methods.

More...
typedef std::list< MacPkt * > MacQueue

Protected Member Functions

void fsmError (t_mac_event event, cMessage *msg)
 This MAC layers MAC address.
void executeMac (t_mac_event event, cMessage *msg)
void updateStatusIdle (t_mac_event event, cMessage *msg)
void updateStatusBackoff (t_mac_event event, cMessage *msg)
void updateStatusCCA (t_mac_event event, cMessage *msg)
void updateStatusTransmitFrame (t_mac_event event, cMessage *msg)
void updateStatusWaitAck (t_mac_event event, cMessage *msg)
void updateStatusSIFS (t_mac_event event, cMessage *msg)
void updateStatusTransmitAck (t_mac_event event, cMessage *msg)
void updateStatusNotIdle (cMessage *msg)
void manageQueue ()
void updateMacState (t_mac_states newMacState)
void attachSignal (MacPkt *mac, simtime_t startTime)
void manageMissingAck (t_mac_event event, cMessage *msg)
void startTimer (t_mac_timer timer)
virtual simtime_t scheduleBackoff ()
virtual cPacket * decapsMsg (MacPkt *macPkt)

Protected Attributes

bool stats
 Records general statistics?
bool trace
 Record out put vectors?
t_mac_states macState
 keep track of MAC state
t_mac_status status
simtime_t sifs
 Maximum time between a packet and its ACK.
simtime_t macAckWaitDuration
 The amount of time the MAC waits for the ACK of a packet.
bool transmissionAttemptInterruptedByRx
simtime_t ccaDetectionTime
 CCA detection time.
simtime_t rxSetupTime
 Time to setup radio from sleep to Rx state.
simtime_t aTurnaroundTime
 Time to switch radio from Rx to Tx state.
int macMaxCSMABackoffs
 maximum number of backoffs before frame drop
unsigned int macMaxFrameRetries
 maximum number of frame retransmissions without ack
simtime_t aUnitBackoffPeriod
 base time unit for calculating backoff durations
bool useMACAcks
 Stores if the MAC expects Acks for Unicast packets.
backoff_methods backoffMethod
 Defines the backoff method to be used.
int macMinBE
 Minimum backoff exponent. Only used for exponential backoff method.
int macMaxBE
 Maximum backoff exponent. Only used for exponential backoff method.
double initialCW
 initial contention window size Only used for linear and constant backoff method.
double txPower
 The power (in mW) to transmit with.
int NB
 number of backoff performed until now for current frame
MacQueue macQueue
 A queue to store packets from upper layer in case another packet is still waiting for transmission..
unsigned int queueLength
 length of the queue
unsigned int txAttempts
 count the number of tx attempts
double bitrate
 the bit rate at which we transmit
DroppedPacket droppedPacket
 Inspect reasons for dropped packets.
int catDroppedPacket
 plus category from BB
int nicId
 publish dropped packets nic wide
int ackLength
 The bit length of the ACK packet.
MacPkt * ackMessage
std::map< int, unsigned long > SeqNrParent
std::map< int, unsigned long > SeqNrChild
Different tracked statistics.

long nbTxFrames
long nbRxFrames
long nbMissedAcks
long nbRecvdAcks
long nbDroppedFrames
long nbTxAcks
long nbDuplicates
long nbBackoffs
double backoffValues
Pointer for timer messages.

cMessage * backoffTimer
cMessage * ccaTimer
cMessage * txTimer
cMessage * sifsTimer
cMessage * rxAckTimer

Detailed Description

Generic CSMA Mac-Layer.

Supports constant, linear and exponential backoffs as well as MAC ACKs.

Author:
Jerome Rousselot, Amre El-Hoiydi, Marc Loebbers, Yosia Hadisusanto, Andreas Koepke
Karl Wessel (port for MiXiM)
csmaFSM.png

CSMA Mac-Layer - finite state machine

Definition at line 54 of file csma.h.


Member Enumeration Documentation

enum csma::backoff_methods [protected]

The different back-off methods.

Enumerator:
CONSTANT 

Constant back-off time.

LINEAR 

Linear increasing back-off time.

EXPONENTIAL 

Exponentially increasing back-off time.

Definition at line 169 of file csma.h.

                         {
      CONSTANT = 0,
      LINEAR,
      EXPONENTIAL,
    };


Member Function Documentation

cPacket * csma::decapsMsg ( MacPkt *  macPkt  )  [protected, virtual]

Update the internal copies of interesting BB variables

Reimplemented from BaseMacLayer.

Reimplemented in CSMA802154.

Definition at line 871 of file csma.cc.

                                        {
  cPacket * msg = macPkt->decapsulate();
  MacToNetwControlInfo* info = new MacToNetwControlInfo(macPkt->getSrcAddr());

  msg->setControlInfo(info);
  return msg;
}

void csma::executeMac ( t_mac_event  event,
cMessage *  msg 
) [protected]

Updates state machine.

Definition at line 595 of file csma.cc.

References macState.

Referenced by handleLowerControl(), handleLowerMsg(), handleSelfMsg(), and handleUpperMsg().

                                                      {
  debugEV<< "In executeMac" << endl;
  if(macState != IDLE_1 && event == EV_SEND_REQUEST) {
    updateStatusNotIdle(msg);
  } else {
    switch(macState) {
    case IDLE_1:
      updateStatusIdle(event, msg);
      break;
    case BACKOFF_2:
      updateStatusBackoff(event, msg);
      break;
    case CCA_3:
      updateStatusCCA(event, msg);
      break;
    case TRANSMITFRAME_4:
      updateStatusTransmitFrame(event, msg);
      break;
    case WAITACK_5:
      updateStatusWaitAck(event, msg);
      break;
    case WAITSIFS_6:
      updateStatusSIFS(event, msg);
      break;
    case TRANSMITACK_7:
      updateStatusTransmitAck(event, msg);
      break;
    default:
      EV << "Error in CSMA FSM: an unknown state has been reached. macState=" << macState << endl;
    }
  }
}

void csma::handleLowerMsg ( cMessage *  msg  )  [virtual]

Handle messages from lower layer.

Compares the address of this Host with the destination address in frame. Generates the corresponding event.

Reimplemented from BaseMacLayer.

Definition at line 750 of file csma.cc.

References ackLength, executeMac(), macQueue, macState, BaseMacLayer::myMacAddr, and useMACAcks.

                                       {
  MacPkt *macPkt = static_cast<MacPkt *> (msg);
  long src = macPkt->getSrcAddr();
  long dest = macPkt->getDestAddr();
  long ExpectedNr = 0;

  debugEV<< "Received frame name= " << macPkt->getName()
  << ", myState=" << macState << " src=" << macPkt->getSrcAddr()
  << " dst=" << macPkt->getDestAddr() << " myAddr="
  << myMacAddr << endl;

  if(macPkt->getDestAddr() == myMacAddr)
  {
    if(!useMACAcks) {
      debugEV << "Received a data packet addressed to me." << endl;
//      nbRxFrames++;
      executeMac(EV_FRAME_RECEIVED, macPkt);
    }
    else {
      long SeqNr = macPkt->getSequenceId();

      if(strcmp(macPkt->getName(), "CSMA-Ack") != 0) {
        // This is a data message addressed to us
        // and we should send an ack.
        // we build the ack packet here because we need to
        // copy data from macPkt (src).
        debugEV << "Received a data packet addressed to me,"
           << " preparing an ack..." << endl;

//        nbRxFrames++;

        if(ackMessage != NULL)
          delete ackMessage;
        ackMessage = new MacPkt("CSMA-Ack");
        ackMessage->setSrcAddr(myMacAddr);
        ackMessage->setDestAddr(macPkt->getSrcAddr());
        ackMessage->setBitLength(ackLength);
        //Check for duplicates by checking expected seqNr of sender
        if(SeqNrChild.find(src) == SeqNrChild.end()) {
          //no record of current child -> add expected next number to map
          SeqNrChild[src] = SeqNr + 1;
          debugEV << "Adding a new child to the map of Sequence numbers:" << src << endl;
          executeMac(EV_FRAME_RECEIVED, macPkt);
        }
        else {
          ExpectedNr = SeqNrChild[src];
          debugEV << "Expected Sequence number is " << ExpectedNr <<
          " and number of packet is " << SeqNr << endl;
          if(SeqNr < ExpectedNr) {
            //Duplicate Packet, count and do not send to upper layer
            nbDuplicates++;
            executeMac(EV_DUPLICATE_RECEIVED, macPkt);
          }
          else {
            SeqNrChild[src] = SeqNr + 1;
            executeMac(EV_FRAME_RECEIVED, macPkt);
          }
        }

      } else if(macQueue.size() != 0) {

        // message is an ack, and it is for us.
        // Is it from the right node ?
        MacPkt * firstPacket = static_cast<MacPkt *>(macQueue.front());
        if(macPkt->getSrcAddr() == firstPacket->getDestAddr()) {
          nbRecvdAcks++;
          executeMac(EV_ACK_RECEIVED, macPkt);
        } else {
          EV << "Error! Received an ack from an unexpected source: src=" << macPkt->getSrcAddr() << ", I was expecting from node addr=" << firstPacket->getDestAddr() << endl;
          delete macPkt;
        }
      } else {
        EV << "Error! Received an Ack while my send queue was empty. src=" << macPkt->getSrcAddr() << "." << endl;
        delete macPkt;
      }
    }
  }
  else if (dest == L2BROADCAST) {
    executeMac(EV_BROADCAST_RECEIVED, macPkt);
  } else {
    debugEV << "packet not for me, deleting...\n";
    delete macPkt;
  }
}

void csma::handleUpperMsg ( cMessage *  msg  )  [virtual]

Handle messages from upper layer.

Encapsulates the message to be transmitted and pass it on to the FSM main method for further processing.

Reimplemented from BaseMacLayer.

Definition at line 188 of file csma.cc.

References executeMac(), NetwToMacControlInfo::getNextHopMac(), BaseMacLayer::headerLength, BaseMacLayer::myMacAddr, and useMACAcks.

                                       {
  //MacPkt *macPkt = encapsMsg(msg);
  MacPkt *macPkt = new MacPkt(msg->getName());
  macPkt->setBitLength(headerLength);
  NetwToMacControlInfo* cInfo =
      static_cast<NetwToMacControlInfo*> (msg->removeControlInfo());
  debugEV<<"CSMA received a message from upper layer, name is " << msg->getName() <<", CInfo removed, mac addr="<< cInfo->getNextHopMac()<<endl;
  int dest = cInfo->getNextHopMac();
  macPkt->setDestAddr(dest);
  delete cInfo;
  macPkt->setSrcAddr(myMacAddr);

  if(useMACAcks) {
    if(SeqNrParent.find(dest) == SeqNrParent.end()) {
      //no record of current parent -> add next sequence number to map
      SeqNrParent[dest] = 1;
      macPkt->setSequenceId(0);
      debugEV << "Adding a new parent to the map of Sequence numbers:" << dest << endl;
    }
    else {
      macPkt->setSequenceId(SeqNrParent[dest]);
      debugEV << "Packet send with sequence number = " << SeqNrParent[dest] << endl;
      SeqNrParent[dest]++;
    }
  }

  //RadioAccNoise3PhyControlInfo *pco = new RadioAccNoise3PhyControlInfo(bitrate);
  //macPkt->setControlInfo(pco);
  assert(static_cast<cPacket*>(msg));
  macPkt->encapsulate(static_cast<cPacket*>(msg));
  debugEV <<"pkt encapsulated, length: " << macPkt->getBitLength() << "\n";
  executeMac(EV_SEND_REQUEST, macPkt);
}

void csma::initialize ( int  stage  )  [virtual]

Initialization of the module and some variables.

Initialize the of the omnetpp.ini variables in stage 1. In stage two subscribe to the RadioState.

Reimplemented from BaseMacLayer.

Reimplemented in CSMA802154.

Definition at line 51 of file csma.cc.

References ackLength, aTurnaroundTime, aUnitBackoffPeriod, backoffMethod, bitrate, catDroppedPacket, ccaDetectionTime, droppedPacket, Blackboard::getCategory(), BaseMacLayer::getConnectionManager(), initialCW, macAckWaitDuration, macMaxBE, macMaxCSMABackoffs, macMaxFrameRetries, macMinBE, macState, NB, nicId, queueLength, rxSetupTime, DroppedPacket::setReason(), sifs, stats, trace, txAttempts, txPower, useMACAcks, and BaseModule::utility.

                               {
  BaseMacLayer::initialize(stage);

  if (stage == 0) {

    useMACAcks = par("useMACAcks").boolValue();
    queueLength = par("queueLength");
    sifs = par("sifs");
    transmissionAttemptInterruptedByRx = false;
    nbTxFrames = 0;
    nbRxFrames = 0;
    nbMissedAcks = 0;
    nbTxAcks = 0;
    nbRecvdAcks = 0;
    nbDroppedFrames = 0;
    nbDuplicates = 0;
    nbBackoffs = 0;
    backoffValues = 0;
    stats = par("stats");
    trace = par("trace");
    macMaxCSMABackoffs = par("macMaxCSMABackoffs");
    macMaxFrameRetries = par("macMaxFrameRetries");
    macAckWaitDuration = par("macAckWaitDuration").doubleValue();
    aUnitBackoffPeriod = par("aUnitBackoffPeriod");
    ccaDetectionTime = par("ccaDetectionTime").doubleValue();
    rxSetupTime = par("rxSetupTime").doubleValue();
    aTurnaroundTime = par("aTurnaroundTime").doubleValue();
    bitrate = par("bitrate");
    ackLength = par("ackLength");
    ackMessage = NULL;

    //init parameters for backoff method
    std::string backoffMethodStr = par("backoffMethod").stdstringValue();
    if(backoffMethodStr == "exponential") {
      backoffMethod = EXPONENTIAL;
      macMinBE = par("macMinBE");
      macMaxBE = par("macMaxBE");
    }
    else {
      if(backoffMethodStr == "linear") {
        backoffMethod = LINEAR;
      }
      else if (backoffMethodStr == "constant") {
        backoffMethod = CONSTANT;
      }
      else {
        error("Unknown backoff method \"%s\".\
             Use \"constant\", \"linear\" or \"\
             \"exponential\".", backoffMethodStr.c_str());
      }
      initialCW = par("contentionWindow");
    }
    NB = 0;

    txPower = par("txPower").doubleValue();

    droppedPacket.setReason(DroppedPacket::NONE);
    nicId = getParentModule()->getId();

    catDroppedPacket = utility->getCategory(&droppedPacket);

    // initialize the timers
    backoffTimer = new cMessage("timer-backoff");
    ccaTimer = new cMessage("timer-cca");
    sifsTimer = new cMessage("timer-sifs");
    rxAckTimer = new cMessage("timer-rxAck");
    macState = IDLE_1;
    txAttempts = 0;

    //check parameters for consistency
    cModule* phyModule = FindModule<BasePhyLayer*>
								::findSubModule(getParentModule());

    //aTurnaroundTime should match (be equal or bigger) the RX to TX
    //switching time of the radio
    if(phyModule->hasPar("timeRXToTX")) {
      simtime_t rxToTx = phyModule->par("timeRXToTX").doubleValue();
      if( rxToTx > aTurnaroundTime)
      {
        opp_warning("Parameter \"aTurnaroundTime\" (%f) does not match"
              " the radios RX to TX switching time (%f)! It"
              " should be equal or bigger",
              aTurnaroundTime.dbl(), rxToTx.dbl());
      }
    }

  } else if(stage == 1) {
    BaseConnectionManager* cc = getConnectionManager();

      if(cc->hasPar("pMax") && txPower > cc->par("pMax").doubleValue())
            opp_error("TranmitterPower can't be bigger than pMax in ConnectionManager! "
                  "Please adjust your omnetpp.ini file accordingly");

      debugEV << "queueLength = " << queueLength
    << " bitrate = " << bitrate
    << " backoff method = " << par("backoffMethod").stringValue() << endl;

    debugEV << "finished csma init stage 1." << endl;
  }
}


Member Data Documentation

simtime_t csma::sifs [protected]

Maximum time between a packet and its ACK.

Usually this is slightly more then the tx-rx turnaround time The channel should stay clear within this period of time.

Definition at line 187 of file csma.h.

Referenced by initialize().

unsigned int csma::txAttempts [protected]

count the number of tx attempts

This holds the number of transmission attempts for the current frame.

Definition at line 243 of file csma.h.

Referenced by initialize().


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