datacommsserver/esockserver/core_states/ss_esockactivities.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/core_states/ss_esockactivities.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,210 @@
+// Copyright (c) 2006-2009 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:
+// ESock Sub Session Activities
+// THIS API IS INTERNAL TO NETWORKING AND IS SUBJECT TO CHANGE AND NOT FOR EXTERNAL USE
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <comms-infras/ss_log.h>
+#include <comms-infras/ss_nodemessages.h>
+#include <ss_std.h>
+#include <comms-infras/ss_esockstates.h>
+#include "ss_esockactivities.h"
+
+
+#ifdef _DEBUG
+// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
+// (if it could happen through user error then you should give it an explicit, documented, category + code)
+_LIT(KSpecAssert_ESockCrStaESclAC, "ESockCrStaESclAC");
+#endif
+
+#if defined LOG || defined ESOCK_EXTLOG_ACTIVE
+	#define KESockActivityTag KESockCoreProviderTag
+	_LIT8(KESockActivitySubTag, "esockactivity");
+#endif
+
+using namespace NetStateMachine;
+using namespace SubSessStates;
+using namespace SubSessActivities;
+using namespace MeshMachine;
+using namespace ESock;
+
+//
+//CESockClientActivityBase
+MeshMachine::CNodeActivityBase* CESockClientActivityBase::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	{
+	return new (ELeave) CESockClientActivityBase(aActivitySig,aNode);
+	}
+
+CESockClientActivityBase::~CESockClientActivityBase()
+	{
+	if (!iMessage.IsNull())
+		{ //Can be NULL only if the client has been panicked and we do not want to complete it
+		__ASSERT_DEBUG(iSubSession, User::Panic(KSpecAssert_ESockCrStaESclAC, 1));
+
+		LOG(ESockLogExternal::Printf(KESockActivityTag, KESockActivitySubTag, _L8("~CESockClientActivityBase %08x:\tRMessage2::Complete (%08x) with %d."), this, iMessage.Handle(), Error()));
+		iMessage.Complete(Error());
+		}
+	SetError(KErrNone);
+	}
+
+void CESockClientActivityBase::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const TStateTriple& aFirst)
+	{
+	//We should not be starting when the close activity is running!
+	__ASSERT_DEBUG(ActivityId()==ECFActivityDestroy || aContext.iNode.CountActivities(ECFActivityDestroy)==0, User::Panic(KSpecAssert_ESockCrStaESclAC, 2));
+
+	//Very important for client activities is to allow only one outstanding request at a time.
+	//This is achieved by allowing only the first originator to start such activity
+	if (iOriginators.Count())
+		{
+		MESH_LOG_CONTEXT_EXT(KESockMeshMachine, aContext, _L8("ERROR: CESockClientActivityBase::StartL->One outstanding request allowed"));
+		User::Leave(KErrInUse);
+		}
+
+	//Either we are the close activity or there can not be close running when this activity is started
+	__ASSERT_DEBUG(ActivitySigId()==ECFActivityDestroy || aContext.iNode.CountActivities(ECFActivityDestroy)==0, User::Panic(KSpecAssert_ESockCrStaESclAC, 3));
+
+  	iOriginators.AppendL(aOriginator);
+
+	MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CESockClientActivityBase %08x:\tStartL->starting activity"), this));
+	__ASSERT_DEBUG(IsIdle(), User::Panic(KSpecAssert_ESockCrStaESclAC, 4));
+	NetStateMachine::ACore::Start(&aContext, aFirst);
+
+	MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CESockClientActivityBase %08x:\tStartL->activity started"), this));
+	}
+
+void CESockClientActivityBase::AcquireOwnership(RMessage2& aMessage, CSockSubSession& aSubSession)
+	{
+	__ASSERT_DEBUG(iMessage.IsNull(), User::Panic(KSpecAssert_ESockCrStaESclAC, 5));
+	__ASSERT_DEBUG(!iSubSession, User::Panic(KSpecAssert_ESockCrStaESclAC, 6));
+	iMessage = aMessage;
+	aMessage = RMessage2(); //Null the original message
+	iSubSession = &aSubSession;
+	LOG(ESockLogExternal::Printf(KESockActivityTag, KESockActivitySubTag, _L8("CESockClientActivityBase %08x:\tRMessage2 ownership taken! RMessage2(%08x), SubSession(%08x), ActivityId(%d)"), this, iMessage.Handle(), &aSubSession, ActivityId()));
+	aSubSession.DontCompleteCurrentRequest();
+	}
+
+void CESockClientActivityBase::PanicClient(TESockPanic aPanic)
+	{
+	__ASSERT_DEBUG(!iMessage.IsNull(), User::Panic(KSpecAssert_ESockCrStaESclAC, 7));
+	__ASSERT_DEBUG(iSubSession, User::Panic(KSpecAssert_ESockCrStaESclAC, 8));
+	RThread t;
+	iMessage.Client(t);
+	TExitType exittype=t.ExitType();
+	t.Close();
+	if(exittype == EExitPending) // is client alive?
+		{
+		LOG(ESockLogExternal::Printf(KESockActivityTag, KESockActivitySubTag, _L8("CESockClientActivityBase::PanicClient\tRMessage2(%08x), Reason=%d"), iMessage.Handle(), aPanic));
+		iMessage.Panic(KESockClientPanic, aPanic);
+		}
+	iMessage = RMessage2(); //Clear the message so that it does not get completed
+	iSubSession = NULL;
+	}
+
+void CESockClientActivityBase::ReadL(TInt aSrcParamIndex, TDes8& aDes)
+	{
+	__ASSERT_DEBUG(!iMessage.IsNull(), User::Panic(KSpecAssert_ESockCrStaESclAC, 9)); //Read only after it has been initialised!
+	TInt err = iMessage.Read(aSrcParamIndex, aDes);
+	if (err!=KErrNone)
+		{
+		PanicClient(ESockBadHandle);
+		User::Leave(err);
+		}
+	}
+
+TInt CESockClientActivityBase::GetDesLengthL(TInt aSrcParamIndex)
+	{
+ 	__ASSERT_DEBUG(!iMessage.IsNull(), User::Panic(KSpecAssert_ESockCrStaESclAC, 10));
+ 	return iMessage.GetDesLengthL(aSrcParamIndex);
+	}
+
+TInt CESockClientActivityBase::GetDesMaxLengthL(TInt aSrcParamIndex)
+	{
+ 	__ASSERT_DEBUG(!iMessage.IsNull(), User::Panic(KSpecAssert_ESockCrStaESclAC, 11));
+ 	return iMessage.GetDesMaxLengthL(aSrcParamIndex);
+	}
+
+void CESockClientActivityBase::WriteL(TInt aSrcParamIndex, TDes8& aDes)
+	{
+	iMessage.WriteL(aSrcParamIndex,aDes);
+	}
+
+TInt CESockClientActivityBase::Function()
+	{
+	return iMessage.Function();
+	}
+
+void CESockClientActivityBase::HasCapabilityL(TCapability aCapability, const char* aDiagnosticMessage)
+    {
+    return iMessage.HasCapabilityL(aCapability, aDiagnosticMessage);
+    }
+
+
+
+
+//
+//CPreallocatedESockClientActivity
+MeshMachine::CNodeActivityBase* CPreallocatedESockClientActivity::New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	{
+	TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CPreallocatedESockClientActivity));
+	CPreallocatedESockClientActivity* self = new (space) CPreallocatedESockClientActivity(aActivitySig, aNode);
+	self->InsertPreallocatedDestroyActivity();
+	return self;
+	}
+
+CPreallocatedESockClientActivity::CPreallocatedESockClientActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+:	CESockClientActivityBase(aActivitySig,aNode),
+	APreallocatedOriginators<1>(iOriginators)
+	{
+	}
+
+void CPreallocatedESockClientActivity::Destroy()
+	{
+	ReturnPreallocatedSpace(this);
+	this->~CPreallocatedESockClientActivity(); //Run the destructor
+	}
+
+
+
+
+//
+//CCloseActivity
+MeshMachine::CNodeActivityBase* CCloseActivity::New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+	{
+	TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CCloseActivity));
+	CCloseActivity* self = new (space) CCloseActivity(aActivitySig, aNode);
+	self->InsertPreallocatedDestroyActivity();
+	return self;
+	}
+
+CCloseActivity::CCloseActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+:	CESockClientActivityBase(aActivitySig,aNode),
+	APreallocatedOriginators<1>(iOriginators)
+	{
+	}
+
+void CCloseActivity::Destroy()
+	{
+	ReturnPreallocatedSpace(this);
+	this->~CCloseActivity(); //Run the destructor
+
+	ESock::CMMSockSubSession* subSessNode = static_cast<ESock::CMMSockSubSession*>(&iNode);
+	delete subSessNode; //We are taking down the whole node. All relevant diagnostics and logging is done from MeshMachine::AMMNodeBase::~MeshMachine::AMMNodeBase().
+	}
+