//=========================================================================
// Summary  :
// Filename : Modem.h
// Author   : haydn
// Project  :
// Revision : 1
// Created  : 2000/12/08
// Modified : 2000/12/08
//=========================================================================
// Description :  Generic Modem Interface
//=========================================================================
#ifndef _MODEM_H
#define _MODEM_H


// MSDEV warning that we don't need.
#pragma warning( disable : 4290 )

#include "Exception.h"
#include "MyAssert.h"
#include "ourTypes.h"


#ifndef _MSC_VER   // QNX

# include "Syslog.h"
# include <stdlib.h>

# include <unistd.h>
# include "System.h"
# define Sleep(MILLISECONDS) System::milliSleep(MILLISECONDS)

#endif

///////////////////////////////////////////////////////
// Max blob size is currently 16K.
//  Note that this is often limited by the modem rather than by the blob.
//  This number mainly determines the size of our temporary buffers.
//  Just make sure that this is bigger than the modems want.
#define iMAX_BLOB_SIZE (1024) // 16*1024
#define iMAX_FILE_SIZE (134217728) // 1024*1024*128
//#define ModemIFServerName "MIFQNXServ"
#define iMAX_QNX_MESSAGE_BYTES (iMAX_MESSAGE_SIZE+64)



///////////////////////////////////////////////////////
//  Modem class, public interface to a modem.

//   This is the low-level thing that just plain sends information back and forth.
//   It is dumb, and will slavishly follow any orders given to it.
//   It could look like a stream, if we want that kind of compatibility.
//   Any hardware-specific implementations ought to descend from Modem.

//   Modem could descend from SerialDevice in its internals.  Where possible, I have
//    mimicked the SerialDevice API to allow for a uniform device interface, but it
//    is at a lower level than I want exposed to users of Modem.

//
//  IMPORTANT!!!!!  when you inherit from Modem,
//    ALL MODEM CALLS MUST BE NON_BLOCKING!!!
//

class Modem
{
 public:

    Modem();
    virtual ~Modem();

    enum Setup
    {
	INITIATE,
	LISTEN
    };

    ///////////////////////////////////////////////////////////////////
    // read - reads chars from modem into buf.  Returns number of bytes read.
    //  This call will only return complete transmissions.  If a transmission
    //  is not complete, it returns immediately with zero bytes.
    virtual int read(char *buf, int maxBytes) = 0;

    ///////////////////////////////////////////////////////////////////
    // writeBegin - initiates a write action.
    //  This call buffers the outgoing data and begins writing it to the remote machine.
    //  Returns true if the transmission began successfully, and false if the modem
    //   could not begin.
    //  A TRUE RETURN DOES NOT MEAN THAT THE TRANSMISSION ITSELF IS SUCCESSFUL.
    virtual bool bBeginWrite(const char *buf, int nBytes) = 0;

    ///////////////////////////////////////////////////////////////////
    // getWriteStatus - returns the write status.
    enum Status
    {
	sPENDING,   // the most recently requested write is not yet done
	sFAILED,    // the most recently requested write has failed
	sSUCCEEDED,  // the most recently requested write seems to have succeeded (from the transit side)
	//  to be sure, send back acknowledgements.
	sERROR,      // The modem cannot write at this time.
	sIDLE,      // The modem is ready to write, but has no status from previous transmissions
    };
    virtual Status getWriteStatus() { return _status; };

    ///////////////////////////////////////////////////////////////////
    // getBytesPerSecond- ask the modem what kind of bandwidth it is
    //   currently seeing, in bytes per second.  Returns -1 if unknown.
    virtual int getBytesPerSecond() =0;

    ///////////////////////////////////////////////////////////////////
    // some status functions
    virtual bool bCanWrite()=0;  // true when the modem can write data
    virtual bool bHasIncomingData()=0;  // true when the modem has something to "read"
    virtual bool bHasConnection()=0;  // true when the modem thinks that it has a hope of getting data across.
    virtual int  iGetMaxTransitBytes()=0; // maximum number of bytes modem can send in one transfer
    virtual int  iExpectedRoundTripDuration() const=0; // number of seconds required for a data round trip

 protected:
    const char* _pcStatusString;   // pointer to the modem's current status in human-readable form.
    Status _status;
};


#endif
