implementation MacLayer on MiXiM

169 views
Skip to first unread message

Kortas Manel

unread,
Apr 13, 2015, 4:32:21 AM4/13/15
to omn...@googlegroups.com
Hello, I have a question please, I want to know if I can implement a simple send-response  of a message on Mac layer only without the use of the network layer in Mixim ???

Thomas Menzel

unread,
Apr 14, 2015, 4:06:26 AM4/14/15
to omn...@googlegroups.com
Yes, that's possible. For traffic generation you then have to choose:
a) still generate at APP, but make it sendDown directly to the MAC
b) generate traffic at MAC

Kortas Manel

unread,
Apr 14, 2015, 6:11:21 AM4/14/15
to omn...@googlegroups.com
How can I make the network layer and application layer not invorved in message manipulation , and generate it directly in mac layer ??
Because now I triying to do the first methode ,bur it would be better if I do the second

--
You received this message because you are subscribed to a topic in the Google Groups "OMNeT++ Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/omnetpp/hZKbNsXM3WE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to omnetpp+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Thomas Menzel

unread,
Apr 14, 2015, 9:08:54 AM4/14/15
to omn...@googlegroups.com
Check how it's done in the APP layer. You can do more or less the same things on the MAC layer as well.

Kortas Manel

unread,
Apr 14, 2015, 9:24:38 AM4/14/15
to omn...@googlegroups.com
Ok , thx Thomas, I have another question if you don't mind , the destination address that i have to put is a LAddress::L2Type address and it 's initialized by a broadcast address , How can I put the address that I want ??? thx again

Thomas Menzel

unread,
Apr 14, 2015, 9:46:00 AM4/14/15
to omn...@googlegroups.com
It should be possible to cast int or at least uint64 to LAddress::L2Type, but at the moment I can't find the function.
However, if you're only interested in one link, you can use the broadcast address and/or ignore the addres when receiving.

Kortas Manel

unread,
Apr 15, 2015, 4:53:01 AM4/15/15
to omn...@googlegroups.com
Good morning Thomas,
On my first quetion, I managed to get traffic directly from the App layer to the mac layer, but when I wanted to try the second method, it did not work, in fact i deleted the heart of the function sendData in the Appl layer, and I created a new message in handlUpperMsg function in mac layer, but in simutaion it does not appear, apparently the program does not know how to go to the mac layer to read the code because  it  didn't execut the function sendDown () in the senData function in the App layer.
help please!!

Thomas Menzel

unread,
Apr 19, 2015, 5:10:32 AM4/19/15
to omn...@googlegroups.com
handlUpperMsg is called when a message arrives from the upper layer. Instead, you have to invoke the message sending by a timer like it is done the 'real' APP layer

Kortas Manel

unread,
Apr 19, 2015, 6:33:42 AM4/19/15
to omn...@googlegroups.com
In that function whén the message arrived from the Appl Layer I delete It and I create  a new one witch well be send , I tried to  do the suggestion that you proposed but it didn't work
you can see my code spetially the function handlUpper Msg :
#include "csmaNew.h"

#include <cassert>

#include "FWMath.h"
#include "BaseDecider.h"
#include "ArpHost.h"
#include "AddressingInterface.h"
#include "BasePhyLayer.h"
#include "SimpleAddress.h"
#include "BaseConnectionManager.h"
#include "BaseWorldUtility.h"
#include "FindModule.h"
#include "MacPkt_m.h"
#include "MACAddress.h"
#include "NetwControlInfo.h"
#include "BaseNetwLayer.h"
#include "NetwToMacControlInfo.h"

Define_Module(csmaNew);

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

