Generic CSMA Mac-Layer. More...
#include <csma.h>
Inherits BaseMacLayer.
Inherited by CSMA802154.
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 |
Generic CSMA Mac-Layer.
Supports constant, linear and exponential backoffs as well as MAC ACKs.
CSMA Mac-Layer - finite state machine
Definition at line 54 of file csma.h.
enum csma::backoff_methods [protected] |
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; } }
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().