Protected Types | Protected Member Functions | Protected Attributes

CSMAMacLayer Class Reference
[macLayer - MAC layer modulesCSMA - Classes for the CSMA implementation of MiXiM]

MAC module which provides non-persistent CSMA. More...

#include <CSMAMacLayer.h>

Inherits BaseMacLayer.

Collaboration diagram for CSMAMacLayer:
Collaboration graph
[legend]

List of all members.

Protected Types

enum  States { RX, CCA, TX }
 

MAC states.

More...
typedef std::list< cPacket * > MacQueue
 Type for a queue of cPackets.

Protected Member Functions

virtual void initialize (int)
 Inspect reasons for dropped packets.
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.
virtual void scheduleBackoff ()
 schedule a backoff
virtual MacPkt * encapsMsg (cPacket *pkt)
 Encapsulates the NetwPkt into the MacPkt and sets the parameters.

Protected Attributes

States macState
 kepp track of MAC state
double slotDuration
 Duration of a slot.
double difs
 Maximum time between a packet and its ACK.
MacQueue macQueue
 A queue to store packets from upper layer in case another packet is still waiting for transmission..
unsigned queueLength
 length of the queue
cMessage * backoffTimer
 Timer for backoff (non-persistent CSMA).
cMessage * minorMsg
 Multi-purpose message.
unsigned txAttempts
 count the number of tx attempts
unsigned maxTxAttempts
 maximum number of transmission attempts
double bitrate
 the bit rate at which we transmit
double txPower
 The power at which we transmit.
unsigned initialCW
 initial contention window size
double nbBackoffs
 Counts the total number of backoffs.
double backoffValues
 Counts the total time spent in backoff.
unsigned long nbTxFrames
 Counts the number of frames transmitted.

Detailed Description

MAC module which provides non-persistent CSMA.

This is an implementation of a simple non-persistent CSMA. The idea of nonpersistent CSMA is "listen before talk". Before attempting to transmit, a station will sense the medium for a carrier signal, which, if present, indicates that some other station is sending.

If the channel is busy a random waiting time is computed and after this time the channel is sensed again. Once the channel gets idle the message is sent. (State of the channel is obtained from ChannelInfo via phyLayer.)

An option of this module is to use a queue. If a packet from the upper layer arrives although there is still another packet waiting for its transmission or being transmitted the new packet can be stored in this queue. The length of this queue can be specified by the user in the omnetpp.ini file. By default the length is 0. If the queue is full or there is no queue (length = 0) new packet(s) will be deleted.

ATTENTION: Imagine the following scenario:

Several stations receive a broadcast request packet, usally exactly at the same time. They will all try to answer at exactly the same time, i.e. they all will sense the channel at exactly the same time and start to transmit because the channel was sensed idle by all of them. Therefore a small random delay should be built into one/some of the upper layers to simulate a random processing time!

The TestApplLayer e.g. implements such a processing delay!

Author:
Marc L�bbers, Yosia Hadisusanto, Andreas Koepke, Karl Wessel

Definition at line 51 of file CSMAMacLayer.h.


Member Enumeration Documentation

enum CSMAMacLayer::States [protected]

MAC states.

The MAC states help to keep track what the MAC is actually trying to do -- this is esp. useful when radio switching takes some time.

Enumerator:
RX 

MAC accepts packets from PHY layer.

CCA 

Clear Channel Assessment - MAC checks whether medium is busy.

TX 

MAC transmits a packet.

Definition at line 66 of file CSMAMacLayer.h.

                {
        RX,
        CCA,
        TX,
    };


Member Function Documentation

void CSMAMacLayer::handleLowerMsg ( cMessage *  msg  )  [protected, virtual]

Handle messages from lower layer.

Compare the address of this Host with the destination address in frame. If they are equal or the frame is broadcast, we send this frame to the upper layer. If not delete it.

Reimplemented from BaseMacLayer.

Definition at line 202 of file CSMAMacLayer.cc.

References backoffTimer, BaseMacLayer::decapsMsg(), BaseMacLayer::myMacAddr, scheduleBackoff(), and BaseLayer::sendUp().