void csmaNew::initialize(int stage) {
    BaseMacLayer::initialize(stage);

    if (stage == 0) {
     //   BaseLayer::catPacketSignal.initialize();
        BaseLayer::catDroppedPacketSignal.initialize();

        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");

        initializationTime = par("initializationTime");
        trafficParam = par("trafficParam");

        macAckWaitDuration = par("macAckWaitDuration").doubleValue();
        aUnitBackoffPeriod = par("aUnitBackoffPeriod").doubleValue();
        ccaDetectionTime = par("ccaDetectionTime").doubleValue();
        rxSetupTime = par("rxSetupTime").doubleValue();
        aTurnaroundTime = par("aTurnaroundTime").doubleValue();
        bitrate = par("bitrate");
        ackLength = par("ackLength");
        ackMessage = NULL;
        destAddr= LAddress::L2Type(par("destAddr").longValue());
        macAddr= LAddress::L2Type(par("macAddr").longValue());
        //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 = getNic()->getId();

        // 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(getNic());

        //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",
                            SIMTIME_DBL(aTurnaroundTime), SIMTIME_DBL(rxToTx));
            }

            delayTimer = new cMessage("appDelay", SEND_DATA_TIMER);


        }


    //    BaseWorldUtility*   world = FindModule<BaseWorldUtility*>::findGlobalModule();
    } 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");






                // get pointer to the world module

                debugEV << "in initialize() stage 1...";
                // Application address configuration: equals to host address

    /*            cModule *const pHost = findHost();
                const cModule* netw  = FindModule<BaseNetwLayer*>::findSubModule(pHost);
                if(!netw) {
                    netw = pHost->getSubmodule("netwl");
                    if(!netw) {
                        opp_error("Could not find network layer module. This means "
                                  "either no network layer module is present or the "
                                  "used network layer module does not subclass from "
                                  "BaseNetworkLayer.");
                    }
                }*/
                cModule *const pHost = findHost();
                const AddressingInterface *const addrScheme = FindModule<AddressingInterface*>::findSubModule(pHost);


       scheduleAt(simTime() +uniform(initializationTime, initializationTime + trafficParam), delayTimer);





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

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

void csmaNew::finish() {
    if (stats) {
        recordScalar("nbTxFrames", nbTxFrames);
        recordScalar("nbRxFrames", nbRxFrames);
        recordScalar("nbDroppedFrames", nbDroppedFrames);
        recordScalar("nbMissedAcks", nbMissedAcks);
        recordScalar("nbRecvdAcks", nbRecvdAcks);
        recordScalar("nbTxAcks", nbTxAcks);
        recordScalar("nbDuplicates", nbDuplicates);
        if (nbBackoffs > 0) {
            recordScalar("meanBackoff", backoffValues / nbBackoffs);
        } else {
            recordScalar("meanBackoff", 0);
        }
        recordScalar("nbBackoffs", nbBackoffs);
        recordScalar("backoffDurations", backoffValues);
    }
    BaseMacLayer::finish();
}

csmaNew::~csmaNew() {
    cancelAndDelete(backoffTimer);
    cancelAndDelete(ccaTimer);
    cancelAndDelete(sifsTimer);
    cancelAndDelete(rxAckTimer);
    if (ackMessage)
        delete ackMessage;
    MacQueue::iterator it;
    for (it = macQueue.begin(); it != macQueue.end(); ++it) {
        delete (*it);
    }
}

/**
 * Encapsulates the message to be transmitted and pass it on
 * to the FSM main method for further processing.
 */
cObject* csmaNew::setDownControlInfoNew(cMessage *const pMsg, const LAddress::L2Type& pDestAddr)
{
    return NetwToMacControlInfo::setControlInfo(pMsg, pDestAddr);
}


void csmaNew::handleUpperMsg(cMessage *msg) {
     // //macpkt_ptr_tmacPkt = encapsMsg(msg);
    macpkt_ptr_t macPkt = new MacPkt(msg->getName());
     macPkt->setBitLength(headerLength);

     cObject *const cInfo = msg->removeControlInfo();
    debugEV<<"CSMA received a message from upper layer, name is " << msg->getName() <<", CInfo removed, mac addr="<< getUpperDestinationFromControlInfo(cInfo) << endl;
    LAddress::L2Type dest = getUpperDestinationFromControlInfo(cInfo);
    macPkt->setDestAddr(dest);
   macPkt->setSrcAddr(myMacAddr);

    macpkt_ptr_t macPktOne = new MacPkt("DataCopy");
    cObject *const cInfoo = setDownControlInfoNew(macPktOne, destAddr);
    LAddress::L2Type destfinal = getUpperDestinationFromControlInfo(cInfo);

    macPktOne->setBitLength(headerLength);
        macPktOne ->setSrcAddr(myMacAddr);
        macPktOne->setDestAddr(destfinal);
  debugEV<<"CSMA generate a message in mac layer, name is " << macPktOne->getName() <<", CInfo removed, mac addr="<< destfinal<< endl;

    delete cInfo;
   delete macPkt;



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

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

    //  scheduleAt(simTime() +uniform(0, trafficParam), delayTimer);

}

