Stack Exchange
Omnet++ Adding functionalities to handleMessage in my class
I have this error trying to inherit handlemessage in my queue class (GateDropTailQueue) which is inheriting from DropTailQueue which in turn is inheriting from PassiveQueueBase.
class INET_API GateDropTailQueue: public DropTailQueue {
private:
    cMessage *msg1;
    cMessage *msg2;
protected:
    virtual void initialize() override;
    virtual void handleMessage(cMessage *msg) override;
... 
};

 void GateDropTailQueue::initialize()
{
    DropTailQueue::initialize();
msg1 = new cMessage("msg1"); scheduleAt(2, msg1); msg1 = nullptr;
...
}   


void GateDropTailQueue::handleMessage(cMessage *msg)
{
    DropTailQueue::handleMessage(msg);
if (msg == msg1) {
msg1 = new cMessage("msg1"); scheduleAt(10, msg1); msg1 = nullptr;
msg2 = new cMessage("msg2"); scheduleAt(2, msg2); msg2 = nullptr;
...
}
else if (msg == msg2) {
msg2 = new cMessage("msg2"); scheduleAt(2, msg2); msg2 = nullptr;
...
}
}

I am having the below error

 Error in module (inet::GateDropTailQueue)
  Mysimulation.switch.eth[0].queue.Queue1 (id=33) at event #12, t=2:
  Signal "rcvdPk" emitted with wrong class (omnetpp::cMessage does not
  subclass from omnetpp::cPacket as declared).

This error is related to first line in handleMessage in PassiveQueueBase
// PassiveQueueBase.cc
namespace inet { 
simsignal_t PassiveQueueBase::rcvdPkSignal = registerSignal("rcvdPk");

    void PassiveQueueBase::handleMessage(cMessage *msg)
    {  numQueueReceived++;
       emit(rcvdPkSignal, msg);
       ...
    }
}


The declaration
`simsignal_t PassiveQueueBase::rcvdPkSignal = registerSignal("rcvdPk");`

… of a local something, isn't syntactically valid C++.
However, this appears to be unrelated to the error message you quote.
I think it means that the code you present is likely not the one that produces that error message.

@Cheersandhth.-Alf I edit the code for that line, you are right it is in different place but I included it at that place thinking that it is only declaration for a variable rcvdPKSignal. The code runs with out my edits and this function is called normally and runs normally. Once I did changes in handleMessage, this error took place.

Probably in the NED file of your model you have this line:
@signal[rcvdPk](type=cPacket);

It means that rcvdPk signal may be emitted with a cPacket object, not with cMessage. What you should to do is to cast msg to cPacket, for example this way:
void PassiveQueueBase::handleMessage(cMessage *msg)
{  numQueueReceived++;
   cPacket * pkt = dynamic_cast<cPacket *> (msg);
   if (pkt) {
       emit(rcvdPkSignal, pkt);
   } else {
       // ... not a cPacket
   }

   ...
}


well I just checked that the message was used to be transmitted EtherIIFrame in the network is of type EtherFrame  which is in turn of type cPacket. tried your solution but gave me the same error. I tried changing my class messages to cPacket type instead and it worked until the self message (I created) is received and gave me another error. <!> Error in module (inet::EtherMACFullDuplex) Mysimulation.switch.eth[0].mac (id=25) at event #40, t=2: check_and_cast(): cannot cast (omnetpp::cPacket)msg2 to type 'inet::EtherFrame '. might be that I should rethink about my code.

In INET emit for rcvdPk signal is used several times. Probably the problem is in different place. Did you try to debug your project? By the way: you must not assign a nullptr for msg after scheduling it! Moreover, in GateDropTailQueue::handleMessage you create a new message every time after receiving other message, but you do not delete them - it leads to memory leaks.

Thank you for this notes, It is my first trial and I wanted to see output. You are right about creating every time new message I just edited that. I replaced in handleMessage msg1 = new cMessage("msg1"); by msg1 = msg; and replaced msg2 = new cMessage("msg2"); under else condition only by msg2 =msg; so I only create "msg2" once every msg1 reception which is normally twice or three times per simulation. Regarding the nullptr I tried to follow the tictoc tutorial send(tictocMsg, "out"); tictocMsg = nullptr; [https://omnetpp.org/doc/omnetpp/tictoc-tutorial/txc6.cc.html]

I am working on debuging, still all I know is that I can see both handleMessage are executed in PassiveQueueBase and GateDropTailQueue, on the third attempt on that line emit(rcvdPkSignal, msg); it crash. In the simulation I can see only one message received so I don't understand still how in the debugging I can see both functions are executed twice.

Could you show the definition of this signal in NED?

@signal[rcvdPk](type=cPacket);

So, does it crash using this code: cPacket * pkt = dynamic_cast<cPacket *> (msg);  if (pkt) { emit(rcvdPkSignal, pkt); } ?

cPacket * pkt = dynamic_cast<cPacket *> (msg);        if (pkt) {            emit(rcvdPkSignal, pkt);        } else {     numQueueReceived++; ... }  and yes it gives the same error

But if msg is not a cPacket object, dynamic_cast returns nullptr, and  in if condition only else is executed. So it is impossible, that this code results in error Signal "rcvdPk" emitted with wrong class (omnetpp::cMessage does not subclass from omnetpp::cPacket as declared). What do you place in else?

I edited the question and added the code at the end of the question.

Now everything is clear. You must not emit rcvdPkSignal for non-cPacket object! So remove emit(rcvdPkSignal, msg); from else.

I removed the if condition and forced the emit for pkt then I started getting error for the rest of emit so I changed all the emit in the same function. so I got another error <!> Error in module (inet::GateDropTailQueue) Mysimulation.switch.eth[0].queue.Queue1 (id=33) at event #12, t=2: Signal "rcvdPk" emitted a nullptr (specify 'type=omnetpp::cPacket?' in @signal to allow nullptr).  The point is that this same handlemessage was working with the same type of frames of type cPacket before creating my function above. I don't see how my handlemessage functions affected the parent one.

Every scheduleAt from your code generates a cMessage object received by handleMessage at specified time. So at the beginning of handleMessage you should check, whether the message is self-message, for example this way: if(msg->isSelfMessage()) { // self message processing } else { // current code from handleMessage }.

It was solved by having a condition over the parent handleMessage(cMessage * msg)
 if (!msg->isSelfMessage()) { ... }

// while it didn't work using the condition
if (msg != msg1 && msg != msg2) { ... }