{
    MacPkt *mac = static_cast<MacPkt *>(msg);
    int dest = mac->getDestAddr();

    if(dest == myMacAddr || dest == L2BROADCAST)
    {
      debugEV << "sending pkt to upper...\n";
        sendUp(decapsMsg(mac));
    }
    else {
      debugEV << "packet not for me, deleting...\n";
        delete mac;
    }

    if(!backoffTimer->isScheduled()) scheduleBackoff();
}

void CSMAMacLayer::handleSelfMsg ( cMessage *  msg  )  [protected, virtual]

Handle self messages such as timers.

After the timer expires try to retransmit the message by calling handleUpperMsg again.

Reimplemented from BaseMacLayer.

Definition at line 140 of file CSMAMacLayer.cc.

References backoffTimer, CCA, difs, MacToPhyInterface::getChannelState(), MacToPhyInterface::getRadioState(), ChannelState::isIdle(), macQueue, macState, minorMsg, BaseMacLayer::phy, RX, scheduleBackoff(), MacToPhyInterface::setRadioState(), Radio::TX, and TX.

{
    if(msg == backoffTimer) {
      debugEV << "backoffTimer ";

        if(macState == RX) {
          debugEV << " RX ";

            if(macQueue.size() != 0) {
              macState = CCA;

                if(phy->getRadioState() == Radio::RX) {

                    if(phy->getChannelState().isIdle()) {
                      debugEV << " idle ";
                        scheduleAt(simTime()+difs, minorMsg);
                    }
                    else{
                      macState = RX;
                      debugEV << " busy ";
                        scheduleBackoff();
                    }
                }
            }
        }
        else {
          debugEV << "" << endl;
          debugEV << "state=" << macState << "(TX="<<TX<<", CCA="<<CCA<<")\n";
            error("backoffTimer expired, MAC in wrong state");
        }
    }
    else if(msg == minorMsg) {
      debugEV << " minorMsg ";

        //TODO: replace with channel sense request
        if((macState == CCA) && (phy->getRadioState() == Radio::RX)) {

            if(phy->getChannelState().isIdle()) {
              debugEV << " idle -> to send ";
                macState = TX;
                phy->setRadioState(Radio::TX);
            }
            else {
              debugEV << " busy -> backoff ";
                macState = RX;
                if(!backoffTimer->isScheduled())
                  scheduleBackoff();
            }
        }
        else {
            error("minClearTimer fired -- channel or mac in wrong state");
        }
    }
    debugEV << endl;
}

void CSMAMacLayer::handleUpperMsg ( cMessage *  msg  )  [protected, virtual]

Handle messages from upper layer.

First it has to be checked whether a frame is currently being transmitted or waiting to be transmitted. If so the newly arrived message is stored in a queue. If there is no queue or it is full print a warning.

Before transmitting a frame it is tested whether the channel is busy at the moment or not. If the channel is busy, a short random time will be generated and the MacPkt is buffered for this time, before a next attempt to send the packet is started.

If channel is idle the frame will be transmitted immediately.

Reimplemented from BaseMacLayer.

Definition at line 103 of file CSMAMacLayer.cc.

References backoffTimer, encapsMsg(), macQueue, macState, BaseMacLayer::PACKET_DROPPED, queueLength, RX, scheduleBackoff(), and BaseLayer::sendControlUp().

{
  cPacket* pkt = static_cast<cPacket*>(msg);

    //MacPkt *mac = encapsMsg(pkt);

    // message has to be queued if another message is waiting to be send
    // or if we are already trying to send another message

    if (macQueue.size() <= queueLength)
    {
        macQueue.push_back(pkt);
        debugEV   << "packet putt in queue\n  queue size:" << macQueue.size() << " macState:" << macState
      << " (RX=" << RX << ") is scheduled:" << backoffTimer->isScheduled() << endl;;

        if((macQueue.size() == 1) && (macState == RX) && !backoffTimer->isScheduled()) {
            scheduleBackoff();
        }
    }
    else {
        // queue is full, message has to be deleted
      EV << "New packet arrived, but queue is FULL, so new packet is deleted\n";
        MacPkt* mac = encapsMsg(pkt);
        mac->setName("MAC ERROR");
        mac->setKind(PACKET_DROPPED);
        sendControlUp(mac);

        //TODO: send packet drop bb info
        //droppedPacket.setReason(DroppedPacket::QUEUE);
        //utility->publishBBItem(catDroppedPacket, &droppedPacket, nicId);
    }
}