void csmaNew::updateStatusIdle(t_mac_event event, cMessage *msg) {
    switch (event) {
    case EV_SEND_REQUEST:
        if (macQueue.size() <= queueLength) {
            macQueue.push_back(static_cast<macpkt_ptr_t> (msg));
            debugEV<<"(1) FSM State IDLE_1, EV_SEND_REQUEST and [TxBuff avail]: startTimerBackOff -> BACKOFF." << endl;
            updateMacState(BACKOFF_2);
            NB = 0;
            //BE = macMinBE;
            startTimer(TIMER_BACKOFF);
        } else {
            // queue is full, message has to be deleted
            debugEV << "(12) FSM State IDLE_1, EV_SEND_REQUEST and [TxBuff not avail]: dropping packet -> IDLE." << endl;
            msg->setName("MAC ERROR");
            msg->setKind(PACKET_DROPPED);
            sendControlUp(msg);
            droppedPacket.setReason(DroppedPacket::QUEUE);
            emit(BaseLayer::catDroppedPacketSignal, &droppedPacket);
            updateMacState(IDLE_1);
        }
        break;
    case EV_DUPLICATE_RECEIVED:
        debugEV << "(15) FSM State IDLE_1, EV_DUPLICATE_RECEIVED: setting up radio tx -> WAITSIFS." << endl;
        //sendUp(decapsMsg(static_cast<MacSeqPkt *>(msg)));
        delete msg;
        //if(useMACAcks) {
            phy->setRadioState(MiximRadio::TX);
            updateMacState(WAITSIFS_6);
            startTimer(TIMER_SIFS);
        //}
        break;

    case EV_FRAME_RECEIVED:
        debugEV << "(15) FSM State IDLE_1, EV_FRAME_RECEIVED: setting up radio tx -> WAITSIFS." << endl;
        sendUp(decapsMsg(static_cast<macpkt_ptr_t>(msg)));
        nbRxFrames++;
        delete msg;

    //    if(useMACAcks) {
            phy->setRadioState(MiximRadio::TX);
            updateMacState(WAITSIFS_6);
            startTimer(TIMER_SIFS);
    //    }
        break;

    //case EV_BROADCAST_RECEIVED:
        //debugEV << "(23) FSM State IDLE_1, EV_BROADCAST_RECEIVED: Nothing to do." << endl;
        //nbRxFrames++;
        //sendUp(decapsMsg(static_cast<macpkt_ptr_t>(msg)));
    //    delete msg;
    //    break;
    default:
        fsmError(event, msg);
        break;
    }
}

void csmaNew::updateStatusBackoff(t_mac_event event, cMessage *msg) {
    switch (event) {
    case EV_TIMER_BACKOFF:
        debugEV<< "(2) FSM State BACKOFF, EV_TIMER_BACKOFF:"
        << " starting CCA timer." << endl;
        startTimer(TIMER_CCA);
        updateMacState(CCA_3);
        phy->setRadioState(MiximRadio::RX);
        break;
    case EV_DUPLICATE_RECEIVED:
        // suspend current transmission attempt,
        // transmit ack,
        // and resume transmission when entering manageQueue()
        debugEV << "(28) FSM State BACKOFF, EV_DUPLICATE_RECEIVED:";
        if(useMACAcks) {
            debugEV << "suspending current transmit tentative and transmitting ack";
            transmissionAttemptInterruptedByRx = true;
            cancelEvent(backoffTimer);
            phy->setRadioState(MiximRadio::TX);
            updateMacState(WAITSIFS_6);
            startTimer(TIMER_SIFS);
        } else {
            debugEV << "Nothing to do.";
        }
        //sendUp(decapsMsgmsg->getName()(static_cast<MacSeqPkt *>(msg)));
        delete msg;

        break;
    case EV_FRAME_RECEIVED:
        // suspend current transmission attempt,
        // transmit ack,
        // and resume transmission when entering manageQueue()
        debugEV << "(28) FSM State BACKOFF, EV_FRAME_RECEIVED:";
        if(useMACAcks) {
            debugEV << "suspending current transmit tentative and transmitting ack";
            transmissionAttemptInterruptedByRx = true;
            cancelEvent(backoffTimer);

            phy->setRadioState(MiximRadio::TX);
            updateMacState(WAITSIFS_6);
            startTimer(TIMER_SIFS);
        } else {
            debugEV << "sending frame up and resuming normal operation.";
        }
        sendUp(decapsMsg(static_cast<macpkt_ptr_t>(msg)));
        delete msg;
        break;
    //case EV_BROADCAST_RECEIVED:
    //    debugEV << "(29) FSM State BACKOFF, EV_BROADCAST_RECEIVED:"
    ///    << "sending frame up and resuming normal operation." <<endl;
        //sendUp(decapsMsg(static_cast<macpkt_ptr_t>(msg)));
    //    delete msg;
    //    break;
    default:
        fsmError(event, msg);
        break;
    }
}

