bluetoothmgmt/btmgr/Inc/BTManServer.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 15 Jul 2010 19:55:36 +0300
branchRCL_3
changeset 21 14e240312f6f
parent 11 20fda83a6398
permissions -rw-r--r--
Revision: 201025 Kit: 2010127

// Copyright (c) 1999-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//

/**
 @file
 @internalAll
*/

#ifndef BTManServer_H
#define BTManServer_H

#include <bt_subscribe.h>
#include "BTRegistryDB.h"
#include "btmanclientserver.h"
#include "btmanserverburmgr.h"

#if KMaxBluetoothNameLen > KMaxFriendlyNameLen
#define KLongestName KMaxBluetoothNameLen
#else
#define KLongestName KMaxFriendlyNameLen
#endif

class CBTSecMan;
class CBTRegistryHelper;
class CBTManSession;
class CBTManSubSession;

/**
BTMan Server Shutdown Timer.
Closes the BTMan server after a preset delay. Activated before the first client connects
and after the last client disconnects.
**/
NONSHARABLE_CLASS(CBTManServerShutdown) : public CTimer
	{
	enum {KBTManServerShutdownDelay=5000000};	// 5s
public:
	inline CBTManServerShutdown();
	inline void ConstructL();
	inline void Start();
private:
	void RunL();
	};

void PanicServer(TInt aPanic);
void PanicClient(const RMessage2& aMessage, TInt aPanic, CBTManSession* aSession);

//**********************************
//MBTManHelper
//**********************************
/**
Helper interface class.
Defines interface to allow CBTManMessage to use SecMan helper objects.
**/
class MBTManHelper
	{
public:
	virtual void Delete() = 0;
	virtual const RMessage2& Message() = 0;
	};

//**********************************
//CBTManMessage
//**********************************
/**
RMessage2 container class.
Ties together client requests and helper objects dealing with them.
Messages must be completed via this class.
**/
NONSHARABLE_CLASS(CBTManMessage) : public CBase
	{
public:
	static CBTManMessage* NewL(const RMessage2& aMessage);
	~CBTManMessage();
	void SetHelper(MBTManHelper* aHelper);
	void RemoveHelper();
	void Complete(TInt aReason);
	const RMessage2& Message();
	const TAny* CancelPtr();
	MBTManHelper* Helper();
	TBool operator==(CBTManMessage& aMessage) const;
private:
	CBTManMessage(const RMessage2& aMessage);
	void ConstructL();
private:
	RMessage2	iMessage;	//<The message to be completed
	const TAny* iCancelPtr;	//<Address of the TRequestStatus of the client-side active object - used for cancelling purposes
	MBTManHelper* iHelper;	//<The helper associated with the message
	};


//**********************************
//CBTManServer
//**********************************
/**
The BTMan Server.
**/
NONSHARABLE_CLASS(CBTManServer) : public CPolicyServer, public MBTBURNotify
	{
public:
	//construct / destruct
	static CServer2* NewLC();
	~CBTManServer();

	// From MBTBURNotify
	virtual void BUROperationStarted();
	virtual void BUROperationStopped();

	void AddSession();
	void DropSession();

	inline TInt MaxSessionCount() const;
	inline TInt SessionCount() const;
	
	//return an object container. Will produce containers with unique ids within the server
	CObjectCon* NewContainerL();
	void DeleteContainer(CObjectCon* aCon);

	inline CBTRegistry& Registry() const;

	void Publish(TUint aKey, TInt aValue); // only publish ints for now, ignore error
	void NotifyViewChange(CBTManSubSession& aSubSessionViewOwner, const TDesC& aViewDescriptor);
	void NotifyViewChange(const TDesC& aViewDescriptor);

private:
	CBTManServer();
	void ConstructL();
	//open/close a session
	CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
	void TryToStartShutdownTimer();

private:
	TInt					iMaxSessionCount;
	TInt					iSessionCount;	//<The number of sessions
	CBTManServerShutdown	iShutdown;//<A timer used to shut the server down after all clients have exited.
	CObjectConIx*			iContainerIndex;//<The server has an onject container index which creates an object container for each session
	CBTRegistry*			iRegistry;
	RProperty				iProperty;	// so that subsessions can publish change info
	CBTManServerBURMgr*		iBURManager;	// Manage backup and restore events generated by the Secure Backup Engine

	TBool			iBUROperationStarted;	// Whether or not a backup or restore operation is in progress (meaning that this server should not shutdown)
	};

