userlibandfileserver/domainmgr/src/domainsrv.cpp
changeset 0 a41df078684a
child 279 957c583b417b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/domainmgr/src/domainsrv.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1618 @@
+// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// domain\src\domainsrv.cpp
+// 
+//
+
+#include <e32debug.h>
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32property.h>
+#include <f32file.h>
+
+#include <domainpolicy.h>
+#include "domainsrv.h"
+
+#define __DS_PANIC(aError) User::Panic(_L("domainSrv.cpp"), (-(aError)) | (__LINE__ << 16))
+#define __DS_ASSERT(aCond) ((aCond) || (User::Panic(_L("domainSrv.cpp; assertion failed"), __LINE__), 1))
+
+//#define __DS_DEBUG
+
+#ifdef __DS_DEBUG
+#define __DS_TRACE(s) RDebug::Print s
+#else
+#define __DS_TRACE(s)
+#endif
+
+static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+static _LIT_SECURITY_POLICY_C1(KPowerMgmtPolicy,ECapabilityPowerMgmt);
+
+// forward refs
+class CSvrDomain;
+class CDmHierarchy;
+class CPowerUpHandler;
+class CDmHierarchyPower;
+class CDmSvrManager;
+class CDmDomainServer;
+class CDmDomainSession;
+class CDmManagerServer;
+class CDmManagerSession;
+
+
+
+// CSvrDomain
+class CSvrDomain : public CTimer
+	{
+public: 
+	static CSvrDomain* New(CDmHierarchy& aHierarchy, const TDmDomainSpec&);
+
+	// from CTimer
+	void RunL();
+
+	void Attach(CDmDomainSession*);
+	void Detach(CDmDomainSession*);
+	void AddChild(CSvrDomain*);
+	CSvrDomain* Lookup(TDmDomainId);
+	TBool CheckPropValue(TInt aPropValue);
+	void RequestDomainTransition();
+	void CompleteMemberTransition(TInt aError);
+	void CancelTransition();
+	void SetObserver(TBool aSet);
+	TDmDomainState State();
+
+private:
+	CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec*);
+	void Construct(const TDmDomainSpec* spec);
+
+	void RequestMembersTransition();
+	void RequestChildrenTransition();
+	void MembersTransitionDone();
+	void ChildrenTransitionDone();
+	void CompleteDomainTransition();
+
+private:
+	CDmHierarchy&		iHierarchy;
+	CSvrDomain*			iParent;
+	CSvrDomain*			iPeer;
+	CSvrDomain*			iChild;
+	RProperty			iProperty;
+	CDmDomainSession*	iSessions;
+	TUint16				iChildrenCount;
+	TUint16				iTransCount;
+	TTimeIntervalMicroSeconds32	iTransTimeBudget;
+
+public:
+	const TSecurityPolicy	iJoinPolicy;
+	TBool iIsObserved;
+	TDmDomainId			iId;
+	};
+
+
+// CDmHierarchy
+class CDmHierarchy : public CBase
+	{
+public:
+	static CDmHierarchy* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
+
+	CSvrDomain* LookupDomain(TDmDomainId aDomainId);
+	TInt RequestDomainTransition(TDmDomainId, TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
+	void RequestTransition(const RMessage2* aMessage);
+	TInt StartObserver( TDmDomainId aDomainId,TDmNotifyType aNotifyType);
+	void SetNotifyMessage(const RMessage2* aMessage);
+	void CompleteNotification(TInt aError);
+	TBool OutstandingNotification();
+	void StopObserver();
+	virtual TInt RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
+	virtual void CompleteTransition(TInt aError);
+	virtual void NotifyCompletion(TInt aReason);
+	
+protected:
+	CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
+	void SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection = ETraverseDefault);
+
+private:
+	RMessagePtr2	iTransMessagePtr;
+	RMessagePtr2	iObsvrMessagePtr;
+	CSvrDomain*		iObservedDomain;
+	TBool			iOutstandingNotification;
+public:
+	TDmHierarchyId	iHierarchyId;
+	CSvrDomain*		iRootDomain;
+	CSvrDomain*		iTransDomain;
+	TInt			iTransPropValue;
+	TDmDomainState	iTransState;
+	TDmTraverseDirection	iTraverseDirection;
+	TUint8			iTransId;
+	CDmManagerSession* iControllerSession;	// only one controller per hierarchy
+	TDmHierarchyPolicy iPolicy;
+	RArray<TTransitionFailure> iTransitionFailures;
+	
+	// observer stuff
+	TBool			iObserverStarted;
+	TDmNotifyType	iNotifyType;
+	RArray<TTransInfo>	iTransitions;
+	CDmManagerSession* iObserverSession;	// only one observer per hierarchy
+	TInt			iObservedChildren;
+	};
+
+
+// CPowerUpHandler
+// Active object used to receive power-up notifications 
+// from the Kernel-level power manager
+class CPowerUpHandler : public CActive
+	{
+public: 
+	static CPowerUpHandler* New(CDmHierarchyPower& aHierarchyPower);
+	
+	// from CActive
+	void RunL();
+	void DoCancel();
+
+	void RequestWakeupEventNotification();
+	void Cancel();
+
+private:
+	CPowerUpHandler(CDmHierarchyPower& aHierarchyPower);
+	void Construct();
+
+private:
+	CDmHierarchyPower& iHierarchyPower;
+	};
+
+
+// CDmHierarchyPower
+// CDmHierarchy-derived class 
+// Interfaces to the Kernel-level power manager
+class CDmHierarchyPower : public CDmHierarchy
+	{
+public:
+	static CDmHierarchyPower* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
+
+	// from CDmHierarchy
+	virtual TInt RequestSystemTransition(TDmDomainState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
+	virtual void CompleteTransition(TInt aError);
+	virtual void NotifyCompletion(TInt aReason);
+
+	void PowerUp();	// called from CPowerUpHandler
+
+private:
+	CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
+	void Construct();
+
+private:
+	enum 
+		{
+		EPoweringDown	= 0x01,
+		};
+	TUint8			iTransStatus;
+	CPowerUpHandler* iPowerUpHandler;
+	};
+
+
+// CDmSvrManager
+class CDmSvrManager : public CBase
+	{
+public:
+	static CDmSvrManager* New();
+
+	TInt BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy);
+	CDmHierarchy* LookupHierarchy(TDmHierarchyId aHierarchyId);
+	TInt LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain);
+
+private:
+	CDmSvrManager();
+	void Construct();
+
+private:
+	RPointerArray<CDmHierarchy> iDomainHierarchies;
+	};
+
+// CDmDomainServer
+class CDmDomainServer : public CServer2
+	{
+public: 
+	// from CServer2
+	CSession2* NewSessionL(const TVersion& aVer) const;
+	CSession2* NewSessionL(const TVersion& aVer, const RMessage2& aMessage) const;
+
+	CDmDomainServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
+		{}
+
+public:
+	CDmSvrManager*	iManager;
+	};
+
+// CDmDomainSession
+class CDmDomainSession : public CSession2
+	{
+public: 
+	// from CBase
+	~CDmDomainSession();
+
+	// from CSession2
+	void ServiceL(const RMessage2& aMessage);
+
+private:
+	CSvrDomain*			iDomain;
+
+public:
+	CDmDomainSession*	iNext;
+	TUint8				iPending;
+	TBool				iNotificationEnabled;
+	};
+
+class CDmManagerServer : public CServer2
+	{
+public: 
+	// from CServer2
+	CSession2* NewSessionL(const TVersion& aVer) const;
+	CSession2* NewSessionL(const TVersion& aVer, const RMessage2&) const;
+
+	CDmManagerServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
+		{}
+	CDmSvrManager*	iManager;
+	};
+
+class CDmManagerSession : public CSession2
+	{
+public: 
+	// from CBase
+	~CDmManagerSession();
+	
+	// from CSession2
+	void ServiceL(const RMessage2& aMessage);
+
+	CDmManagerSession();
+private:
+	CDmHierarchy* iHierarchy;	// not owned
+	};
+
+
+
+
+//*********************************************************
+// TTransitionFailure
+//*********************************************************
+/**
+@internalTechnology
+
+Constructor for transition failure info.
+
+@param aDomainID	Id of the domain of interest
+@param aError		error code of transition	 
+*/
+TTransitionFailure::TTransitionFailure(TDmDomainId aDomainId, TInt aError) :
+	iDomainId(aDomainId), iError(aError)
+	{
+	}
+
+//*********************************************************
+// TTransInfo
+//*********************************************************
+
+/**
+@internalTechnology
+
+Constructor for transition failure info.
+
+@param aDomainID	Id of the domain of interest
+@param aState		State of the domain after transition
+@param aError		error code of transition	 
+*/
+TTransInfo::TTransInfo(TDmDomainId aDomainId, TDmDomainState aState, TInt aError) :
+	iDomainId(aDomainId), iState(aState), iError(aError)
+	{
+	}
+
+//*********************************************************
+// CSvrDomain
+//*********************************************************
+
+
+CSvrDomain::CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec* spec)
+	:	CTimer(CActive::EPriorityStandard), 
+		iHierarchy(aHierarchy),
+		iTransTimeBudget(spec->iTimeBudgetUs),
+		iJoinPolicy(spec->iJoinPolicy),
+		iId(spec->iId)
+	{}
+
+CSvrDomain* CSvrDomain::New(CDmHierarchy& aHierarchy, const TDmDomainSpec& aSpec)
+	{
+
+	CSvrDomain* self = new CSvrDomain(aHierarchy, &aSpec);
+
+	if (!self)
+		__DS_PANIC(KErrNoMemory);
+	self->Construct(&aSpec);
+	return self;
+	}
+
+void CSvrDomain::Construct(const TDmDomainSpec* spec)
+	{
+	TInt r = iProperty.Define(
+		KUidDmPropertyCategory, 
+		DmStatePropertyKey(iHierarchy.iHierarchyId, iId), 
+		RProperty::EInt,
+		KAllowAllPolicy,KPowerMgmtPolicy);
+
+	if (r != KErrNone)
+		__DS_PANIC(r);
+	
+	r = iProperty.Attach(KUidDmPropertyCategory, DmStatePropertyKey(
+		iHierarchy.iHierarchyId, 
+		iId));
+
+	if (r != KErrNone)
+		__DS_PANIC(r);
+
+	r = iProperty.Set(DmStatePropertyValue(0, spec->iInitState));
+	if (r != KErrNone)
+		__DS_PANIC(r);
+
+	TRAP(r, CTimer::ConstructL());
+	if (r != KErrNone)
+		__DS_PANIC(r);
+	CActiveScheduler::Add(this);
+	}
+
+void CSvrDomain::Attach(CDmDomainSession* aSession)
+	{
+	aSession->iNext = iSessions;
+	iSessions = aSession;
+	}
+
+void CSvrDomain::Detach(CDmDomainSession* aSession)
+	{
+	CDmDomainSession** prevp = &iSessions;
+	while (*prevp != aSession)
+		{
+		prevp = &((*prevp)->iNext);
+		__DS_ASSERT(*prevp);
+		}
+	*(prevp) = aSession->iNext;
+	}
+
+void CSvrDomain::AddChild(CSvrDomain* aChild)
+	{
+	++iChildrenCount;
+	aChild->iParent = this;
+	if(iIsObserved)
+		aChild->iIsObserved=ETrue;
+	// Insert the child in the list of its peers
+	aChild->iPeer = iChild;
+	iChild = aChild;
+	}
+
+CSvrDomain* CSvrDomain::Lookup(TDmDomainId aDomainId)
+	{
+	if (iId == aDomainId)
+		return this;
+
+	CSvrDomain* child = iChild;
+	while (child)
+		{
+		CSvrDomain* domain = child->Lookup(aDomainId);
+		if (domain)
+			return domain;
+		child = child->iPeer;
+		}
+	return NULL;
+	}
+
+TBool CSvrDomain::CheckPropValue(TInt aPropValue)
+	{ return iHierarchy.iTransPropValue == aPropValue; }
+
+void CSvrDomain::RequestMembersTransition()
+	{
+	__DS_TRACE((_L("CSvrDomain::RequestMembersTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+	__DS_ASSERT(iTransCount == 0);
+	
+	for(CDmDomainSession* s = iSessions; s; s = s->iNext)
+		if (s->iNotificationEnabled)
+			{
+			++iTransCount;
+			s->iPending = ETrue;
+			// notifications will be disabled until the client makes another 
+			// call to RDmDomain::RequestTransitionNotification()
+			s->iNotificationEnabled = EFalse;
+			}
+
+	if(iIsObserved)
+		{
+		if((iHierarchy.iNotifyType&EDmNotifyTransRequest)==EDmNotifyTransRequest)
+			{
+			TTransInfo transInfo(iId,State(),KDmErrOutstanding);
+			iHierarchy.iTransitions.Append(transInfo);
+			if(iHierarchy.OutstandingNotification())
+					iHierarchy.CompleteNotification(KErrNone);	
+			}
+		}
+	if (iTransCount > 0)
+		CTimer::After(iTransTimeBudget);
+	iProperty.Set(iHierarchy.iTransPropValue);
+	if (iTransCount == 0)
+		MembersTransitionDone();
+	}
+
+
+void CSvrDomain::RequestChildrenTransition()
+	{
+	__DS_TRACE((_L("CSvrDomain::RequestChildrenTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+	__DS_ASSERT(iTransCount == 0);
+	iTransCount = iChildrenCount;
+	if (iTransCount)
+		{
+		CSvrDomain* child = iChild;
+		__DS_ASSERT(child);
+		do	{
+			child->RequestDomainTransition();
+			child = child->iPeer;
+			}
+		while(child);
+		}
+	else
+		ChildrenTransitionDone();
+	}
+
+void CSvrDomain::RequestDomainTransition()
+	{
+	__DS_TRACE((_L("CSvrDomain::RequestDomainTransition() hierarchy=%d, domain=0x%x state=0x%x prop=0x%x"), 
+						iHierarchy.iHierarchyId, iId, iHierarchy.iTransState, iHierarchy.iTransPropValue));
+	__DS_ASSERT(iTransCount == 0);
+	if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
+		RequestChildrenTransition();
+	else
+		RequestMembersTransition();
+	}
+		
+void CSvrDomain::MembersTransitionDone()
+	{
+	__DS_TRACE((_L("CSvrDomain::MembersTransitionDone() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+	__DS_ASSERT(iTransCount == 0);
+	if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
+		CompleteDomainTransition();
+	else
+		RequestChildrenTransition();
+	}
+
+void CSvrDomain::ChildrenTransitionDone()
+	{
+	__DS_TRACE((_L("CSvrDomain::ChildrenTransitionDone() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+	__DS_ASSERT(iTransCount == 0);
+	if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
+		RequestMembersTransition();
+	else
+		CompleteDomainTransition();
+	}
+
+void CSvrDomain::CompleteMemberTransition(TInt aError)
+	{
+	__DS_TRACE((_L("CSvrDomain::CompleteMemberTransition() hierarchy=%d, domain=0x%x, aError = %d"), iHierarchy.iHierarchyId, iId, aError));
+	__DS_ASSERT(iTransCount);
+
+	if (aError)
+		{
+		// Add a transition failure to the array
+		TTransitionFailure failure(iId, aError);
+		iHierarchy.iTransitionFailures.Append(failure);
+		
+		if(iIsObserved)
+			{
+				if((iHierarchy.iNotifyType&EDmNotifyFail)==EDmNotifyFail)
+				{
+				TTransInfo transInfo(iId,State(),aError);
+				iHierarchy.iTransitions.Append(transInfo);
+				if(iHierarchy.OutstandingNotification())
+					iHierarchy.CompleteNotification(KErrNone);
+				}
+			}
+		// examine the failure policy to work out what to do
+		if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
+			{
+			iHierarchy.CompleteTransition(aError);
+			return;
+			}
+		}
+	else if(iIsObserved)
+			{
+				if((iHierarchy.iNotifyType&EDmNotifyPass) == EDmNotifyPass)
+				{
+				TTransInfo transInfo(iId,State(),aError);
+				iHierarchy.iTransitions.Append(transInfo);
+				if(iHierarchy.OutstandingNotification())
+					iHierarchy.CompleteNotification(KErrNone);
+				}
+			}
+
+	if (--iTransCount == 0)
+		{
+		CTimer::Cancel();
+		MembersTransitionDone();
+		}
+	}
+
+void CSvrDomain::RunL()
+	{ // Timer expired 
+	__DS_TRACE((_L("CSvrDomain::RunL() Members transition timeout hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+
+	// Add a transition failure to the array
+	TTransitionFailure failure(iId,KErrTimedOut);
+	iHierarchy.iTransitionFailures.Append(failure);
+
+
+	// examine the failure policy to work out what to do
+	if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
+		{
+		iHierarchy.CompleteTransition(KErrTimedOut);
+		return;
+		}
+
+	if (iTransCount)
+		{ // Complete transition of all members
+		CDmDomainSession* session = iSessions;
+		while (session)
+			{
+			session->iPending = EFalse;
+			session = session->iNext;
+			}
+		iTransCount = 0;
+		MembersTransitionDone();
+		}
+	}
+
+
+void CSvrDomain::CompleteDomainTransition()
+	{
+	__DS_TRACE((_L("CSvrDomain::CompleteDomainTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+	__DS_ASSERT(iTransCount == 0);
+	if (iHierarchy.iTransDomain == this)
+		{
+		const TInt err = (iHierarchy.iTransitionFailures.Count() > 0)? 
+			iHierarchy.iTransitionFailures[0].iError : KErrNone;
+		iHierarchy.CompleteTransition(err);
+		}
+	else
+		{
+		__DS_ASSERT(iParent);
+		__DS_ASSERT(iParent->iTransCount);
+		if (--iParent->iTransCount == 0)
+			iParent->ChildrenTransitionDone();
+		}
+	}
+
+void CSvrDomain::CancelTransition()
+	{
+	__DS_TRACE((_L("CSvrDomain::CancelTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+	CTimer::Cancel();
+	CSvrDomain* child = iChild;
+	while (child)
+		{
+		child->CancelTransition();
+		child = child->iPeer;
+		}
+	CDmDomainSession* session = iSessions;
+	while (session)
+		{
+		session->iPending = EFalse;
+		session = session->iNext;
+		}
+	iTransCount = 0;
+	}
+
+void CSvrDomain::SetObserver(TBool aSet)
+	{
+	iIsObserved=aSet;
+	if(aSet)
+		{
+		iHierarchy.iObservedChildren++;
+		}
+	else 
+		{
+		// this should be zero at the end
+		iHierarchy.iObservedChildren--;
+		}
+	if(iChildrenCount!=0)
+		{
+		CSvrDomain* domain=iChild;
+		do	{
+			domain->SetObserver(aSet);
+			domain = domain->iPeer;
+			}
+		while(domain);
+		}
+	}
+
+TDmDomainState CSvrDomain::State()
+	{
+	TInt value;
+	iProperty.Get(value);
+	return DmStateFromPropertyValue(value);
+	}
+
+//*********************************************************
+// CDmHierarchy
+//*********************************************************
+
+CDmHierarchy* CDmHierarchy::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
+	{
+	CDmHierarchy* self;
+	
+	if (aHierarchyId == KDmHierarchyIdPower)
+		self = CDmHierarchyPower::New(aHierarchyId, aPolicy);
+	else 
+		self = new CDmHierarchy(aHierarchyId, aPolicy);
+
+	if (!self)
+		__DS_PANIC(KErrNoMemory);
+
+	return self;
+	}
+
+CDmHierarchy::CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
+	iOutstandingNotification(EFalse),
+	iHierarchyId(aHierarchyId),
+	iPolicy(aPolicy)
+	{
+	iTransitionFailures.Reset();
+	}
+
+CSvrDomain* CDmHierarchy::LookupDomain(TDmDomainId aDomainId)
+	{
+	return iRootDomain ? iRootDomain->Lookup(aDomainId) : NULL;
+	}
+
+void CDmHierarchy::RequestTransition(const RMessage2* aMessage)
+	{
+	// reset the array of transition failures
+	iTransitionFailures.Reset();
+
+	if (aMessage)
+		iTransMessagePtr = *aMessage;
+	iTransPropValue = DmStatePropertyValue(++iTransId, iTransState);
+
+	iTransDomain->RequestDomainTransition();
+	}
+
+
+TInt CDmHierarchy::StartObserver(TDmDomainId aDomainId,TDmNotifyType aNotifyType)
+	{
+	iObservedDomain = LookupDomain(aDomainId);
+		
+	if(iObservedDomain==NULL)
+		return KDmErrBadDomainId;
+	
+
+	iObservedDomain->SetObserver(ETrue);
+	iNotifyType=aNotifyType;
+	iObserverStarted=ETrue;
+	return KErrNone;
+	}
+
+void CDmHierarchy::SetNotifyMessage(const RMessage2* aMessage)
+	{
+	if (aMessage)
+		{
+		iObsvrMessagePtr = *aMessage;
+		iOutstandingNotification=ETrue;
+		}		
+	}
+
+TBool CDmHierarchy::OutstandingNotification()
+	{
+	return iOutstandingNotification;
+	}
+
+void CDmHierarchy::CompleteNotification(TInt aError)
+	{
+	if(iOutstandingNotification)
+		{
+		iObsvrMessagePtr.Complete(aError);
+		iOutstandingNotification=EFalse;
+		}
+	}
+
+void CDmHierarchy::StopObserver()
+	{
+	
+	iObservedDomain->SetObserver(EFalse);
+	iTransitions.Reset();
+	iObserverStarted=EFalse;
+	}
+void CDmHierarchy::NotifyCompletion(TInt aReason)
+	{
+	iTransDomain = NULL;
+	iTransPropValue = 0;
+	iTransMessagePtr.Complete(aReason);
+	}
+
+TInt CDmHierarchy::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
+	{
+	iTransDomain = iRootDomain;
+	SetState(aTargetState, aTraverseDirection);
+	RequestTransition(aMessage);
+	return KErrNone;
+	}
+
+
+TInt CDmHierarchy::RequestDomainTransition(
+	TDmDomainId aDomainId, 
+	TDmDomainState aTargetState, 
+	TDmTraverseDirection aTraverseDirection, 
+	const RMessage2* aMessage)
+	{
+	__DS_TRACE((_L("CDmHierarchy::RequestTransition() hierarchy=%d domain=0x%x state=0x%x"), iHierarchyId, aDomainId, aTargetState)); 
+	iTransDomain = LookupDomain(aDomainId);
+	if (!iTransDomain)
+		return KDmErrBadDomainId;
+	SetState(aTargetState, aTraverseDirection);
+	RequestTransition(aMessage);
+	return KErrNone;
+	}
+
+void CDmHierarchy::CompleteTransition(TInt aError)
+	{
+	if (!iTransDomain)
+		return;
+
+	__DS_TRACE((_L("CDmHierarchy::CompleteTransition() hierarchy=%d, domain=0x%x, aError=%d"), iHierarchyId, iTransDomain->iId, aError));
+
+	if (iTransDomain)
+		{
+		iTransDomain->CancelTransition();
+		NotifyCompletion(aError);
+		}
+	}
+
+void CDmHierarchy::SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection)
+	{
+	__DS_ASSERT(iTransDomain);
+
+
+	if (aTraverseDirection == ETraverseDefault)
+		{
+		TDmDomainState oldState = iTransDomain->State();
+
+		if (aTargetState >= oldState)
+			iTraverseDirection = iPolicy.iPositiveTransitions;
+		else
+			iTraverseDirection = iPolicy.iNegativeTransitions;
+		}
+	else
+		iTraverseDirection = aTraverseDirection;
+
+	__DS_ASSERT(iTraverseDirection < ETraverseMax);
+
+	iTransState = aTargetState;
+	}
+
+//*********************************************************
+// CPowerUpHandler
+//*********************************************************
+
+CPowerUpHandler* CPowerUpHandler::New(CDmHierarchyPower& aHierarchyPower)
+	{
+	CPowerUpHandler* self = new CPowerUpHandler(aHierarchyPower);
+	if (!self)
+		__DS_PANIC(KErrNoMemory);
+	self->Construct();
+	return self;
+	}
+
+CPowerUpHandler::CPowerUpHandler(CDmHierarchyPower& aHierarchyPower) : 
+	CActive(CActive::EPriorityStandard),
+	iHierarchyPower(aHierarchyPower)
+	{
+	}
+
+void CPowerUpHandler::Construct()
+	{
+	CActiveScheduler::Add(this);
+	}
+
+
+void CPowerUpHandler::RequestWakeupEventNotification()
+	{
+	Power::RequestWakeupEventNotification(iStatus);
+	SetActive();
+	}
+
+
+void CPowerUpHandler::Cancel()
+	{
+	CActive::Cancel();
+	}
+
+void CPowerUpHandler::RunL()
+	{ 
+	// power wakeup event
+	iHierarchyPower.PowerUp();
+	}
+
+
+void CPowerUpHandler::DoCancel()
+	{
+	Power::DisableWakeupEvents();
+	Power::CancelWakeupEventNotification(); 
+	}
+
+
+
+//*********************************************************
+// CDmHierarchyPower
+//*********************************************************
+CDmHierarchyPower* CDmHierarchyPower::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
+	{
+	CDmHierarchyPower* self;
+
+	self = new CDmHierarchyPower(aHierarchyId, aPolicy);
+
+	if (!self)
+		__DS_PANIC(KErrNoMemory);
+
+	self->Construct();
+
+	return self;
+	}
+
+CDmHierarchyPower::CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
+	CDmHierarchy(aHierarchyId, aPolicy)
+	{
+	}
+
+
+void CDmHierarchyPower::Construct()
+	{
+	iPowerUpHandler = CPowerUpHandler::New(*this);
+	if (!iPowerUpHandler)
+		__DS_PANIC(KErrNoMemory);
+	}
+
+void CDmHierarchyPower::NotifyCompletion(TInt aReason)
+	{
+	iTransStatus = 0;
+	CDmHierarchy::NotifyCompletion(aReason);
+	}
+
+TInt CDmHierarchyPower::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
+	{
+	__DS_TRACE((_L("CDmSvrManager::RequestSystemTransition() state = 0x%x"), aTargetState));
+	
+	TInt r = Power::EnableWakeupEvents((TPowerState) aTargetState);
+	if (r != KErrNone)
+		return r;
+	
+	iPowerUpHandler->RequestWakeupEventNotification();
+
+	iTransStatus |= EPoweringDown;
+
+	return CDmHierarchy::RequestSystemTransition(aTargetState, aTraverseDirection, aMessage);
+	}
+
+void CDmHierarchyPower::CompleteTransition(TInt aError)
+	{
+	if (!iTransDomain)
+		return;
+
+	__DS_TRACE((_L("CDmHierarchyPower::CompleteTransition() domain=0x%x"), iTransDomain->iId));
+
+	if (iTransDomain && aError == KErrCancel)
+		iPowerUpHandler->Cancel();
+
+	if (iTransStatus & EPoweringDown)
+		{
+		RFs fs;
+		TInt r=fs.Connect();
+		__DS_ASSERT(r==KErrNone);	
+		__DS_TRACE((_L("CDmSvrManager::CompleteTransition() Calling FinaliseDrives")));
+		r=fs.FinaliseDrives();
+		__DS_TRACE((_L("CDmSvrManager::CompleteTransition()  Finalise returned %d"),r)); 
+		fs.Close();
+
+		Power::PowerDown();
+		__DS_ASSERT(iTransState != (TDmDomainState) EPwOff);
+		__DS_ASSERT(iPowerUpHandler->iStatus.Int() == KErrNone);
+		}	
+	else
+		{
+		CDmHierarchy::CompleteTransition(aError);
+		}
+	}
+
+
+void CDmHierarchyPower::PowerUp()
+	{
+	__DS_TRACE((_L("CDmHierarchyPower::RunL() Wakeup Event")));
+	__DS_ASSERT(iTransDomain);
+
+	Power::DisableWakeupEvents();
+
+	iTransStatus &= ~EPoweringDown;
+	iTransDomain->CancelTransition();
+	SetState((TDmDomainState) EPwActive);
+	RequestTransition(NULL);
+	}
+
+
+//*********************************************************
+// CDmSvrManager
+//*********************************************************
+
+CDmSvrManager* CDmSvrManager::New()
+	{
+	CDmSvrManager* self = new CDmSvrManager();
+	if (!self)
+		__DS_PANIC(KErrNoMemory);
+	self->Construct();
+	return self;
+	}
+
+CDmSvrManager::CDmSvrManager()
+	{
+	}
+
+void CDmSvrManager::Construct()
+	{
+	// load the power hierarchy-  Other hieratchies need to be loaded 
+	// explicitly using RDmDomainManager::AddDomainHierarchy()
+	CDmHierarchy* hierarchy;
+	TInt r = BuildDomainTree(KDmHierarchyIdPower, hierarchy);
+	if (r != KErrNone)
+		__DS_PANIC(r);
+
+
+	RProperty prop;
+	r = prop.Define(KUidDmPropertyCategory, KDmPropertyKeyInit, RProperty::EInt,
+							KAllowAllPolicy,KPowerMgmtPolicy);
+	if (r != KErrNone)
+		__DS_PANIC(r);
+
+	prop.Set(KUidDmPropertyCategory, KDmPropertyKeyInit, ETrue);
+	}
+
+TInt CDmSvrManager::BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy)
+	{
+
+	aHierarchy = NULL;
+
+	// assume we have already checked that the hierarchy doesn't already exist
+
+	// Get the name of the policy Dll
+	// This will be "domainPolicy.dll" for the power hierarchy
+	// and "domainPolicy<n>.dll" for other hierarchies where <n> is the hierarchy ID.
+	//
+	// If the hierarchy ID is less than KMaxCriticalPolicyDll, load only from ROM
+
+	TFullName dllName;
+
+	// is this policy "critical" i.e non-replaceable ?
+	_LIT(KSysBin,"z:\\sys\\bin\\");	
+	// const TInt KMaxCriticalPolicyDll = 1000;
+	// if (aHierarchyId < KMaxCriticalPolicyDll) // <-- cannot be false while aHierarchyId is a TUint8 (typedef'd to TDmHierarchyId)
+	dllName.Append(KSysBin);
+
+	dllName.Append(_L("domainPolicy"));
+	if (aHierarchyId != KDmHierarchyIdPower)
+		dllName.AppendNum(aHierarchyId);
+
+	dllName.Append(_L(".dll"));
+	RLibrary lib;
+	TInt r = lib.Load(dllName);
+	if (r == KErrNotFound)
+		return KErrBadHierarchyId;
+	else if (r != KErrNone)
+		return r;
+
+	TLibraryFunction ordinal1 = lib.Lookup(EDmPolicyGetDomainSpecs);
+	DmPolicyGetDomainSpecs getDomainSpecs = reinterpret_cast<DmPolicyGetDomainSpecs>(ordinal1);
+	if (getDomainSpecs == NULL)
+		r = KErrBadHierarchyId;
+
+	TLibraryFunction ordinal2 = lib.Lookup(EDmPolicyRelease);
+	DmPolicyRelease release = reinterpret_cast<DmPolicyRelease>(ordinal2);
+	if (release == NULL)
+		r = KErrBadHierarchyId;
+
+	TLibraryFunction ordinal3 = lib.Lookup(EDmPolicyGetPolicy);
+	DmPolicyGetPolicy getPolicy = reinterpret_cast<DmPolicyGetPolicy>(ordinal3);
+	if (getPolicy == NULL)
+		r = KErrBadHierarchyId;
+
+
+	// get the domain spec for this hierarchy
+	const TDmDomainSpec* spec = NULL;
+
+	if (r == KErrNone)
+		{
+		spec = (*getDomainSpecs)();
+		if (spec == NULL)
+			r = KErrBadHierarchyId;
+		}
+	// get the policy
+	TDmHierarchyPolicy hierarchyPolicy;
+	if (r == KErrNone)
+		{
+		r = (*getPolicy)(hierarchyPolicy);
+		if (r == KErrNone)
+			{
+			__DS_ASSERT(hierarchyPolicy.iPositiveTransitions < ETraverseMax);
+			__DS_ASSERT(hierarchyPolicy.iNegativeTransitions < ETraverseMax);
+			}
+		}
+
+	if (r != KErrNone)
+		{
+		lib.Close();
+		return r;
+		}
+
+	CDmHierarchy* hierarchy = CDmHierarchy::New(aHierarchyId, hierarchyPolicy);
+	if (hierarchy == NULL)
+		__DS_PANIC(KErrNoMemory);
+
+	while (r == KErrNone && spec->iId != KDmIdNone)
+		{
+		// make sure the domain doesn't already exist in this hierarchy
+		CSvrDomain* domain = hierarchy->LookupDomain(spec->iId);
+		if (domain)
+			{
+			r = KErrBadHierarchyId;
+			break;
+			}
+
+		domain = CSvrDomain::New(*hierarchy, *spec);
+		__DS_ASSERT(domain);
+	
+		if (spec->iParentId == KDmIdNone)
+			{
+			if (hierarchy->iRootDomain)
+				{
+				r = KDmErrBadDomainSpec;
+				break;
+				}
+			hierarchy->iRootDomain = domain;
+			}
+		else
+			{
+			CSvrDomain* parent = hierarchy->LookupDomain(spec->iParentId);
+			if (!parent)
+				{
+				r = KDmErrBadDomainSpec;
+				break;
+				}
+			parent->AddChild(domain);
+			}
+		++spec;
+		}
+
+	if (spec)
+		(*release)(spec);
+
+
+	if (r == KErrNone)
+		{
+		__DS_ASSERT(hierarchy->iRootDomain);
+		iDomainHierarchies.Append(hierarchy);
+		aHierarchy = hierarchy;
+		}
+	else
+		{
+		delete hierarchy;
+		hierarchy = NULL;
+		}
+
+	lib.Close();
+
+	return r;
+	}
+
+CDmHierarchy* CDmSvrManager::LookupHierarchy(TDmHierarchyId aHierarchyId)
+
+	{
+	// need to find the correct hierarchy first
+	TInt len = iDomainHierarchies.Count();
+
+	CDmHierarchy* hierarchy = NULL;
+	for (TInt n=0; n<len; n++)
+		{
+		if (iDomainHierarchies[n]->iHierarchyId == aHierarchyId)
+			{
+			hierarchy = iDomainHierarchies[n];
+			break;
+			}
+		}
+
+	return hierarchy;
+	}
+	
+
+TInt CDmSvrManager::LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain)
+	{
+	// need to find the correct hierarchy first
+	CDmHierarchy* hierarchy = LookupHierarchy(aHierarchyId);
+	if (hierarchy == NULL)
+		return KErrBadHierarchyId;
+
+	aDomain = hierarchy->LookupDomain(aDomainId);
+	if (aDomain == NULL)
+		return KDmErrBadDomainId;
+	
+	return KErrNone;
+	}
+	
+CSession2* CDmManagerServer::NewSessionL(const TVersion&, const RMessage2& aMessage) const
+	{
+
+    // If the client does not have ECapabilityPowerMgmt capability, then it has no
+    // right to make this request. Blow it up.
+    if (!KPowerMgmtPolicy.CheckPolicy(aMessage))
+		{
+
+        User::Leave(KErrPermissionDenied);
+
+		}
+
+	return new CDmManagerSession();
+	}
+
+CSession2* CDmManagerServer::NewSessionL(const TVersion&) const
+	{
+	__DS_PANIC(KErrGeneral);
+	return 0;
+	}
+
+CDmManagerSession::CDmManagerSession()
+	{}
+
+CDmManagerSession::~CDmManagerSession()
+	{
+	if (iHierarchy && iHierarchy->iControllerSession == this)
+		iHierarchy->iControllerSession = NULL;
+	if (iHierarchy && iHierarchy->iObserverSession == this)
+		iHierarchy->iObserverSession = NULL;
+	}
+
+class MyMessage : public RMessage2
+	{
+public:
+	TInt* ArgRef(TInt i)
+		{ return &iArgs[i]; }
+	};
+
+void CDmManagerSession::ServiceL(const RMessage2& aMessage)
+	{
+	TInt r;
+	CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
+
+	// Check client has ECapabilityPowerMgmt capability
+/*	
+    if (!KPowerMgmtPolicy.CheckPolicy(aMessage))
+		{
+		aMessage.Complete(KErrPermissionDenied);
+		return;
+		}
+*/
+	switch (aMessage.Function())
+		{
+		case EDmHierarchyAdd:
+			{
+			r = KErrNone;
+			TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
+
+			CDmHierarchy* hierarchy = manager->LookupHierarchy(hierarchyId);
+			if (hierarchy == NULL)
+				r = manager->BuildDomainTree(hierarchyId, hierarchy);
+			aMessage.Complete(r);
+			}
+			break;
+
+		case EDmHierarchyJoin:
+			{
+			r = KErrNone;
+			TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
+
+			iHierarchy = manager->LookupHierarchy(hierarchyId);
+			if (iHierarchy == NULL)
+				r = KErrBadHierarchyId;
+
+			if (r == KErrNone)
+				{
+				// is the hierarchy already in use ?
+				if (iHierarchy->iControllerSession)
+					r = KErrInUse;
+				else
+					iHierarchy->iControllerSession = this;
+				}
+
+			aMessage.Complete(r);
+			}
+			break;
+
+		case EDmRequestSystemTransition:
+			if (iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			if (iHierarchy->iTransDomain)
+				{
+				aMessage.Complete(KDmErrBadSequence);
+				break;
+				}
+
+			r = iHierarchy->RequestSystemTransition(
+				(TDmDomainState) aMessage.Int0(),
+				(TDmTraverseDirection) aMessage.Int1(),
+				&aMessage);
+
+			if (r != KErrNone)
+				aMessage.Complete(r);
+			break;
+
+		case EDmRequestDomainTransition:
+			if (iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			if (iHierarchy->iTransDomain)
+				{
+				aMessage.Complete(KDmErrBadSequence);
+				break;
+				}
+			r = iHierarchy->RequestDomainTransition(
+				(TDmDomainId) aMessage.Int0(), 
+				(TDmDomainState) aMessage.Int1(), 
+				(TDmTraverseDirection) aMessage.Int2(),
+				&aMessage);
+
+			if (r != KErrNone)
+				aMessage.Complete(r);
+			break;
+
+		case EDmGetTransitionFailureCount:
+			{
+			if (iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			TInt failureCount = iHierarchy->iTransitionFailures.Count();
+			aMessage.Complete(failureCount);
+			}
+			break;
+		
+		case EDmGetTransitionFailures:
+			{
+			if (iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			TInt failureCount = iHierarchy->iTransitionFailures.Count();
+			TInt clientFailureSize = aMessage.GetDesMaxLength(0);
+			TInt clientFailureCount = clientFailureSize / sizeof(TTransitionFailure);
+			__DS_ASSERT( (clientFailureSize % sizeof(TTransitionFailure)) == 0);
+			__DS_ASSERT(failureCount >= clientFailureCount);
+			
+			HBufC8* hBuf = HBufC8::New(clientFailureSize);
+			if(hBuf == NULL)
+				{
+				aMessage.Complete(KErrNoMemory);
+				break;
+				}
+			TPtr8 pBuf = hBuf->Des();
+			pBuf.Zero();
+			for (TInt i=0; i<clientFailureCount; i++)
+				{
+				TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitionFailures[i], sizeof(TTransitionFailure));
+				pBuf.Append(ptr);
+				}
+			r = aMessage.Write(0, pBuf);
+			delete hBuf;
+
+			aMessage.Complete(r);
+			}
+			break;
+
+		case EDmCancelTransition:
+			if (iHierarchy == NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			iHierarchy->CompleteTransition(KErrCancel);
+			if (iHierarchy->iObserverStarted)
+				{
+				iHierarchy->CompleteNotification(KErrCancel);
+				iHierarchy->StopObserver();
+				}
+			aMessage.Complete(KErrNone);
+			break;
+		case EDmObserverCancel:
+			if (iHierarchy == NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			if(!iHierarchy->iObserverSession)
+				{
+				aMessage.Complete(KDmErrBadSequence);
+				break;
+				}
+			if (iHierarchy->iObserverStarted)
+				{
+				iHierarchy->CompleteNotification(KErrCancel);
+				iHierarchy->StopObserver();
+				}
+			aMessage.Complete(KErrNone);
+			break;
+
+		case EDmObserverJoin:
+			{
+			TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
+
+			iHierarchy = manager->LookupHierarchy(hierarchyId);
+			if(iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			if(iHierarchy->iObserverSession)
+				{
+				aMessage.Complete(KDmErrBadSequence);
+				break;
+				}
+			iHierarchy->iTransitions.Reset();
+			iHierarchy->iObserverSession = this;
+			aMessage.Complete(KErrNone);
+			}
+			break;
+
+		case EDmObserverStart:
+			{
+			if (iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			
+			if(iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+				{
+				aMessage.Complete(KDmErrBadSequence); 
+				break;
+				}
+			TInt ret= iHierarchy->StartObserver((TDmDomainId)aMessage.Int0(),(TDmNotifyType)aMessage.Int1());
+			aMessage.Complete(ret);
+			}
+			break;
+
+		case EDmObserverNotify:
+			{
+			if (iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+				{
+				aMessage.Complete(KDmErrBadSequence); 
+				break;
+				}
+			//	Check to see if we have any events stored 
+			//	If so, then notify the client
+			if(iHierarchy->iTransitions.Count()>0)
+				{
+				aMessage.Complete(KErrNone);
+				break;
+				}
+			//	No events are stored. complete this message later
+			iHierarchy->SetNotifyMessage(&aMessage);
+			}
+			break;
+		
+		case EDmObserverEventCount:
+			{
+			if (iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+				{
+				aMessage.Complete(KDmErrBadSequence);
+				break;
+				}
+			TInt count = iHierarchy->iTransitions.Count();
+			aMessage.Complete(count);
+			}
+			break;
+		
+		case EDmObserverGetEvent:
+			{
+			if (iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+				{
+				aMessage.Complete(KDmErrBadSequence);
+				break;
+				}
+			TInt transitionCount = iHierarchy->iTransitions.Count();
+			TInt clientTransitionSize = aMessage.GetDesMaxLength(0);
+			TInt clientTransitionCount = clientTransitionSize / sizeof(TTransInfo);
+			__DS_ASSERT( (clientTransitionSize % sizeof(TTransInfo)) == 0);
+			__DS_ASSERT(transitionCount >= clientTransitionCount);
+			
+			HBufC8* hBuf = HBufC8::New(clientTransitionSize);
+			if(hBuf == NULL)
+				{
+				aMessage.Complete(KErrNoMemory);
+				break;
+				}
+			TPtr8 pBuf = hBuf->Des();
+			pBuf.Zero();
+			for (TInt i=0; i<clientTransitionCount; i++)
+				{
+				TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitions[0], sizeof(TTransInfo));
+				pBuf.Append(ptr);
+				iHierarchy->iTransitions.Remove(0);
+				}
+			r = aMessage.Write(0, pBuf);
+			delete hBuf;
+
+			aMessage.Complete(r);
+			}
+			break;
+		case EDmObserveredCount:
+			{
+			if (iHierarchy==NULL)
+				{
+				aMessage.Complete(KErrBadHierarchyId);
+				break;
+				}
+			if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+				{
+				aMessage.Complete(KDmErrBadSequence);
+				break;
+				}
+			aMessage.Complete(iHierarchy->iObservedChildren);
+			}
+			break;
+		default:
+			aMessage.Complete(KDmErrBadRequest);
+			break;
+		}
+	}
+
+CSession2* CDmDomainServer::NewSessionL(const TVersion&, const RMessage2&) const
+	{
+
+	return new CDmDomainSession();
+	}
+
+CSession2* CDmDomainServer::NewSessionL(const TVersion&) const
+	{
+	__DS_PANIC(KErrGeneral);
+	return 0;
+	}
+
+CDmDomainSession::~CDmDomainSession()
+	{
+	if (iPending)
+		iDomain->CompleteMemberTransition(KErrNone);
+	if (iDomain)
+		iDomain->Detach(this);
+	}
+
+void CDmDomainSession::ServiceL(const RMessage2& aMessage)
+	{
+	TInt r = KErrNone;
+	CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
+
+	switch (aMessage.Function())
+		{
+	case EDmDomainJoin:
+		{
+		TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
+		TDmDomainId domainId = (TDmDomainId) aMessage.Int1();
+
+		r = manager->LookupDomain(hierarchyId, domainId, iDomain);
+
+		if (r != KErrNone)
+			break;
+
+		// Check client has capability to join the domain
+		if (!iDomain->iJoinPolicy.CheckPolicy(aMessage))
+			{
+			r = KErrPermissionDenied;
+			iDomain = NULL;
+			break;
+			}
+
+		iDomain->Attach(this);
+		break;
+		}
+
+	case EDmStateRequestTransitionNotification:
+		iNotificationEnabled = ETrue;
+		break;
+
+	case EDmStateCancelTransitionNotification:
+		iNotificationEnabled = EFalse;
+		break;
+
+	case EDmStateAcknowledge:
+		{
+		TInt propValue = aMessage.Int0();
+		TInt error = aMessage.Int1();
+		if (!iDomain)
+			{
+			r = KDmErrNotJoin;
+			break;
+			}
+		if (iPending && iDomain->CheckPropValue(propValue))
+			{
+			iPending = EFalse;
+			iDomain->CompleteMemberTransition(error);
+			}
+		}
+		break;
+	default:
+		r = KDmErrBadRequest;
+		break;
+		}
+	aMessage.Complete(r);
+	}
+
+	
+TInt E32Main()
+	{
+	CTrapCleanup* cleanupStack = CTrapCleanup::New();
+	if(!cleanupStack)
+		__DS_PANIC(KErrNoMemory);
+
+	CActiveScheduler* sched = new CActiveScheduler();
+	if (!sched)
+		__DS_PANIC(KErrNoMemory);
+
+	CActiveScheduler::Install(sched);
+
+	CDmSvrManager* mngr = CDmSvrManager::New();
+	__DS_ASSERT(mngr);
+
+	CDmManagerServer* msrv = new CDmManagerServer(mngr);
+	if (!msrv)
+		__DS_PANIC(KErrNoMemory);
+
+	TInt r=msrv->Start(KDmManagerServerNameLit);
+	if (r != KErrNone)
+		__DS_PANIC(r);
+
+	CDmDomainServer* dsrv = new CDmDomainServer(mngr);
+	if (!dsrv)
+		__DS_PANIC(KErrNoMemory);
+
+	r=dsrv->Start(KDmDomainServerNameLit);
+	if (r != KErrNone)
+		__DS_PANIC(r);
+
+	CActiveScheduler::Start();
+
+	__DS_PANIC(0);
+
+	return KErrNone;
+	}