void csmaNew::attachSignal(macpkt_ptr_t mac, simtime_t_cref startTime) {
    simtime_t duration = (mac->getBitLength() + phyHeaderLength)/bitrate;
    setDownControlInfo(mac, createSignal(startTime, duration, txPower, bitrate));
}

void csmaNew::updateStatusCCA(t_mac_event event, cMessage *msg) {
    switch (event) {
    case EV_TIMER_CCA:
    {
        debugEV<< "(25) FSM State CCA_3, EV_TIMER_CCA" << endl;
        bool isIdle = phy->getChannelState().isIdle();
        if(isIdle) {
            debugEV << "(3) FSM State CCA_3, EV_TIMER_CCA, [Channel Idle]: -> TRANSMITFRAME_4." << endl;
            updateMacState(TRANSMITFRAME_4);
            phy->setRadioState(MiximRadio::TX);
            macpkt_ptr_t mac = check_and_cast<macpkt_ptr_t>(macQueue.front()->dup());
            attachSignal(mac, simTime()+aTurnaroundTime);
            //sendDown(msg);
            // give time for the radio to be in Tx state before transmitting
            sendDelayed(mac, aTurnaroundTime, lowerLayerOut);
            nbTxFrames++;
        } else {
            // Channel was busy, increment 802.15.4 backoff timers as specified.
            debugEV << "(7) FSM State CCA_3, EV_TIMER_CCA, [Channel Busy]: "
            << " increment counters." << endl;
            NB = NB+1;
            //BE = std::min(BE+1, macMaxBE);

            // decide if we go for another backoff or if we drop the frame.
            if(NB> macMaxCSMABackoffs) {
                // drop the frame
                debugEV << "Tried " << NB << " backoffs, all reported a busy "
                << "channel. Dropping the packet." << endl;
                cMessage * mac = macQueue.front();
                macQueue.pop_front();
                txAttempts = 0;
                nbDroppedFrames++;
                mac->setName("MAC ERROR");
                mac->setKind(PACKET_DROPPED);
                sendControlUp(mac);
                manageQueue();
            } else {
                // redo backoff
                updateMacState(BACKOFF_2);
                startTimer(TIMER_BACKOFF);
            }
        }
        break;
    }
    case EV_DUPLICATE_RECEIVED:
        debugEV << "(26) FSM State CCA_3, EV_DUPLICATE_RECEIVED:";
        if(useMACAcks) {
            debugEV << " setting up radio tx -> WAITSIFS." << endl;
            // suspend current transmission attempt,
            // transmit ack,
            // and resume transmission when entering manageQueue()
            transmissionAttemptInterruptedByRx = true;
            cancelEvent(ccaTimer);

            phy->setRadioState(MiximRadio::TX);
            updateMacState(WAITSIFS_6);
            startTimer(TIMER_SIFS);
        } else {
            debugEV << " Nothing to do." << endl;
        }
        //sendUp(decapsMsg(static_cast<macpkt_ptr_t>(msg)));
        delete msg;
        break;

    case EV_FRAME_RECEIVED:
        debugEV << "(26) FSM State CCA_3, EV_FRAME_RECEIVED:";
        if(useMACAcks) {
            debugEV << " setting up radio tx -> WAITSIFS." << endl;
            // suspend current transmission attempt,
            // transmit ack,
            // and resume transmission when entering manageQueue()
            transmissionAttemptInterruptedByRx = true;
            cancelEvent(ccaTimer);
            phy->setRadioState(MiximRadio::TX);
            updateMacState(WAITSIFS_6);
            startTimer(TIMER_SIFS);
        } else {
            debugEV << " Nothing to do." << endl;
        }
        sendUp(decapsMsg(static_cast<macpkt_ptr_t>(msg)));
        delete msg;
        break;
    //case EV_BROADCAST_RECEIVED:
    //    debugEV << "(24) FSM State BACKOFF, EV_BROADCAST_RECEIVED:"
    //    << " Nothing to do." << endl;
    ////    sendUp(decapsMsg(static_cast<macpkt_ptr_t>(msg)));
    //    delete msg;
    //    break;
    default:
        fsmError(event, msg);
        break;
    }
}