inline TInt CBTManServer::MaxSessionCount() const {return iMaxSessionCount;}
inline TInt CBTManServer::SessionCount() const {return iSessionCount;}
inline CBTRegistry& CBTManServer::Registry() const {return *iRegistry;}

//
//**********************************
//CBTManSession
//**********************************
/**
BTMan Server Session.
General purpose session used to create functionally specific subsessions.
**/
NONSHARABLE_CLASS(CBTManSession) : public CSession2
	{
private:
	enum TSubSessionType{EHostResolver, ERegistry, ELocalDevice, ECommPortSettings,ESecuritySettingsB};
public:
	CBTManSession(CBTRegistry& aRegistry, const RMessage2& aMessage);
	void CreateL();
	void ConstructL();
	~CBTManSession();

	//Create/delete subsession
	void NewSubSessionL(TSubSessionType aType, const RMessage2 &aMessage);
	void CloseSubSession(const RMessage2 &aMessage);
	void DeleteSubsession(TInt aHandle, const RMessage2 &aMessage); //can't fail - can panic client
	CBTManSubSession* SubSessionFromHandle(TInt aHandle);
	CBTManServer& Server();

	void ServiceL(const RMessage2 &aMessage);
	TInt HandleError(TInt aError, const RMessage2 &aMessage);
	TBool DispatchSessMessageL(const RMessage2 &aMessage);
	void DispatchSubSessMessageL(const RMessage2 &aMessage);

	void CompleteMessage(const RMessage2& aMessage, TInt aReason);
	void CompleteMessage(MBTManHelper* aHelper, TInt aReason);
	void CreateBTManMessageL(const RMessage2& aMessage);
	CBTManMessage* FindMessage(const RMessage2& aMessage);
	CBTManMessage* FindMessage(MBTManHelper* aHelper);
	void DeleteMessage(CBTManMessage* aMessage);

	void CancelRequest(const RMessage2& aMessage);

	TBool SubSessionHasOverlappingView(CBTManSubSession& aSubSessionViewOwner, const TDesC& aViewDescriptor);
	TBool SubSessionHasOverlappingView(const TDesC& aViewDescriptor);

private:
	void DoCompleteMessage(CBTManMessage& aMessage, TInt aReason);
	void CompleteOutstandingMessages();
	void ClientRegChangeNotification(TAny* aPtr1);

private:
	CObjectCon*					iContainer;		//<object container for this session
	CObjectIx*					iSubSessions;	//<object index which stores subsessions
	TInt						iResourceCount;		//<total number of resources allocated
	CBTRegistry&				iRegistry;

	CArrayPtr<CBTManMessage>*	iMessageArray;	//array of outstanding messages
	RMessage2 iCurrentMessage;
	TBool	  					iClientPanic;   //Flag to indicate if ClientPanic'd when session closed

	};


//**********************************
// CBTManSubSession
//**********************************
/**
BTMan Subsession base class.
**/
NONSHARABLE_CLASS(CBTManSubSession) : public CObject
	{
public:
	virtual void Cleanup(TInt aError)=0;
	virtual TBool IsOverlappingView(const TDesC& aViewDescriptor);
	virtual void SetViewChangeNotificationMessage(const RMessage2& aMessage);

protected:
	CBTManSubSession(CBTManSession& aSession, CBTRegistry& aRegistry);
	void NotifyChange(TUint aTableChanged);
	void NotifyChange(TUint aTableChanged, CBTManSubSession& aSubSessionViewOwner, const TDesC& aViewDescriptor);

protected:
	CBTManSession&	iSession;	// session owning us
	CBTRegistry&	iRegistry;	// the class that shields us from DBMS

	RMessage2       iViewChangeNotificationMessage; // not all subsession types may use this
	};

