Self-message tutorial, please Help!

855 views
Skip to first unread message

Марина Котова

unread,
Apr 6, 2017, 10:21:01 AM4/6/17
to OMNeT++ Users
Hello, I'm new in Omnet, I hope, that you can help me!
 I've already done Omnet tutorial and I want to combine two lessons "Step 6: Modeling processing delay" and "Step 13: Defining message class", but i can't do it. I just want to have a delay via self message
I suppose, I can't do this because of adding a new message class. Here is my code:
#include <stdio.h>

#include <string.h>

#include <omnetpp.h>



using namespace omnetpp;



// Include a generated file: the header file created from tictoc13.msg.

// It contains the definition of the TictocMsg10 class, derived from

// cMessage.

#include "tictoc13_m.h"



class Txc13 : public cSimpleModule

{
private:

   cMessage *event;  // pointer to the event object which we'll use for timing

   TicTocMsg13 *buf;  // variable to remember the message until we send it back


public:

  Txc13();

  virtual ~Txc13();


  protected:

    virtual TicTocMsg13 *generateMessage();

    virtual void forwardMessage(TicTocMsg13 *msg);

    virtual void initialize() override;

    virtual void handleMessage(cMessage *msg) override;

};



Define_Module(Txc13);

Txc13::Txc13()

{


    event = buf = nullptr;

}

Txc13::~Txc13()

{

    cancelAndDelete(event);

    delete buf;

}



void Txc13::initialize()

{
    event = new cMessage("event");
    buf = nullptr;
    // Module 0 sends the first message

    if (getIndex() == 0) {

        // Boot the process scheduling the initial message as a self-message.

        TicTocMsg13 *msg = generateMessage();
        buf=msg;
        scheduleAt(5.0, event);

    }

}



void Txc13::handleMessage(cMessage *msg)

{

    if (msg->isSelfMessage()){
        TicTocMsg13 *ttmsg = check_and_cast<TicTocMsg13 *>(msg);



    if (ttmsg->getDestination() == getIndex()) {

        // Message arrived.

        EV << "Message " << ttmsg << " arrived after " << ttmsg->getHopCount() << " hops.\n";

        bubble("ARRIVED, starting new one!");

        delete ttmsg;



        // Generate another one.

        EV << "Generating another message: ";

        TicTocMsg13 *newmsg = generateMessage();

        EV << newmsg << endl;

        forwardMessage(newmsg);

    }

    else {

        // We need to forward the message.

        forwardMessage(ttmsg);

    }

}
    else {
    buf = check_and_cast<TicTocMsg13 *>(msg);
    scheduleAt(simTime()+1.0, event);
    }
}



TicTocMsg13 *Txc13::generateMessage()

{

    // Produce source and destination addresses.

    int src = getIndex();  // our module index

    int n = getVectorSize();  // module vector size

    int dest = intuniform(0, n-2);

    if (dest >= src)

        dest++;



    char msgname[20];

    sprintf(msgname, "Hi? Ilnur, it's a tic-%d-to-%d", src, dest);



    // Create message object and set source and destination field.

    TicTocMsg13 *msg = new TicTocMsg13(msgname);

    msg->setSource(src);

    msg->setDestination(dest);

    return msg;

}



void Txc13::forwardMessage(TicTocMsg13 *msg)

{

    // Increment hop count.

    msg->setHopCount(msg->getHopCount()+1);



    // Same routing as before: random gate.

    int n = gateSize("gate");

    int k = intuniform(0, n-1);



    EV << "Forwarding message " << msg << " on gate[" << k << "]\n";

    send(msg, "gate$o", k);

}


When I run this, I get error: "check and cast (): cannot cast (omnetpp::cMessage*) event to type TicToc13Msg"
I repeat, that I just want to realise delay via self message in programm which have message class. 
I hope, that you can help me with that problem, thanks.
Best regards, Maria
omn.png

Michael Kirsche

unread,
Apr 6, 2017, 11:53:36 AM4/6/17
to OMNeT++ Users
Why do you check_and_cast your own self message into the TicTocMsg13? This is obviously wrong...

From a quick glance at your code, you are also mixing the treatment of self-messages with the forwarding of packets.
When a self-message arrives, you can check if its a self-message just like you did with (msg->isSelfMessage), but afterwards you want to check if the selfMessage has reached its destination? Clearly you mean to check if a normal message has reached its destination, not the timer message, which is always scheduled and send inside a module.

Second, you do not need to generate selfMessages of the TicTocMsg13 type, just a plain cMessage and schedule this...

What you need to do is generate a TicTocMsg13 maybe during the initialize and whenever a timer runs out.

Attached is the slightly restructured example code.

#include <stdio.h>

#include <string.h>

#include <omnetpp.h>

// Include a generated file: the header file created from tictoc13.msg.

// It contains the definition of the TictocMsg10 class, derived from

// cMessage.

#include "tictoc13_m.h"

class Txc13 : public cSimpleModule
{
   
private:

        cMessage
*event;  // pointer to the event object which we'll use for timing

       
TicTocMsg13 *buf;  // variable to remember the message until we send it back

   
public:

       
Txc13();

       
virtual ~Txc13();

   
protected:

       
virtual TicTocMsg13 *generateMessage();

       
virtual void forwardMessage(TicTocMsg13 *msg);

       
virtual void initialize() override;

       
virtual void handleMessage(cMessage *msg) override;

};

Define_Module(Txc13);

Txc13::Txc13()

{

   
event = buf = nullptr;

}

Txc13::~Txc13()

{

    cancelAndDelete
(event);

   
delete buf;

}

void Txc13::initialize()

{
   
event = new cMessage("event");

   
// Module 0 sends the first message
   
if (getIndex() == 0)
   
{
       
// Boot the process scheduling the initial message as a self-message.

        scheduleAt
(5.0, event);
   
}

}

void Txc13::handleMessage(cMessage *msg)

{
   
if (msg->isSelfMessage())
   
{

        scheduleAt
(simTime() + 1.0, msg);
       
TicTocMsg13 *newmsg = generateMessage();
        EV
<< "Generating a new message and forwarding it" << endl;
        forwardMessage
(newmsg);
   
}
   
else

   
{
       
TicTocMsg13 *ttmsg = check_and_cast<TicTocMsg13 *>(msg);

       
if (ttmsg->getDestination() == getIndex())
       
{

           
// Message arrived.

            EV
<< "Message " << ttmsg << " arrived after " << ttmsg->getHopCount() << " hops.\n";

            bubble
("ARRIVED, starting new one!");

           
delete ttmsg;

           
// Generate another one.

            EV
<< "Generating another message: ";

           
TicTocMsg13 *newmsg = generateMessage();

            EV
<< newmsg << endl;

            forwardMessage
(newmsg);
       
}
       
else
       
{
           
// We need to forward the message.
            forwardMessage
(ttmsg);
       
}
   
}
}

Марина Котова

unread,
Apr 6, 2017, 11:56:56 AM4/6/17
to OMNeT++ Users
I solved this partly, now I have problem with source and destination adr. In generateMessage() I set  source and destination and via sprintf displayed it. On display I have normal values, but really I have...(.png)
    if (getIndex() == 2) {

        // Boot the process scheduling the initial message as a self-message.

        TicTocMsg13 *msg = generateMessage();
        buf=msg;
        scheduleAt(5.0, msg);

    }

}



void Txc13::handleMessage(cMessage *msg)

{

 if (msg->isSelfMessage()){
        TicTocMsg13 *ttmsg = check_and_cast<TicTocMsg13 *>(buf);



    if (ttmsg->getDestination() == getIndex()) {

        // Message arrived.

        EV << "Message " << ttmsg << " arrived after " << ttmsg->getHopCount() << " hops.\n";

        bubble("ARRIVED, starting new one!");

        delete ttmsg;



        // Generate another one.

        EV << "Generating another message: ";

        TicTocMsg13 *newmsg = generateMessage();

        EV << newmsg << endl;

        forwardMessage(newmsg);

    }

    else {

        // We need to forward the message.

        forwardMessage(ttmsg);
        buf = nullptr;
omnet1.png

Michael Kirsche

unread,
Apr 6, 2017, 5:27:24 PM4/6/17
to OMNeT++ Users
Did you try the code that I've added? It works without problems under OMNeT 4.6 and the setting of the destination address to a random address works too.
The problem with the source address (and later on with the destination address) is that you write too many letters in your message name, because you set the space for the name to 20 characters via char msgname[20];

Afterwards you sprintf your message name: sprintf(msgname, "Hi? Ilnur, it's a tic-%d-to-%d", src, dest);
but this is longer than 20 characters, so simply set your character array to 35 characters for example
char msgname[35];


Марина Котова

unread,
Apr 7, 2017, 5:08:09 AM4/7/17
to OMNeT++ Users
 Hi, Michael, I'm very thanks to you for your help. I have Omnet 5.0 and I have this (.png) in it. After 1 simulation second your programm generate another message without deleting old one. And It don't work like processing delay.
Your advise about length of array is good. The second code I send with this works very good. The 
TicTocMsg13 *buf
is a variable to remember the message until we send it back. I did this as shown in the tutorial lesson  
"Step 6: Modeling processing delay". If it's possible to do this whithout buf variable please tell me more.
Best regards, Maria
omnet2.png

Michael Kirsche

unread,
Apr 7, 2017, 6:55:49 AM4/7/17
to OMNeT++ Users
I simply rearranged your code. The "second" message that gets generated after 6 seconds is the one generated after the second selfMessage is processed in handleMessage() of tic[0].
You asked for a "delay via self messages", that's what I did there. If you want another delay or another "processing" of the delay, simply adjust the source code to what you desire.

"Without deleting the old one" -> self messages do not need to be deleted if they are rescheduled.
If you mean "deleting the old message", this gets only deleted when it reached its destination, or do you want a different behavior? If so, again simply change the source code.

"TicTocMsg13 *buf" -> I didn't use your buffer message to remember anything, you can simply delete it from my example code.
Reply all
Reply to author
Forward
0 new messages