// NIFMAN.H
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#if !defined(__NIFMAN_H__)
#define __NIFMAN_H__

#ifndef __ES_PROT_H__
#include <es_prot.h>
#endif

#ifndef __NIFVAR_H__
#include <nifvar.h>
#endif

#ifndef __CDBOVER_H__
#include <cdbover.h>
#endif

// Manager classes
class CNifMan;
class CNifFactory : public CObject
	{
friend CNifMan;
public:
	IMPORT_C CNifFactory();
	IMPORT_C virtual TInt Open();
	IMPORT_C virtual void Close();
	IMPORT_C static void Cleanup(TAny* aObject);
    IMPORT_C static TInt ControlledDelete(TAny* aFactory);
	IMPORT_C void InitL(RLibrary& aLib, CObjectCon& aCon);

protected:
	IMPORT_C ~CNifFactory();
	virtual void InstallL()=0;
	RLibrary iLib;
	CAsyncCallBack* iAsyncDtor;
	};

// Agent classes
class TNifAgentInfo
	{
public:
	TVersion iVersion;
	TName iName;
	};

class CNifAgentBase;
class CNifAgentRef;
class CNifAgentFactory : public CNifFactory
	{
friend CNifAgentRef;
protected:
	virtual CNifAgentBase *NewAgentL(const TDesC& aName)=0;
	virtual TInt Info(TNifAgentInfo& aInfo, TInt aIndex) const =0;
	};

class MNifAgentNotify
	{
public:
	virtual void ConnectComplete(TInt aStatus)=0;
	virtual void ReconnectComplete(TInt aStatus)=0;
	virtual void AuthenticateComplete(TInt aStatus)=0;
	virtual void ServiceStarted()=0;
	virtual void ServiceClosed()=0;
	virtual void DisconnectComplete()=0;
	virtual void AgentProgress(TInt aStage, TInt aError)=0;
	};

class CNifCompanionSession;
class CNifAgentBase : public CBase
	{
friend CNifAgentRef;
public:
	enum TConnectType { EStartDialOut, EReconnect, EStartCallBack, ENone, EStartDialIn };	
	IMPORT_C CNifAgentBase();

	virtual void Info(TNifAgentInfo& aInfo) const =0;
	virtual void Connect(TConnectType aType)=0;
	virtual void Connect(TConnectType aType, CCommDbOverrideSettings& aOverrideSettings)=0;
	virtual void CancelConnect()=0;
	virtual void Reconnect()=0;
	virtual void CancelReconnect()=0;
	virtual void Authenticate(TDes& aUsername, TDes& aPassword)=0;
	virtual void CancelAuthenticate()=0;
	virtual void Disconnect(TInt aReason)=0;
	virtual TInt GetExcessData(TDes8& aBuffer)=0;
	virtual TInt ReadInt(const TDesC& aField, TInt& aValue)=0;						
	virtual TInt WriteInt(const TDesC& aField, TInt aValue)=0;						
	virtual TInt ReadDes(const TDesC& aField, TDes8& aValue)=0;						
	virtual TInt WriteDes(const TDesC& aField, const TDesC8& aValue)=0;			
	virtual TInt ReadDes(const TDesC& aField, TDes16& aValue)=0;						
	virtual TInt WriteDes(const TDesC& aField, const TDesC16& aValue)=0;			
	virtual TInt ReadBool(const TDesC& aField, TBool& aValue)=0;					
	virtual TInt WriteBool(const TDesC& aField, TBool aValue)=0;					
	virtual TInt Notification(TNDCallbackEventType aEvent, const TAny* aInfo)=0;
    virtual CNifCompanionSession *NewCompanionSessionL(CSession& aSession)=0;

protected:
	MNifAgentNotify* iNotify;
	};

class CNifCompanionSession : public CBase
	{
public:
	enum TCompanionFunction{ ENifStart, ECompanionFirst=100 };

	inline const CSession& Session() const;
	inline const RMessage& Message() const;
	virtual void ServiceL(const RMessage& aMessage) =0;
protected:
	IMPORT_C CNifCompanionSession(CSession& aSession);
private:
	CSession* iSession;
	};

class TNifProgress
	{	
public:
	inline TNifProgress();
	TInt iStage;
	TInt iError;
	};

typedef TPckgBuf<TNifProgress> TNifProgressBuf;