//**********************************
// CBTRegistrySubSession
//**********************************
/**
Registry Subsession.
Represents (server-side) remote Bluetooth devices
**/
NONSHARABLE_CLASS(CBTRegistrySubSession): public CBTManSubSession
	{
public:
	static CBTRegistrySubSession* NewL(CBTManSession& aSession, CBTRegistry& aRegistry);
	~CBTRegistrySubSession();

	void PreLoadL(const RMessage2& aMessage);
	void GetDeviceL(const TBTNamelessDevice& aDevice, const RMessage2& aMessage);
	void AddDeviceL(const CBTDevice& aDetails, const RMessage2& aMessage);
	void ModifyL(const CBTDevice& aDetails, const RMessage2& aMessage);
	void ModifyL(const TBTNamelessDevice& aNewDetails, const RMessage2& aMessage);
	void ModifyNameL(const TBTDevAddr& aAddress, const RMessage2& aMessage);
	void OpenViewL(const TBTRegistrySearch& aSearch, const RMessage2& aMessage);
	void UnpairL(const TBTDevAddr& aAddress, const RMessage2& aMessage);
	void UnpairViewL(const RMessage2& aMessage);
	void RetrieveL(const RMessage2& aMessage);
	void DeleteViewL(const RMessage2& aMessage);
	void CloseView(const RMessage2& aMessage);
	void Cleanup(TInt aError);

private:
	void ConstructL();
	CBTRegistrySubSession(CBTManSession& aSession, CBTRegistry& aRegistry);
	void DoCloseView();
	void NotifyChange(CBTManSubSession& aSubSessionViewOwner, const TDesC& aViewDescriptor);

	virtual TBool IsOverlappingView(const TDesC& aViewDescriptor);
	virtual void SetViewChangeNotificationMessage(const RMessage2& aMessage);

private:
	RDbView*		iDBView;
	TInt			iViewCount;
	TDbBookmark		iBookmark;	// we look after our bookmark for registry to zip back to
	CBufFlat*		iResultBuffer; // for communicating back to client
	TInt			iNumDevicesInBuffer;

	// Each Registry subsession keeps one of these to then use for view spoil notifications.
	// When the server sees a subsession perform a writeable view operation it will give the changed 
	// subsession's precompiled query to all other subsessions, each of which will be asked to run 
	// the precompiled query against its own rowset row by row.
	// Any Match will be reported back and tells the server that a spoil has occurred
	
	HBufC* iUnderlyingSearch;

	};



//**********************************
// CBTLocalDeviceSubSession
//**********************************
/**
Registry Subsession.
Represents (server-side) local device details
**/
NONSHARABLE_CLASS(CBTLocalDeviceSubSession): public CBTManSubSession
	{
public:
	static CBTLocalDeviceSubSession* NewL(CBTManSession& aSession, CBTRegistry& aRegistry);
	~CBTLocalDeviceSubSession();

	void GetL(const RMessage2& aMessage);
	void UpdateL(const TBTLocalDevice& aLocalDevice, const RMessage2& aMessage);
	void Cleanup(TInt aError);
private:
	CBTLocalDeviceSubSession(CBTManSession& aSession, CBTRegistry& aRegistry);
	void ConstructL();
	};

//**********************************
// CBTCommPortSettingsSubSession
//**********************************
/**
Registry Subsession.
Represents (server-side) settings for virtual serial ports
**/
NONSHARABLE_CLASS(CBTCommPortSettingsSubSession): public CBTManSubSession
	{
public:
	static CBTCommPortSettingsSubSession* NewL(CBTManSession& aSession, CBTRegistry& aRegistry);
	~CBTCommPortSettingsSubSession();

	void GetL(const TBTCommPortSettings& aLocalDevice, const RMessage2& aMessage);
	void UpdateL(const TBTCommPortSettings& aLocalDevice, const RMessage2& aMessage);
	void DeleteL(const TBTCommPortSettings& aLocalDevice, const RMessage2& aMessage);
	void Cleanup(TInt aError);
private:
	CBTCommPortSettingsSubSession(CBTManSession& aSession, CBTRegistry& aRegistry);
	void ConstructL();	
	};


/*
* Panic definitions
*/
_LIT(KBTManPanic,"BTManServer");
// reasons for server panic
enum TBTManServerPanic
	{
	EBTManBadRequest,
	EBTManBadDescriptor,
	EBTManBadSubSessionHandle,
	EBTManBadSubSessionRemove,
	EBTManBadSubSessionType,
	EBTManBadHelper,
	EBTManBadBTManMessage,
	EBTManBadServiceArray,
	EBTManBadNotifierArray,
	EBTManBadHCIRequestRequest,
	EBTManTooManyDevicesInView,
	EBTManUnknownSeverity,
	EBTManClientShouldBeBusy,
	EBTManBadState,
	EBTManUnexpectedDbError,
	EBTManOutstandingMessagesOnClosedSession,
	};



#endif