virtual void CSMAMacLayer::initialize ( int   )  [protected, virtual]

Inspect reasons for dropped packets.

plus category from BBpublish dropped packets nic wideInitialization of the module and some variables

Reimplemented from BaseMacLayer.

void CSMAMacLayer::scheduleBackoff (  )  [protected, virtual]

schedule a backoff

A non-persistent CSMA ideally uses a fixed backoff window, but it could also increase this window in a linear fashion, or even exponential -- here, a linear increase is used. Overwrite this function to define another schedule function. It also checks the retransmission counters -- if you overwrite it, do it with care.

Definition at line 243 of file CSMAMacLayer.cc.

References backoffTimer, backoffValues, encapsMsg(), MacToPhyInterface::getRadioState(), initialCW, macQueue, macState, maxTxAttempts, minorMsg, nbBackoffs, BaseMacLayer::PACKET_DROPPED, BaseMacLayer::phy, BaseLayer::sendControlUp(), slotDuration, and txAttempts.

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

{
    if(backoffTimer->isScheduled()) {
        std::cerr << " is scheduled: MAC state "
                  << macState << " radio state : " << phy->getRadioState() << endl;
    }

    if(minorMsg->isScheduled()){
    cancelEvent( minorMsg );
    macState=RX;
  }

    if(txAttempts > maxTxAttempts) {
      debugEV << " drop packet " << endl;

        cMessage *mac = encapsMsg(macQueue.front());
        mac->setName("MAC ERROR");
        mac->setKind(PACKET_DROPPED);
        txAttempts = 0;
        macQueue.pop_front();
        sendControlUp(mac);

        //TODO: send packet drop bb info
        //droppedPacket.setReason(DroppedPacket::CHANNEL);
        //bb->publishBBItem(catDroppedPacket, &droppedPacket, nicId);
    }

    if(macQueue.size() != 0) {
      debugEV << " schedule backoff " << endl;

        double slots = intrand(initialCW + txAttempts) + 1.0 + dblrand();
        double time = slots * slotDuration;

        txAttempts++;
        debugEV << " attempts so far: " << txAttempts  << " " << endl;

    nbBackoffs = nbBackoffs + 1;
    backoffValues = backoffValues + time;

        scheduleAt(simTime() + time, backoffTimer);
    }

}


Member Data Documentation

double CSMAMacLayer::difs [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 92 of file CSMAMacLayer.h.

Referenced by handleSelfMsg().

unsigned CSMAMacLayer::maxTxAttempts [protected]

maximum number of transmission attempts

The packet is discarded when this number is reached.

Definition at line 123 of file CSMAMacLayer.h.

Referenced by scheduleBackoff().

cMessage* CSMAMacLayer::minorMsg [protected]

Multi-purpose message.

Keeps track of things like minimum time of clear channel (important for atomic acks) and race condition avoidance.

Definition at line 109 of file CSMAMacLayer.h.

Referenced by handleSelfMsg(), and scheduleBackoff().

double CSMAMacLayer::slotDuration [protected]

Duration of a slot.

This duration can be a mini-slot (that is an RX-TX-turnaround time) but in general it should be the time it takes to send a packet plus some guard times (RX-TX-turnaround + a minimum inter-packet space).

Definition at line 85 of file CSMAMacLayer.h.

Referenced by encapsMsg(), and scheduleBackoff().

unsigned CSMAMacLayer::txAttempts [protected]

count the number of tx attempts

This holds the number of transmission attempts, since no Acks are used this is the way how we can empty our queue even with overloaded channels.

Definition at line 117 of file CSMAMacLayer.h.

Referenced by handleLowerControl(), and scheduleBackoff().


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