/*********************************************************************
 *
 * AUTHORIZATION TO USE AND DISTRIBUTE
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: 
 *
 * (1) source code distributions retain this paragraph in its entirety, 
 *  
 * (2) distributions including binary code include this paragraph in
 *     its entirety in the documentation or other materials provided 
 *     with the distribution, and 
 *
 * (3) all advertising materials mentioning features or use of this 
 *     software display the following acknowledgment:
 * 
 *      "This product includes software written and developed 
 *       by Brian Adamson and Joe Macker of the Naval Research 
 *       Laboratory (NRL)." 
 *         
 *  The name of NRL, the name(s) of NRL  employee(s), or any entity
 *  of the United States Government may not be used to endorse or
 *  promote  products derived from this software, nor does the 
 *  inclusion of the NRL written and developed software  directly or
 *  indirectly suggest NRL or United States  Government endorsement
 *  of this product.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 ********************************************************************/
 
 
#ifndef _PROTO_SIM
#define _PROTO_SIM

// The ProtoSim class serves as a base class for creating
// simulation environment versions of code using ProtoLib.
// Simulation agents for different simulation environments can
// be derived from this base class.  An "ns-2" example is
// given in the "ns" directory of the ProtoLib source tree.

// The "ProtoSim" class allows us to bind UdpSocket instances
// to the simulation environment by creating a replacement 
// implementation of the UdpSocket class.  UdpSocket instances must 
// be inited such that the UdpSocket "install_data" is a pointer 
// to the derived ProtoSim instance providing input/output 
// for the socket

// Our "ProtoSim" also has hooks for binding ProtocolTimerMgr
// instances to timing mechanisms provided by simulation environments
// A static "TimerInstaller" function is provided for use with
// ProtocolTimerMgr instances.  Again, those ProtocolTimerMgr
// instances must be provided a pointer to the ProtoSim
// instance as the "install_data"

#include "udpSocket.h"
#include "protocolTimer.h"

class ProtoSim
{
    public:
        // Simulation socket functions which must be overridden
        // (Our simulated UdpSocket class calls these)
        virtual bool OpenUdpSocket(UdpSocket* theSocket, unsigned short* thePort) = 0;
        virtual void CloseUdpSocket(UdpSocket* theSocket) = 0;       
        virtual bool SendTo(UdpSocket* theSocket, SIMADDR theAddr, unsigned short thePort,
                            const char* buffer, unsigned int len) = 0;
        virtual bool RecvFrom(UdpSocket* theSocket, char* buffer, unsigned int* buflen,
                              SIMADDR* srcAddr, unsigned short* srcPort) = 0; 
        virtual bool JoinGroup(UdpSocket* theSocket, SIMADDR theGroup) = 0;
        virtual void LeaveGroup(UdpSocket* theSocket, SIMADDR theGroup) = 0;
        virtual void SetSocketTTL(UdpSocket* theSocket, unsigned char theTTL) = 0;
        virtual void SetSocketLoopback(UdpSocket* theSocket, bool state) = 0;
        
        // "TimerInstaller" function for binding ProtoTimerMgr
        // class instances to the simulation environment
        static bool TimerInstaller(ProtocolTimerInstallCmd cmd,
                                   double                  delay,
                                   ProtocolTimerMgr*       timerMgr, 
                                   const void*             installData);
        // "SocketInstaller" is a dummy, but remember the "install_data"
        // for UdpSockets _must_ be a pointer to the applicable 
        // ProtoSim instance
        static bool SocketInstaller(UdpSocketCmd        cmd,
                                    class UdpSocket*    theSocket,
                                    const void*         installData) {}
        
    protected:
        // Simulation timer mgmt functions which must be overridden
        virtual bool InstallTimer(ProtocolTimerMgr* timerMgr, double delay) = 0;
        virtual bool ModifyTimer(ProtocolTimerMgr* timerMgr, double delay) = 0;
        virtual bool RemoveTimer(ProtocolTimerMgr* timerMgr) = 0;
                
};  // end class ProtoSim

#endif // _PROTO_SIM