void csmaNew::updateStatusTransmitFrame(t_mac_event event, cMessage *msg) {
    if (event == EV_FRAME_TRANSMITTED) {
        //    delete msg;
        macpkt_ptr_t packet = macQueue.front();
        phy->setRadioState(MiximRadio::RX);

        bool expectAck = useMACAcks;
        //if (!LAddress::isL2Broadcast(packet->getDestAddr())) {
            //unicast
        //packet->getDestAddr();
            debugEV << "(4) FSM State TRANSMITFRAME_4, "
               << "EV_FRAME_TRANSMITTED [Unicast]: ";
        //} else {
            //broadcast
        //    debugEV << "(27) FSM State TRANSMITFRAME_4, EV_FRAME_TRANSMITTED "
            //   << " [Broadcast]";
            //expectAck = false;
            //}

        if(expectAck) {
            debugEV << "RadioSetupRx -> WAITACK." << endl;
            updateMacState(WAITACK_5);
            startTimer(TIMER_RX_ACK);
        } else {
            debugEV << ": RadioSetupRx, manageQueue..." << endl;
            macQueue.pop_front();
            delete packet;
            manageQueue();
        }
    } else {
        fsmError(event, msg);
    }
}

void csmaNew::updateStatusWaitAck(t_mac_event event, cMessage *msg) {
    assert(useMACAcks);

    cMessage * mac;
    switch (event) {
    case EV_ACK_RECEIVED:
        debugEV<< "(5) FSM State WAITACK_5, EV_ACK_RECEIVED: "
        << " ProcessAck, manageQueue..." << endl;
        if(rxAckTimer->isScheduled())
        cancelEvent(rxAckTimer);
        mac = static_cast<cMessage *>(macQueue.front());
        macQueue.pop_front();
        txAttempts = 0;
        mac->setName("MAC SUCCESS");
        mac->setKind(TX_OVER);
        sendControlUp(mac);
        delete msg;
        manageQueue();
        break;
    case EV_ACK_TIMEOUT:
        debugEV << "(12) FSM State WAITACK_5, EV_ACK_TIMEOUT:"
        << " incrementCounter/dropPacket, manageQueue..." << endl;
        manageMissingAck(event, msg);
        break;
    //case EV_BROADCAST_RECEIVED:
    case EV_FRAME_RECEIVED:
        sendUp(decapsMsg(static_cast<macpkt_ptr_t>(msg)));
        break;
    case EV_DUPLICATE_RECEIVED:
        debugEV << "Error ! Received a frame during SIFS !" << endl;
        delete msg;
        break;
    default:
        fsmError(event, msg);
        break;
    }

}

void csmaNew::manageMissingAck(t_mac_event /*event*/, cMessage */*msg*/) {
    if (txAttempts < macMaxFrameRetries + 1) {
        // increment counter
        txAttempts++;
        debugEV<< "I will retransmit this packet (I already tried "
        << txAttempts << " times)." << endl;
    } else {
        // drop packet
        debugEV << "Packet was transmitted " << txAttempts
        << " times and I never got an Ack. I drop the packet." << endl;
        cMessage * mac = macQueue.front();
        macQueue.pop_front();
        txAttempts = 0;
        mac->setName("MAC ERROR");
        mac->setKind(PACKET_DROPPED);
        sendControlUp(mac);
    }
    manageQueue();
}
void csmaNew::updateStatusSIFS(t_mac_event event, cMessage *msg) {
    assert(useMACAcks);

    switch (event) {
    case EV_TIMER_SIFS:
        debugEV<< "(17) FSM State WAITSIFS_6, EV_TIMER_SIFS:"
        << " sendAck -> TRANSMITACK." << endl;
        updateMacState(TRANSMITACK_7);
        attachSignal(ackMessage, simTime());
        sendDown(ackMessage);
        nbTxAcks++;
        //        sendDelayed(ackMessage, aTurnaroundTime, lowerLayerOut);
        ackMessage = NULL;
        break;
    case EV_TIMER_BACKOFF:
        // Backoff timer has expired while receiving a frame. Restart it
        // and stay here.
        debugEV << "(16) FSM State WAITSIFS_6, EV_TIMER_BACKOFF. "
        << "Restart backoff timer and don't move." << endl;
        startTimer(TIMER_BACKOFF);
        break;
    //case EV_BROADCAST_RECEIVED:
    case EV_FRAME_RECEIVED:
        EV << "Error ! Received a frame during SIFS !" << endl;
        sendUp(decapsMsg(static_cast<macpkt_ptr_t>(msg)));
        delete msg;
        break;
    default:
        fsmError(event, msg);
        break;
    }
}

