#ifndef _INTERFACE_H_
#define _INTERFACE_H_

#include "commdef.h"

// the error code the INTERFACE returned, 
// if no error occurred, return the bytes sent or read
//
#define IF_OK				(0)
#define IF_MORE_DATA		(-1)
#define	IF_FAIL_READ		(-2)
#define	IF_FAIL_WRITE		(-3)
#define	IF_NEED_RETRY		(-4)
#define	IF_OVER_MTU_SIZE	(-5)
#define IF_FAIL_PARAMETER   (-6)
#define IF_READ_TIMEOUT		(-7)
#define IF_WRITE_TIMEOUT    (-8)


// rwflag
#define	IF_WRITE_ONLY		0x01	// just do the operation of send
#define	IF_READ_ONLY		0x02	// just do the operation of read
#define IF_RAW_READ_WRITE	0x04	// do the raw data r/w
#define IF_SAS				0x08


typedef int (*fn_decode_frame)(unsigned char *buf, int len);
typedef unsigned char (*fn_decode_cs)(unsigned char *buf, int len);

////////////////////////////////////////////////////////////
// for internal use only
//
typedef struct _IF_CMD_BLOCK
{	
	unsigned long timeout;	// [in]in milliseconds
	unsigned long rwflag;	// [in]the flag which control the behavior of read/write	
	const char *outBuf;		// [in] the output data buffer to be sent
	unsigned long outLen;	// [in] the output data buffer size
	char *inBuf;			// [out] the input data buffer to put the firmware returned data
	unsigned long inLen;	// [out] the input data buffer size
	fn_decode_frame df;		// [in] 
	fn_decode_cs    dc;		// [in]
}sIF_CMD_BLOCK, *pIF_CMD_BLOCK;
////////////////////////////////////////////////////////////


#ifdef _WIN32
class ARCLIB_API ArcInterface
#else
class ArcInterface
#endif
{	
public:	
	virtual ~ArcInterface()
	{
	}
	virtual int send(sIF_CMD_BLOCK *ifData) = 0;	
	virtual int recv(sIF_CMD_BLOCK *ifData) = 0;
	virtual int syncSend(sIF_CMD_BLOCK *ifData) = 0;

    //
	//	MTU: Maximum transmission unit
	//  the size (in bytes) of the largest packet that this layer can carry out.	
	//	
	virtual int	 getMTU() = 0;
	virtual void *getDeviceHandle() = 0;

	// These two member functions will be called by the syncSend() member function
	// to ensure the synchronization of send() and recv() to the single controller.
	// The requirelock() will be called before the send() called, 
	// and releaselock() will be called after the recv() called.
	virtual void requirelock(){}
	virtual void releaselock(){}


	// set the timeout for interface read operation
	void setTimeOut(int nSec)
	{
		if(nSec > 0)
		{
			nTimeOut = nSec;
		}
	}

	int getTimeOut()
	{
		return nTimeOut;
	}

private:
	int nTimeOut;
};


#endif
