// // This file is part of an OMNeT++/OMNEST simulation example. // // Copyright (C) 2003-2015 Andras Varga // // This file is distributed WITHOUT ANY WARRANTY. See the file // `license' for details on this and other legal matters. // #include #include #include using namespace omnetpp; /** * In the previous model we just created another packet if we needed to * retransmit. This is OK because the packet didn't contain much, but * in real life it's usually more practical to keep a copy of the original * packet so that we can re-send it without the need to build it again. */ class Tic9 : public cSimpleModule { private: simtime_t timeout; // timeout cMessage *timeoutEvent; // holds pointer to the timeout self-message int seq; // message sequence number cMessage *message; // message that has to be re-sent on timeout public: Tic9(); virtual ~Tic9(); protected: virtual cMessage *generateNewMessage(); virtual void sendCopyOf(cMessage *msg); virtual void initialize() override; virtual void handleMessage(cMessage *msg) override; }; Define_Module(Tic9); Tic9::Tic9() { timeoutEvent = message = nullptr; } Tic9::~Tic9() { cancelAndDelete(timeoutEvent); delete message; } void Tic9::initialize() { // Initialize variables. seq = 0; timeout = 1.0; timeoutEvent = new cMessage("timeoutEvent"); // Generate and send initial message. EV << "Sending initial message\n"; message = generateNewMessage(); sendCopyOf(message); scheduleAt(simTime()+timeout, timeoutEvent); } void Tic9::handleMessage(cMessage *msg) { if (msg == timeoutEvent) { // If we receive the timeout event, that means the packet hasn't // arrived in time and we have to re-send it. EV << "Timeout expired, resending message and restarting timer\n"; sendCopyOf(message); scheduleAt(simTime()+timeout, timeoutEvent); } else { // message arrived // Acknowledgement received! EV << "Received: " << msg->getName() << "\n"; delete msg; // Also delete the stored message and cancel the timeout event. EV << "Timer cancelled.\n"; cancelEvent(timeoutEvent); delete message; // Ready to send another one. message = generateNewMessage(); sendCopyOf(message); scheduleAt(simTime()+timeout, timeoutEvent); } } cMessage *Tic9::generateNewMessage() { // Generate a message with a different name every time. char msgname[20]; sprintf(msgname, "tic-%d", ++seq); cMessage *msg = new cMessage(msgname); return msg; } void Tic9::sendCopyOf(cMessage *msg) { // Duplicate message and send the copy. cMessage *copy = (cMessage *)msg->dup(); send(copy, "out"); } /** * Sends back an acknowledgement -- or not. */ class Toc9 : public cSimpleModule { protected: virtual void handleMessage(cMessage *msg) override; }; Define_Module(Toc9); void Toc9::handleMessage(cMessage *msg) { if (uniform(0, 1) < 0.1) { EV << "\"Losing\" message " << msg << endl; bubble("message lost"); delete msg; } else { EV << msg << " received, sending back an acknowledgement.\n"; delete msg; send(new cMessage("ack"), "out"); } }