# txc8.cc

    //
    // This file is part of an OMNeT++/OMNEST simulation example.
    //
    // Copyright (C) 2003-2005 Andras Varga
    //
    // This file is distributed WITHOUT ANY WARRANTY. See the file
    // `license' for details on this and other legal matters.
    //

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

    class Tic8 : public cSimpleModule
    {
      private:
        double 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:
        Tic8();
        virtual ~Tic8();

      protected:
        virtual cMessage *generateNewMessage();
        virtual void sendCopyOf(cMessage *msg);
        virtual void initialize();
        virtual void handleMessage(cMessage *msg);
    };

    Define_Module(Tic8);

    Tic8::Tic8()
    {
        timeoutEvent = message = NULL;
    }

    Tic8::~Tic8()
    {
        cancelAndDelete(timeoutEvent);
        delete message;
    }

    void Tic8::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 Tic8::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->name() << "\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 *Tic8::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 Tic8::sendCopyOf(cMessage *msg)
    {
        // Duplicate message and send the copy.
        cMessage *copy = (cMessage *) msg->dup();
        send(copy, "out");
    }

    class Toc8 : public cSimpleModule
    {
      protected:
        virtual void handleMessage(cMessage *msg);
    };

    Define_Module(Toc8);

    void Toc8::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");
        }
    }