// CS_PORT.H
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#if ! defined (__CS_PORT_H__)
#define __CS_PORT_H__

#if !defined (__C32COMM_H__)
#include <c32comm.h>
#endif

const TInt KDeltaTimerInterval=100000;
const TInt KCommTimerPriority=50;
#ifdef _UNICODE
const TInt KUidUnicodeCommServerModule=0x10003d34;
#else
const TInt KUidCommServerModule=0x10000049;
#endif

class CommTimer 
	{
public:
	IMPORT_C static void Queue(TTimeIntervalMicroSeconds32 aTimeInMicroSeconds,TDeltaTimerEntry& aHandle);
	IMPORT_C static void Remove(TDeltaTimerEntry& aHandle);
	};

class CCommSession;
class CPort : public CObject
	{
friend class PortManager;

public:
	enum TAccess {EShared,EExclusive};
// Not exported
	void CommRead(const RMessage &aMessage,CCommSession* aClient); // Start read operation
	void CommReadCancel(TInt aHandle, CCommSession* aClient);
	void CommWrite(const RMessage &aMessage,CCommSession* aClient); // Start Write opneration
	void CommWriteCancel(TInt aHandle, CCommSession* aClient);
	void CommBreak(const RMessage &aMessage,CCommSession* aClient);	// Start Break operation
	void CommBreakCancel(TInt aHandle, CCommSession* aClient);
	void CommCancel(TInt aHandle, CCommSession* aClient); // Cancel all blocked operation.

	void CommConfig(const RMessage &aMessage,CCommSession& aSession) const;
	void CommSetConfig(const RMessage &aMessage,CCommSession& aSession);
	void CommSetServerConfig(const RMessage &aMessage,CCommSession& aSession);
	void CommGetServerConfig(const RMessage &aMessage,CCommSession& aSession);
	void CommCaps(const RMessage &aMessage,CCommSession& aSession);
	void CommSignals(const RMessage &aMessage,CCommSession& aSession);
	void CommSetSignalsToMark(const RMessage &aMessage, CCommSession& aSession);
	void CommSetSignalsToSpace(const RMessage &aMessage, CCommSession& aSession);
	void CommReceiveBufferLength(const RMessage &aMessage,CCommSession& aSession) const;
	void CommSetReceiveBufferLength(const RMessage &aMessage, CCommSession& aSession);
	void CommQueryReceiveBuffer(const RMessage &aMessage,CCommSession& aSession) const;
	void CommResetBuffers(const RMessage &aMessage, CCommSession& aSession);

	TBool TakeOwnershipForReading(CCommSession* aClient);		// Check if a read request is valid and take ownership of port
	TBool TakeOwnershipForWriting(CCommSession* aClient);		// Check if a Write request is valid and take ownership of port
	TBool TakeOwnershipForBreaking(CCommSession* aClient);		// Check if a Break request is valid and take ownership of port

	void InitL(TDesC8 &aName);
	static TInt WriteTimerExpiredHandler(TAny *aPtr);
	static TInt ReadTimerExpiredHandler(TAny *aPtr);
	TBool AreAnyPending();

public:
	IMPORT_C TInt IPCRead(const TAny *aPtr,TDes8 &aDes,TInt anOffset=0)const;
	IMPORT_C TInt IPCWrite(const TAny* aPtr,const TDesC8& aDes,TInt anOffset=0)const;
	IMPORT_C CPort();
	IMPORT_C void ReadCompleted(TInt anError);		// Called by a CPort to completes a read.
	IMPORT_C void WriteCompleted(TInt anError);		// Called by a CPort to completes a write
	IMPORT_C void BreakCompleted(TInt anError);		// Called by a CPort to completes a break
	IMPORT_C virtual ~CPort();
	IMPORT_C void Close();

public:
// Pure virtual
	virtual void Destruct()=0;	// Called by manager - port must call delete this.
	virtual void StartRead(const TAny* aClientBuffer,TInt aLength)=0;
	virtual void ReadCancel()=0;
	virtual TInt QueryReceiveBuffer(TInt& aLength) const=0;
	virtual void ResetBuffers(TUint aFlags)=0;
	virtual void StartWrite(const TAny* aClientBuffer,TInt aLength)=0;
	virtual void WriteCancel()=0;
	virtual void Break(TInt aTime)=0;
	virtual void BreakCancel()=0;
	virtual TInt GetConfig(TDes8& aPackage) const=0;
	virtual TInt SetConfig(const TDesC8& aPackage)=0;
	virtual TInt SetServerConfig(const TDesC8& aPackage)=0;
	virtual TInt GetServerConfig(TDes8& aPackage)=0;
	virtual TInt GetCaps(TDes8& aPackage)=0;
	virtual TInt GetSignals(TUint& aSignals)=0;
	virtual TInt SetSignalsToMark(TUint aSignals)=0;
	virtual TInt SetSignalsToSpace(TUint aSignals)=0;
	virtual TInt GetReceiveBufferLength(TInt& aLength) const=0;
	virtual TInt SetReceiveBufferLength(TInt aLength)=0;
	virtual void FreeMemory();
// Accessors
#ifdef _DEBUG_DEVCOMM
	virtual void DoDumpDebugInfo(const RMessage &aMessage)=0;
#endif
private:
	TDeltaTimerEntry iReadTimer;
	TBool iReadTimerPending;
	TDeltaTimerEntry iWriteTimer;
	TBool iWriteTimerPending;
	TAccess iMode;
	CCommSession* iReadOwner;
	TInt iReadOwnerHandle;
	CCommSession* iWriteOwner;
	TInt iWriteOwnerHandle;
	CCommSession* iBreakOwner;
	TInt iBreakOwnerHandle;
	RMessagePtr iBlockedRead;
	RMessagePtr iBlockedWrite;
	RMessagePtr iBlockedBreak;
	};
//
// CSerial factory object
//
class CLibUnloader;
class CSerial : public CObject
	{
public:
	IMPORT_C CSerial();
	IMPORT_C ~CSerial();
	IMPORT_C virtual TBool QueryVersionSupported(TVersion const &aVer) const;
	void ConstructL(RLibrary& aLib);
public:
	virtual CPort * NewPortL(const TUint aUnit)=0;
	virtual void Info(TSerialInfo &aSerialInfo)=0;
	void ModuleName(TDes& aName);
protected:
	TVersion iVersion;
private:
	CLibUnloader* iLibUnloader;
	};

typedef CSerial *(*TSerialNewL)();

#endif