void csmaNew::updateStatusTransmitAck(t_mac_event event, cMessage *msg) {
    assert(useMACAcks);

    if (event == EV_FRAME_TRANSMITTED) {
        debugEV<< "(19) FSM State TRANSMITACK_7, EV_FRAME_TRANSMITTED:"
        << " ->manageQueue." << endl;
        phy->setRadioState(MiximRadio::RX);
        //        delete msg;
        manageQueue();
    } else {
        fsmError(event, msg);
    }
}

void csmaNew::updateStatusNotIdle(cMessage *msg) {
    debugEV<< "(20) FSM State NOT IDLE, EV_SEND_REQUEST. Is a TxBuffer available ?" << endl;
    if (macQueue.size() <= queueLength) {
        macQueue.push_back(static_cast<macpkt_ptr_t>(msg));
        debugEV << "(21) FSM State NOT IDLE, EV_SEND_REQUEST"
        <<" and [TxBuff avail]: enqueue packet and don't move." << endl;
    } else {
        // queue is full, message has to be deleted
        debugEV << "(22) FSM State NOT IDLE, EV_SEND_REQUEST"
        << " and [TxBuff not avail]: dropping packet and don't move."
        << endl;
        msg->setName("MAC ERROR");
        msg->setKind(PACKET_DROPPED);
        sendControlUp(msg);
        droppedPacket.setReason(DroppedPacket::QUEUE);
        emit(BaseLayer::catDroppedPacketSignal, &droppedPacket);
    }

}
/**
 * Updates state machine.
 */
void csmaNew::executeMac(t_mac_event event, cMessage *msg) {
    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;
            break;
        }
    }
}

void csmaNew::manageQueue() {
    if (macQueue.size() != 0) {
        debugEV<< "(manageQueue) there are " << macQueue.size() << " packets to send, entering backoff wait state." << endl;
        if( transmissionAttemptInterruptedByRx) {
            // resume a transmission cycle which was interrupted by
            // a frame reception during CCA check
            transmissionAttemptInterruptedByRx = false;
        } else {
            // initialize counters if we start a new transmission
            // cycle from zero
            NB = 0;
            //BE = macMinBE;
        }
        if(! backoffTimer->isScheduled()) {
          startTimer(TIMER_BACKOFF);
        }
        updateMacState(BACKOFF_2);
    } else {
        debugEV << "(manageQueue) no packets to send, entering IDLE state." << endl;
        updateMacState(IDLE_1);
    }
}

void csmaNew::updateMacState(t_mac_states newMacState) {
    macState = newMacState;
}

/*
 * Called by the FSM machine when an unknown transition is requested.
 */
void csmaNew::fsmError(t_mac_event event, cMessage *msg) {
    EV<< "FSM Error ! In state " << macState << ", received unknown event:" << event << "." << endl;
    if (msg != NULL)
    delete msg;
}

void csmaNew::startTimer(t_mac_timer timer) {
    if (timer == TIMER_BACKOFF) {
        scheduleAt(scheduleBackoff(), backoffTimer);
    } else if (timer == TIMER_CCA) {
        simtime_t ccaTime = rxSetupTime + ccaDetectionTime;
        debugEV<< "(startTimer) ccaTimer value=" << ccaTime
        << "(rxSetupTime,ccaDetectionTime:" << rxSetupTime
        << "," << ccaDetectionTime <<")." << endl;
        scheduleAt(simTime()+rxSetupTime+ccaDetectionTime, ccaTimer);
    } else if (timer==TIMER_SIFS) {
        assert(useMACAcks);
        debugEV << "(startTimer) sifsTimer value=" << sifs << endl;
        scheduleAt(simTime()+sifs, sifsTimer);
    } else if (timer==TIMER_RX_ACK) {
        assert(useMACAcks);
        debugEV << "(startTimer) rxAckTimer value=" << macAckWaitDuration << endl;
        scheduleAt(simTime()+macAckWaitDuration, rxAckTimer);
    } else {
        EV << "Unknown timer requested to start:" << timer << endl;
    }
}