// Static internal API class
enum TNifSocketState { ENifBuffers2048=-4, ENifBuffers1024, ENifBuffers512, 
					   ENifSocketNull=-1,
                       ENifSocketCreated=0, ENifSocketOpen=3, ENifSocketConnected=4,
					   ENifSocketError=9 };

class MNifIfUser;
class CNifIfBase;
class Nif
	{
public:
	// Network protocol support
	IMPORT_C static void BindL(MNifIfUser& aUser, TAny* aId, TDes& aResult, const TDesC& aName=TPtrC(0,0));
	IMPORT_C static void NetworkLayerClosed(MNifIfUser& aUser);
	IMPORT_C static void StartL(TDes& aResult, const TDesC& aName=TPtrC());
	IMPORT_C static void Stop(const TDesC& aName=TPtrC());
	IMPORT_C static CNifIfBase* CreateInterfaceL(const TDesC& aName);
	IMPORT_C static void CheckInstalledMBufManagerL();
	IMPORT_C static CProtocolBase* IsProtocolLoaded(const TDesC& aName);
	IMPORT_C static void CheckInstalledL();
	IMPORT_C static TInt SetSocketState(TNifSocketState aState, CServProviderBase* aProvd);
	IMPORT_C static void ProgressL(TNifProgress& aProgress, const TDesC& aName=TPtrC());
	IMPORT_C static void Stop(TAny* aId, CNifIfBase* aIf=0);
	IMPORT_C static void ProgressL(TNifProgress& aProgress, TAny* aId, CNifIfBase* aIf=0);
	};

// Client side classes
const TInt KDefaultNifSlots = 2;

class RNif : public RSessionBase
	{
public:
	IMPORT_C TInt AgentInfo(TNifAgentInfo& aInfo);
	IMPORT_C TInt DisableTimers(TBool aDisable=ETrue);
	IMPORT_C TInt Stop();
	IMPORT_C void ProgressNotification(TNifProgressBuf& aProgress, TRequestStatus& aStatus);
	IMPORT_C void CancelProgressNotification();
	IMPORT_C TInt Progress(TNifProgress& aProgress);
	IMPORT_C TInt LastProgressError(TNifProgress& aProgress);
	IMPORT_C static TVersion Version();
	IMPORT_C TInt Open(const TDesC& aName=TPtrC(), TInt aSlots=KDefaultNifSlots);
	IMPORT_C TInt NetworkActive(TBool& aIsActive);
protected:
    IMPORT_C TInt Start(TAny *aPtr);
	};

class RNifMonitor : public RNif
	{
public:
	IMPORT_C TInt Open(const TDesC& aName=TPtrC(), TInt aSlots=KDefaultNifSlots);
	};

class Nifman
	{
public:
	IMPORT_C static TInt CheckIniConfig();
	};

// Interface classes
class TNifIfInfo
	{
public:
	TUint iProtocolSupported;
	TUint iFlags;
	TVersion iVersion;
	TName iName;
	};

const TUint KNifIfIsBase           = 0x00000001;
const TUint KNifIfIsLink           = 0x00000002;
const TUint KNifIfUsesNotify       = 0x00000004;
const TUint KNifIfCreatedByFactory = 0x00000008;
const TUint KNifIfCreatedByLink    = 0x00000010;
const TUint KNifIfCreatedAlone     = 0x00000020;
const TUint KNifIfCreatesBinder    = 0x00000040;

class CNifIfFactory : public CNifFactory
	{
friend CNifMan;
protected:
	virtual CNifIfBase *NewInterfaceL(const TDesC& aName)=0;
	virtual TInt Info(TNifIfInfo& aInfo, TInt aIndex) const=0;
	};

