sipproviderplugins/sipprovider/sipconnectionplugins/src/sipcprstates.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sipproviderplugins/sipprovider/sipconnectionplugins/src/sipcprstates.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,347 @@
+// Copyright (c) 2007-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:
+// SIP Connection Provider States/Transitions
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+ 
+
+#include "sipcprstates.h"
+#include <comms-infras/ss_subconnprov.h>
+#include <elements/nm_messages_base.h>
+#include <comms-infras/ss_nodemessages_dataclient.h>
+#include <comms-infras/ss_nodemessages_factory.h>
+
+using namespace SipCpr;
+using namespace SipCprStates;
+using namespace ESock;
+using namespace NetStateMachine;
+
+      
+namespace SipCprStates
+{
+
+//=======================================================================================================================
+//
+// BinderRequest Activity
+//
+//==========================================================================================================================
+DEFINE_SMELEMENT(TIntializeWaitForIncmgParams, NetStateMachine::MStateTransition, SipCprStates::TContext)
+void TIntializeWaitForIncmgParams::DoL()
+	{	
+	TCFServiceProvider::TCommsBinderRequest* binderReq = Messages::message_cast<TCFServiceProvider::TCommsBinderRequest>(&iContext.iMessage);
+	if (binderReq)
+    	{
+    	TSubConnOpen::TSubConnType subconType = (TSubConnOpen::TSubConnType)binderReq->iValue;
+    	iContext.Node().iSubconType = subconType;
+    	if (subconType == RSubConnection::EWaitIncoming)
+    		{
+    		iContext.Node().iConnStatus = SipCpr::EConnIncoming ;    		
+	    	}
+	    	else
+	    	{
+	    	iContext.Node().iConnStatus = SipCpr::EConnOutgoing ;    			
+	    	}    		
+    	}    	    
+	}
+	
+
+//=====================================================
+//
+// Provision Activity
+//
+//=============================================================
+DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, SipCprStates::TContext)
+void TStoreProvision::DoL()
+	{
+	__CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("AStoreProvision::DoL()")));
+	PRStates::TStoreProvision storeProvision(iContext);
+	storeProvision.DoL();
+	
+	//Retrieve profileId, appUid and ptr to TransitionEngineMgr;
+
+	const TSipMcprProvisionInfo* ext = static_cast<const TSipMcprProvisionInfo*>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TSipMcprProvisionInfo::EUid, TSipMcprProvisionInfo::ETypeId)));
+	if (ext)
+    	{
+    	iContext.Node().iProfileId = ext->iProfileId;
+    	iContext.Node().iAppUid	= ext->iAppUid;
+    	iContext.Node().iTransitionEngineMgr = ext->iTransitionEngineMgr;
+    	// Create the transition engine here so that it can be sent in
+    	// send provision to SCPR 
+    	
+    	CTransitionEngineMgr* mgr = iContext.Node().iTransitionEngineMgr;
+		TUint32 profileId = iContext.Node().iProfileId;
+    	TUid appUid = iContext.Node().GetAppUid();
+    	CSIPTransitionEngine* transitionEngine = NULL;
+		TInt err;
+		TRAP(err, transitionEngine = mgr->FindOrCreateL(appUid, profileId));
+		if(KErrNone != err)
+			{
+			__CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("ARegister::DoL: Error [%d] while executing CTransitionEngineMgr::FindOrCreate")));			
+			User::Leave(err);
+			}
+			else
+			{
+			__CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("ARegister::DoL: Transition Engine has created")));			
+			iContext.Node().iTransitionEngine = transitionEngine;
+			if (profileId == KSIPDefaultProfileId)
+				{
+				profileId = mgr->DefaultProfileId();	
+				}					
+			}		
+         }	
+	}
+	
+DEFINE_SMELEMENT(TSendProvision, NetStateMachine::MStateTransition, SipCprStates::TContext)
+void SipCprStates::TSendProvision::DoL()
+	{	 
+	//Adds the extension to Access Config which will beretrieved in 
+	// non-default SCPR and ignored in default SCPR. 	
+	iContext.Node().SetConfigL();    		    
+	
+	PRStates::TSendProvision  cprSendProvision(iContext);
+	cprSendProvision.DoL();
+	}	
+	
+//============================================================================
+//
+// Start Activity
+//
+//===========================================================================
+DEFINE_SMELEMENT(TRegisterCpr,NetStateMachine::MStateTransition, SipCprStates::TContext)
+DEFINE_SMELEMENT(TAwaitingRegistrationComplete,NetStateMachine::MState, SipCprStates::TContext)
+DEFINE_SMELEMENT(TAwaitingIncomingConnection,NetStateMachine::MState, SipCprStates::TContext)
+DEFINE_SMELEMENT(TSetPostedToScpr,NetStateMachine::MStateTransition, SipCprStates::TContext)
+
+void TSetPostedToScpr::DoL()
+	{
+	// Get the SCPR node ID and wait for the IncomingConneciton message from him
+	Messages::RNodeInterface* client = iContext.iNode.FindClient(Messages::message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage).iNodeId);
+	if (client)
+		{
+		iContext.iNodeActivity->SetPostedTo(client->RecipientId());	
+		}	
+	}
+
+void TRegisterCpr::DoL()
+	{	
+	//check if profile ID has been set by passed by MCPR
+	//if no profile Id was paseed as part of conn preferences
+	//profile id is set to KSIPDefaultProfileId (which is a filler because 0 wont work)
+	if (iContext.Node().iProfileId == KSIPDefaultProfileId)
+		{
+		iContext.Node().iProfileId = iContext.Node().iTransitionEngineMgr->DefaultProfileId();	
+		}
+	// Call the SIP High-level API for the Registration
+	if (iContext.Node().iTransitionEngine == NULL)
+		{				
+		iContext.iNodeActivity->SetError(KErrNotFound);
+		
+		const Messages::TNodeId& self = iContext.Node().Id();		
+		// Post RegistrationComplete msg with error set
+		Messages::RClientInterface::OpenPostMessageClose(self,self,TSipCprMessages::TRegistrationComplete(KErrNotFound).CRef());				
+		}
+		else
+		{
+		iContext.Node().iTransitionEngine->RegisterL(&(iContext.Node()));
+		iContext.Node().iStage = SipCpr::EStarting;		
+		}
+	//Expect Response
+    iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();
+    iContext.iNodeActivity->SetPostedTo(iContext.Node().Id());			
+	}	
+	
+TBool TAwaitingIncomingConnection::Accept()
+	{
+	if(iContext.iMessage.IsMessage<TSipCprMessages::TIncomingConnection>())		
+		{		
+		// reset it to the initial value so that so that it is taken care in next time
+		// around. That i.e after Rconn.Waitforincoming() if subcon open is called 
+		// on Rcon like subcon.open(Rcon) then it run into problems. 
+		iContext.Node().iConnStatus = SipCpr::EConnOutgoing ;		
+		return ETrue;
+		}
+	return EFalse;					
+	}
+
+TBool TAwaitingRegistrationComplete::Accept()
+	{	
+	if(iContext.iMessage.IsMessage<TSipCprMessages::TRegistrationComplete>())	
+		{
+		TSipCprMessages::TRegistrationComplete* msg = Messages::message_cast<TSipCprMessages::TRegistrationComplete>(&iContext.iMessage);
+		if (msg->iValue == KErrNone)
+			{
+			iContext.Node().iStage = SipCpr::EActive;			
+			}
+			else
+			{
+			//Set the error for activity and will be raised
+			TInt error = msg->iValue;
+			iContext.iNodeActivity->SetError(error);			
+			}
+		
+		return ETrue;	
+		}
+	return EFalse;
+	}
+
+DEFINE_SMELEMENT(TNoTagOrRegistered,NetStateMachine::MStateFork, SipCprStates::TContext)
+TInt TNoTagOrRegistered::TransitionTag()
+	{
+	if(iContext.Node().iStage == SipCpr::EActive)
+		{
+		return SipCprStates::KRegistered;
+		}
+	return MeshMachine::KNoTag;
+	}
+	
+//===============================================================================
+//
+// Stop Activity
+//
+//===============================================================================  
+
+DEFINE_SMELEMENT(TDeRegisterCpr,NetStateMachine::MStateTransition, SipCprStates::TContext)
+DEFINE_SMELEMENT(TAwaitingDeRegistrationComplete,NetStateMachine::MState, SipCprStates::TContext)
+
+void TDeRegisterCpr::DoL()
+	{
+	// Call the SIP high level API for de-registraiton
+	iContext.Node().iTransitionEngine->Deregister(&(iContext.Node()));	
+	if(iContext.Node().iStage <= SipCpr::EStopping)
+		{
+		//We haven't recieved a DeRegister Request yet
+		iContext.Node().iStage = SipCpr::EStopping;
+		}
+	
+	//Expect Response
+    iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();
+    iContext.iNodeActivity->SetPostedTo(iContext.Node().NodeId());
+	}
+	
+	
+TBool TAwaitingDeRegistrationComplete::Accept()
+	{
+	//catch only messages generated by the SIPCPR 
+	ASSERT(iContext.iSender == iContext.Node().Id());
+	if(iContext.iMessage.IsMessage<TSipCprMessages::TDeRegistrationComplete>())
+		{
+		TSipCprMessages::TDeRegistrationComplete* msg = Messages::message_cast<TSipCprMessages::TDeRegistrationComplete>(&iContext.iMessage);
+		if (msg->iValue == KErrNone)
+			{
+			iContext.Node().iStage = SipCpr::EStopped;
+			}
+			else
+			{
+			//Set the error for activity so that it can be forwarded to applicaiton
+			TInt error = msg->iValue;
+			iContext.iNodeActivity->SetError(error);				
+			}
+		return ETrue;	
+		}
+	return EFalse;	
+	}
+
+/*
+DEFINE_SMELEMENT(TSendStopped,NetStateMachine::MStateTransition, SipCprStates::TContext)
+void TSendStopped::DoL()
+	{
+	
+	TInt stopCode = iContext.Node().iStashedStoppedCode;
+		//the section below is reproduced intoto from the CoreStates::TSendStopped :-)
+	TCFMessage::TStopped msg(iContext.iNode(), iContext.iCFMessageSig.ActivityId(), stopCode);
+	if (iContext.iNodeActivity)
+		{
+		iContext.iNodeActivity->PostToOriginators(msg);
+		}
+	else
+		{
+		//This transition can also be used from a single tripple activity
+		ASSERT(iContext.iCFMessageSig.iPeer); //Always a peer message
+		iContext.iCFMessageSig.iPeer->PostMessage(msg);
+		}
+	if (iContext.Node().CountActivities(ECFActivityStart) == 0)
+    	{
+        TCFMessage::TGoneDown goneDown(iContext.iNode(), ECFActivityNull, stopCode);
+        TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(RNodeInterface::ECtrl);
+       	for (TInt i = 0; iter[i]; i++)
+           	{
+           	//Send TGoneDown to every Ctrl client except the originator (who would be recieving TStopped)
+           	if ((iContext.iNodeActivity && iContext.iNodeActivity->FindOriginator(*iter[i]) != KErrNone) ||
+           	    (iContext.iNodeActivity == NULL && iter[i] != iContext.iCFMessageSig.iPeer))
+               	{
+               	iter[i]->PostMessage(goneDown);
+               	}
+           	}
+    	}
+	if (iContext.iNodeActivity)
+    	{
+        iContext.iNodeActivity->SetError(KErrNone);
+    	}
+	}
+*/	
+
+/**
+Comms-binder activity will use this function. 
+It returns KWaitForIncoming if the connection type is WaitForIncoming
+otherwise returns KUseExisting
+*/
+DEFINE_SMELEMENT(TWaitForIncomingOrUseExisting,NetStateMachine::MStateFork, SipCprStates::TContext)
+TInt TWaitForIncomingOrUseExisting::TransitionTag()
+	{
+	if(iContext.Node().iConnStatus == SipCpr::EConnIncoming)
+		{
+		return CoreNetStates::KWaitForIncoming;
+		}
+		else
+		{		
+		return CoreStates::KUseExisting;
+		}
+	}
+		
+DEFINE_SMELEMENT(TNoTagOrDeRegister,NetStateMachine::MStateFork, SipCprStates::TContext)
+TInt TNoTagOrDeRegister::TransitionTag()
+	{	
+	MeshMachine::CNodeActivityBase* activity = iContext.iNodeActivity;
+	Messages::TSignatureBase& message = iContext.iMessage;
+	TInt code = KErrCancel;
+	if (activity && activity->Error() != KErrNone)
+        {
+        code = activity->Error();
+        }
+    
+	if (message.IsTypeOf(Messages::TSigNumber::TypeId()))
+		{
+   		code = static_cast<const Messages::TSigNumber&>(message).iValue;
+   		}
+    else if (message.IsTypeOf(Messages::TSigNumberNumber::TypeId()))
+		{
+   		code = static_cast<const Messages::TSigNumberNumber&>(message).iValue1;
+   		}
+	
+	//stash the stop code to be used after we get DeRegistrationComplete
+	iContext.Node().iStashedStoppedCode = code;
+	
+	//Now do the regular fork
+	if(iContext.Node().iStage == SipCpr::EActive)
+		{
+		return SipCprStates::KDeRegister;
+		}
+	return MeshMachine::KNoTag;
+	}	
+}// namespace SipCprStates