simtime_t csmaNew::scheduleBackoff() {

    simtime_t backoffTime;

    switch(backoffMethod) {
    case EXPONENTIAL:
    {
        int BE = std::min(macMinBE + NB, macMaxBE);
        int v = (1 << BE) - 1;
        int r = intuniform(0, v, 0);
        backoffTime = r * aUnitBackoffPeriod;

        debugEV<< "(startTimer) backoffTimer value=" << backoffTime
        << " (BE=" << BE << ", 2^BE-1= " << v << "r="
        << r << ")" << endl;
        break;
    }
    case LINEAR:
    {
        int slots = intuniform(1, initialCW + NB, 0);
        backoffTime = slots * aUnitBackoffPeriod;
        debugEV<< "(startTimer) backoffTimer value=" << backoffTime << endl;
        break;
    }
    case CONSTANT:
    {
        int slots = intuniform(1, initialCW, 0);
        backoffTime = slots * aUnitBackoffPeriod;
        debugEV<< "(startTimer) backoffTimer value=" << backoffTime << endl;
        break;
    }
    default:
        error("Unknown backoff method!");
        break;
    }

    nbBackoffs = nbBackoffs + 1;
    backoffValues = backoffValues + SIMTIME_DBL(backoffTime);

    return backoffTime + simTime();
}

/*
 * Binds timers to events and executes FSM.
 */
void csmaNew::handleSelfMsg(cMessage *msg) {
    debugEV<< "timer routine." << endl;
    if(msg==backoffTimer)
        executeMac(EV_TIMER_BACKOFF, msg);
    else if(msg==ccaTimer)
        executeMac(EV_TIMER_CCA, msg);
    else if(msg==sifsTimer)
        executeMac(EV_TIMER_SIFS, msg);
    else if(msg==rxAckTimer) {
        nbMissedAcks++;
        executeMac(EV_ACK_TIMEOUT, msg);
    } else
        EV << "CSMA Error: unknown timer fired:" << msg << endl;
}

/**
 * Compares the address of this Host with the destination address in
 * frame. Generates the corresponding event.
 */
void csmaNew::handleLowerMsg(cMessage *msg) {
    macpkt_ptr_t            macPkt     = static_cast<macpkt_ptr_t> (msg);
    const LAddress::L2Type& src        = macPkt->getSrcAddr();
    const LAddress::L2Type& dest       = macPkt->getDestAddr();
    long  ExpectedNr = 0;

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

    if(strcmp(macPkt->getName(), "CSMA-Ack") != 0){
        nbRxFrames++;
        if(ackMessage != NULL)
            delete ackMessage;
    ackMessage = new MacPkt("CSMA-Ack");
                    ackMessage->setSrcAddr(myMacAddr);
                    ackMessage->setDestAddr(src);
                    ackMessage->setBitLength(ackLength);
                    EV << "ack" <<  endl;
                    assert(static_cast<cPacket*>(msg));
                    ackMessage->encapsulate(static_cast<cPacket*>(msg));
                     debugEV <<"pkt encapsulated, length: " << ackMessage->getBitLength() << "\n";
                    //sendDown(ackMessage);
                    phy->setRadioState(MiximRadio::TX);
                    updateStatusSIFS(EV_TIMER_SIFS, ackMessage);

    }

                //executeMac(EV_SEND_REQUEST, ackMessage);

    /*if(dest == myMacAddr)
    {
            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(src);
                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_ptr_t firstPacket = static_cast<macpkt_ptr_t>(macQueue.front());
                if(src == firstPacket->getDestAddr()) {
                    nbRecvdAcks++;
                    executeMac(EV_ACK_RECEIVED, macPkt);
                } else {
                    EV << "Error! Received an ack from an unexpected source: src=" << src << ", I was expecting from node addr=" << firstPacket->getDestAddr() << endl;
                    delete macPkt;
                }
            } else {
                EV << "Error! Received an Ack while my send queue was empty. src=" << src << "." << endl;
                delete macPkt;
            }
        }
//    }

    else {
        debugEV << "packet not for me, deleting...\n";
        delete macPkt;
    }*/
}