class MNifIfNotify
	{
public:
	enum TAction { EReconnect, ECallBack, EDisconnect };					

public:
//    virtual void LinkLayerDown(TInt aReason, TBool aReconnect)=0;
    virtual void LinkLayerDown(TInt aReason, TAction aAction)=0;		
	virtual void LinkLayerUp()=0;
    virtual void NegotiationFailed(CNifIfBase* aIf, TInt aReason)=0;
    virtual TInt Authenticate(TDes& aUsername, TDes& aPassword)=0;
    virtual void CancelAuthenticate()=0;
	virtual TInt GetExcessData(TDes8& aBuffer)=0;
	virtual TInt ReadInt(const TDesC& aField, TInt& aValue)=0;				
    virtual TInt WriteInt(const TDesC& aField, TInt aValue)=0;				
    virtual TInt ReadDes(const TDesC& aField, TDes8& aValue)=0;				
    virtual TInt ReadDes(const TDesC& aField, TDes16& aValue)=0;				
    virtual TInt WriteDes(const TDesC& aField, const TDesC8& aValue)=0;	
	virtual TInt WriteDes(const TDesC& aField, const TDesC16& aValue)=0;	
	virtual TInt ReadBool(const TDesC& aField, TBool& aValue)=0;			
    virtual TInt WriteBool(const TDesC& aField, TBool aValue)=0;			
	virtual void IfProgress(TInt aStage, TInt aError)=0;
	virtual void OpenRoute()=0;
	virtual void CloseRoute()=0;
	virtual TInt Notification(TNDCallbackEventType aEvent, const void * aInfo = NULL)=0;  

	};

class CNifIfLink;
class CNifIfBase : public CBase
	{
friend CNifAgentRef;
public:
	IMPORT_C CNifIfBase(CNifIfFactory& aFactory);
	IMPORT_C CNifIfBase();
	IMPORT_C ~CNifIfBase();
	IMPORT_C static void Cleanup(TAny* aIf);
	IMPORT_C virtual void Open();
	IMPORT_C virtual void Close();
	IMPORT_C virtual void BindL(TAny *aId);
	IMPORT_C virtual TInt State();
	IMPORT_C virtual TInt Control(TUint aLevel,TUint aName,TDes8& aOption, TAny* aSource=0);
	virtual void Info(TNifIfInfo& aInfo) const =0;
	virtual TInt Send(RMBufChain& aPdu, TAny* aSource=0)=0;
	inline MNifIfNotify* Notify() const;

protected:
	IMPORT_C CNifIfBase(CNifIfLink& aLink);
	TInt iRefCount;
	CNifIfFactory* iFactory;
	MNifIfNotify* iNotify;
	};

class CNifIfLink : public CNifIfBase
	{

public:
	IMPORT_C CNifIfLink(CNifIfFactory& aFactory);
	IMPORT_C virtual void AuthenticateComplete(TInt aResult);
	virtual TInt Start()=0;
//	virtual void Stop(TInt aReason)=0;
	virtual void Stop(TInt aReason, MNifIfNotify::TAction aAction)=0;		
	virtual CNifIfBase* GetBinderL(const TDesC& aName)=0;
	};

class MNifIfUser
	{
public:
	virtual void IfUserBindFailure(TInt aResult, TAny* aId)=0;
	virtual void IfUserNewInterfaceL(CNifIfBase* aIf, TAny* aId)=0;
	virtual void IfUserInterfaceDown(TInt aResult, CNifIfBase* aIf)=0;
	virtual void IfUserOpenNetworkLayer()=0;
	virtual void IfUserCloseNetworkLayer()=0;
	virtual CProtocolBase* IfUserProtocol()=0;
	virtual TBool IfUserIsNetworkLayerActive()=0;
	};

const TUint KNifOptLevel = 0x191;
const TUint KNifOptGetNifIfUser = 1|KSocketInternalOptionBit;
const TUint KNifOptStartInterface = 1;
const TUint KNifOptStopInterface = 2;
const TUint KNifOptInterfaceProgress = 3;
typedef TPckgBuf<MNifIfUser*> TNifIfUser;

const TInt KUidNifmanAgent     = 0x10000388;
const TInt KUidUnicodeNifmanAgent = 0x10003d39;
const TInt KUidNifmanInterface = 0x10000389;
const TInt KUidUnicodeNifmanInterface = 0x10003d3a;
const TInt KUidEsockIniCategory  = 0x1000047A;
const TInt KUidUnicodeEsockIniCategory  = 0x10003d3b;

#define ESOCKINI_RECORD _L8("IniRecord")

// Inlines

inline const CSession& CNifCompanionSession::Session() const
	{ return *iSession; }
inline const RMessage& CNifCompanionSession::Message() const
	{ return iSession->Message(); }

inline MNifIfNotify* CNifIfBase::Notify() const
	{ return iNotify; }

inline TNifProgress::TNifProgress()
	{ iStage=0; iError=KErrNone; }

#endif
