Search code examples
c++omnet++

handleMessage(* msg) doesn't work in OMNET++


I have a wireless network consisting of 7 sensors named node1 to 7, and a gateway. each node and also gateway has an inport which is marked by @directIo. The flow of data is in the way that, the gateway chooses one of the nodes as the cluster head and send a message containing the id number of the chosen cluster head to the nodes using sendDirect(), the problem is that, the node's handleMessage() event isn't called at all.

#include <stdio.h>
#include <string.h>
#include <omnetpp.h>


using namespace omnetpp;

class node : public cSimpleModule
{
private:
    float propagationDelay;
    float duration;
    double eLevel;
    float dist;
    int mCount;
    int clusterHead;
    cModule *target;
    cMessage *timerMessage;
    cMessage *pack;
    cMessage *weak;
    cMessage *msg;
    bool gReq;
  protected:
    virtual void initialize() override;
    virtual void handleMessage(cMessage *msg) override;
};

Define_Module(node);

void node::initialize()
{
    gReq=false;
    eLevel=par("energyLeve");
    mCount=0;
    dist=(rand()%3)+1;
    timerMessage = new cMessage("timer");
    /*if (par("sendMsgOnInit").boolValue() == true) {
       EV << getName()<<getIndex() << "------ distance: " << dist << "\n";
    }*/
}

void node::handleMessage(cMessage *msg)
{
    if (msg->getSenderModuleId()==2){
            clusterHead=atoi((char *) msg->getName());
            if (getId()!=clusterHead){
                pack= new cMessage("Hello");
                timerMessage =new cMessage("Timer");
                mCount=0;
                target = getSimulation()->getModule(clusterHead);
                sendDirect(pack, propagationDelay, duration, target, "radioIn");
                eLevel-=dist;
                if (eLevel<50 && gReq==false){
                    weak= new cMessage("w");
                    target = getSimulation()->getModule(2);
                    sendDirect(weak, propagationDelay, duration, target, "radioIn");
                    gReq=true;
                    EV << "node index: "<< getIndex() << "request sent!";
                }
                EV << getName()<<getIndex() << "------ eLevel: " << eLevel;
                scheduleAt(simTime()+0.1, timerMessage);
            }
        }

}

Code 2

#include <stdio.h>
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;


class gateway : public cSimpleModule
{
  public:
    int mCount;
    cMessage *clusterNodeSelecMess;
    cMessage *timerMessage;
    cMessage *msg;
    int round;
    int clusterHeadId;
    bool weakNodes[7];
    int inx;
  protected:
    int clusterHeadSelection(bool weakNodes[7]);
    virtual void initialize() override;
    virtual void handleMessage(cMessage *msg) override;
};
Define_Module(gateway);

void gateway::initialize()
{
    msg= new cMessage("self");
    scheduleAt(0.0, msg);
    round =0;
    for (int i = 0; i < 7; ++i) {
            weakNodes[i]=false;
        }
}

void gateway::handleMessage(cMessage *msg)
{
    if(msg->getSenderModuleId()==2){
        round++;
        clusterHeadId=clusterHeadSelection(weakNodes);
        std::string s = std::to_string(clusterHeadId);
        EV << "Node number "<<clusterHeadId << " selected as CH\n";
        char const *pchar = s.c_str();
        clusterNodeSelecMess = new cMessage(pchar);
            for (cModule::SubmoduleIterator it(getModuleByPath("FTN")); !it.end(); ++it) {
                    cModule *temp = *it;
                    if (strcmp(temp->getName(),getName())!=0){
                        sendDirect(clusterNodeSelecMess->dup(), temp, "radioIn");
                    }
                }
    }
    else if(msg->getSenderModuleId()==clusterHeadId){
        clusterHeadId=clusterHeadSelection(weakNodes);
        std::string s = std::to_string(clusterHeadId);
        EV << "Node number "<<clusterHeadId << " selected as CH\n";
        char const *pchar = s.c_str();
        clusterNodeSelecMess = new cMessage(pchar);
        for (cModule::SubmoduleIterator it(getModuleByPath("FTN")); !it.end(); ++it) {
            cModule *temp = *it;
            sendDirect(clusterNodeSelecMess->dup(), temp, "radioIn");
         }
    }
    else{
        EV << "Received from node: "<< msg->getSenderGateId() - 1 << "\n";
    }
}

int clusterHeadSelection(bool weakNodes[7]){
        int i = 0;
        int clusterHeadId;
        while(weakNodes[clusterHeadId=(rand() % 12)-2]==true){
                    i++;
                    if (i>7){
                        return(NULL);
                    }
                }
        return(clusterHeadId);
}

Solution

  • The handleMessage() method is never called by the simulator because you never send a message to any of your modules so there is nothing to deliver. Note that sendDirect() calls are only present in your handleMessage() methods, so until one of them is called, there will be no messages to deliver. The way a simulation should work is that SOME code MUST create messages or events (e.g. timers) in the initialize() methods because that is the method that is called on the simulation start.

    In node::initialize() you create a timerMessage but never schedule it so it is not delivered to handleMessage(). (not that it would help because the handleMessage() code would explicitly ignore it):

    The gateway module creates and schedules a self message, and that is delivered to the gateway::handleMessage() but it's not handled and most likely falls through to the else case at the end and then just does nothing.