void csmaNew::handleLowerControl(cMessage *msg) {
    if (msg->getKind() == MacToPhyInterface::TX_OVER) {
        executeMac(EV_FRAME_TRANSMITTED, msg);
    } else if (msg->getKind() == BaseDecider::PACKET_DROPPED) {
        debugEV<< "control message: PACKED DROPPED" << endl;
    } else if (msg->getKind() == MacToPhyInterface::RADIO_SWITCHING_OVER) {
        debugEV<< "control message: RADIO_SWITCHING_OVER" << endl;
    } else {
        EV << "Invalid control message type (type=NOTHING) : name="
        << msg->getName() << " modulesrc="
        << msg->getSenderModule()->getFullPath()
        << "." << endl;
    }
    delete msg;
}

cPacket *csmaNew::decapsMsg(macpkt_ptr_t macPkt) {
    cPacket * msg = macPkt->decapsulate();
    setUpControlInfo(msg, macPkt->getSrcAddr());

    return msg;
}




please help!!
 

Thomas Menzel

unread,
Apr 20, 2015, 4:43:56 AM4/20/15
to omn...@googlegroups.com
I assumed you wanted to omit the APP layer...
However, have you tried using a running project from the examples and modify it step-by-step according to your needs?
...

Kortas Manel

unread,
Apr 20, 2015, 4:59:49 AM4/20/15
to omn...@googlegroups.com
yes that's exactly what i want to do.
No I created a new project in witch I chosed
Appl llayer : SensorApplLayer
Net layer : flooding
Nic : Csma generic
Then I modified them

--

Thomas Menzel

unread,
Apr 20, 2015, 5:04:15 AM4/20/15
to omn...@googlegroups.com
OK, and what's your final goal? You want to get rid of the APP and the NET layer an have packets exchanged only on the MAC?
...

Kortas Manel

unread,
Apr 20, 2015, 5:12:06 AM4/20/15
to omn...@googlegroups.com
Yes , that's what I'm supposed to do , and I have to define the destination address because it's broadcast

--

Thomas Menzel

unread,
Apr 20, 2015, 5:21:19 AM4/20/15
to omn...@googlegroups.com
OK, then take the running example, disable the timer in the APP and reimplement the same kind of the timer in the MAC layer in order to have your packets generated here. For the moment, stay with the BC address. You can switch to unicast once everything else is working.
...

Kortas Manel

unread,
Apr 20, 2015, 5:28:50 AM4/20/15
to omn...@googlegroups.com
You mean this by the timer ? :


delayTimer = new cMessage("appDelay", SEND_DATA_TIMER);
    scheduleAt(simTime() +uniform(initializationTime, initializationTime + trafficParam), delayTimer);

--

Thomas Menzel

unread,
Apr 20, 2015, 5:35:56 AM4/20/15
to omn...@googlegroups.com
Yes.
...

Kortas Manel

unread,
Apr 20, 2015, 5:20:34 PM4/20/15
to omn...@googlegroups.com
Hello, thx Thomas for the information , it works , but I still have a problem , I created a new function generateMsg() in witch I generate the message that will be sent , the problem that the generation of the message is made in the physical layer not in the mac layer , I thing that's related to encapsulate function I tried many touse it but I didn't suceed, please help, that's my function :
void csmaNew::generateMsg(){

  //  netwpkt_ptr_t msg = new netwpkt_t("DataCopy",DATA);
  //  msg->setDestAddr(LAddress::L3BROADCAST);

   // msg->setSeqNum(0);
  //  msg->setTtl(0);
 //   macpkt_ptr_t macPktOne = new MacPkt(msg->getName(),msg->getKind());
    EV<<"debut de création creation de message"<<endl;
    macpkt_ptr_t macPktOne = new MacPkt("DataCopy",DATA);
    EV<<"fin de création creation de message"<<endl;

       macPktOne->setBitLength(headerLength);
           macPktOne ->setSrcAddr(myMacAddr);
           macPktOne->setDestAddr(destAddr);

           //assert(static_cast<cPacket*>(msg));
             // macPktOne->encapsulate(static_cast<cPacket*>(msg));
           executeMac(EV_SEND_REQUEST, macPktOne);

    scheduleNextmacPkt();

  // scheduleAt(simTime() +uniform(0, trafficParam), delayTimer);

}

--

Thomas Menzel

unread,
Apr 21, 2015, 10:22:54 AM4/21/15
to omn...@googlegroups.com
What exactly fails? 
And are you sure it's really needed to create the messages down here?
...
Reply all
Reply to author
Forward
0 new messages