sipproviderplugins/sipprovider/sipconnectionplugins/src/sipscprstates.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sipproviderplugins/sipprovider/sipconnectionplugins/src/sipscprstates.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,272 @@
+// 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 SubConnection Provider states/transitions
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "sipdeftscpr.h"
+#include "sipscpr.h"
+#include "sipscprstates.h"
+
+
+
+using namespace ESock;
+using namespace NetStateMachine;
+using namespace SipSCpr;
+using namespace SipSCprStates;
+
+
+//===========================================
+//
+//	SIP Sub Connection Provider States
+//
+//===========================================
+namespace SipSCprStates
+{
+
+//===================================================================================
+//
+// StartConnection Activity
+//
+//====================================================================================
+
+DEFINE_SMELEMENT(TNoTagOrAlreadyStarted,NetStateMachine::MStateFork, SipSCprStates::TContext)
+DEFINE_SMELEMENT(TStartSession, NetStateMachine::MStateTransition, SipSCprStates::TContext)
+DEFINE_SMELEMENT(TAwaitingSessionEstablished,NetStateMachine::MState, SipSCprStates::TContext)
+
+	
+TInt TNoTagOrAlreadyStarted::TransitionTag()
+	{
+	if(iContext.Node().iStage == SipSCpr::EActive)
+		{
+		return CoreNetStates::KAlreadyStarted;
+		}
+	return MeshMachine::KNoTag;
+	}
+
+void TStartSession::DoL()
+	{
+	//check error conditions before starting sip session
+	TInt stage = iContext.Node().iStage;
+	const Messages::TNodeId& self = iContext.Node().NodeId();
+	if(stage != SipSCpr::EFresh)
+		{
+		switch(stage)
+			{
+			case SipSCpr::EStopped:
+				__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start stopped subconnection")));				
+				
+            	Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStart,self),TSipSCprMessages::TSipSessionEstablished(KErrAbort).CRef());	
+				break;
+			case SipSCpr::EStopping:
+				__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start stopping subconnection")));				
+            	Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStart,self),TSipSCprMessages::TSipSessionEstablished(KErrAbort).CRef());	
+				break;
+			}
+		}		
+	
+	//In the case of SIP SubConnection, the session params should be be set before we start a call.
+	TSipParams& sipParams = iContext.Node().iSipSm->GetSipParams();
+	// Check should be made only to non-incoming request. For incoming request the 
+	// sipParams won't be set in SIP SCPR. The incoming params will be saved in iParameterBundle
+	TInt err;		
+	if(!(iContext.Node().iAwaitingSubConnection) && sipParams.iRequest == TSipHLConsts::ERequestNone)
+		{
+		__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start SIP subconnection if Params are notset")));
+		err = KErrNotSupported;		
+		}
+		else
+		{				
+		if (iContext.Node().subconType == RSubConnection::EWaitIncoming)
+        	{    	
+    		__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("appears to be an incoming call subconection, accepting")));
+        	err = iContext.Node().iSipSm->AcceptCall();        
+        	}
+        	else
+        	{        
+        	err = iContext.Node().iSipSm->StartCall();			        	
+        	}		
+		}
+			
+	if (KErrNone != err)
+     	{
+     	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start SIP subconnection if Params are notset")));       	
+       	Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStart,self),TSipSCprMessages::TSipSessionEstablished(err).CRef());	
+		}
+	//Expect Response
+	iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();       
+    iContext.iNodeActivity->SetPostedTo(iContext.Node().NodeId());
+	iContext.Node().iStage = SipSCpr::EStarting;
+	}	
+
+TBool TAwaitingSessionEstablished::Accept()
+	{
+	if(iContext.iMessage.IsMessage<TSipSCprMessages::TSipSessionEstablished>())	
+		{
+		TSipSCprMessages::TSipSessionEstablished* msg = Messages::message_cast<TSipSCprMessages::TSipSessionEstablished>(&iContext.iMessage);
+		if (msg->iValue == KErrNone)
+			{
+			// This means we have a successful session
+			iContext.Node().iStage = SipSCpr::EActive;
+			return ETrue;
+			}
+			else
+			{
+			//session start failed
+			//Set the error for activity and will be cleared using TClearError
+			TInt error = msg->iValue;
+			iContext.iNodeActivity->SetError(error);
+			return ETrue;							
+			}
+		}
+	
+	return EFalse;
+	}
+
+//========================================================================================================
+//
+// Stop Activiity
+//
+//========================================================================================================
+
+DEFINE_SMELEMENT(TNoTagOrAlreadyStopped, NetStateMachine::MStateFork, SipSCprStates::TContext)
+DEFINE_SMELEMENT(TStopSession, NetStateMachine::MStateTransition, SipSCprStates::TContext)
+DEFINE_SMELEMENT(TAwaitingSessionTerminated,NetStateMachine::MState, SipSCprStates::TContext)
+
+
+TInt TNoTagOrAlreadyStopped::TransitionTag()
+	{
+
+	//iStage defined only for non-deft SCPR
+	TInt stage = iContext.Node().iStage;
+	if (iContext.Node().iStage && iContext.Node().iStage >= SipSCpr::EStopping)
+		{
+		return CoreNetStates::KAlreadyStopped;	
+		}
+		return MeshMachine::KNoTag;
+	}
+
+void TStopSession::DoL()
+	{
+	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("AStopSession::DoL")));		
+
+	//there's no need to check message type before casting as it should've been checked
+	//by the State::Accept() => cast & assert if not the desired type
+	iContext.Node().iStopCode = Messages::message_cast<TCFServiceProvider::TStop>(iContext.iMessage).iValue;
+	TInt err;	
+	
+	if (iContext.Node().iStage == SipSCpr::EFresh)
+	{
+		err = KErrNotReady;
+	}
+	//If this is an incoming call that hasn't been accepted yet. We should
+	//reject it. Otherwise we should just stop it.
+	else if (iContext.Node().iAwaitingSubConnection && iContext.Node().iStage == SipSCpr::EStarting)
+        {
+    	err = iContext.Node().iSipSm->RejectCall();
+        }
+    else
+        {
+    	err = iContext.Node().iSipSm->StopCall();
+        }
+    
+    if (KErrNone != err)
+     	{
+     	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot stop SIP subconnection if Params are notset")));
+       	const Messages::TNodeId& self = iContext.Node().NodeId();
+       	Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStop,self),TSipSCprMessages::TSipSessionTerminated(err).CRef());	
+		}
+		
+    iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();    
+    iContext.iNodeActivity->SetPostedTo(iContext.Node().NodeId());
+    iContext.Node().iStage = SipSCpr::EStopping;
+	}
+	
+TBool TAwaitingSessionTerminated::Accept()
+	{		
+	if(iContext.iMessage.IsMessage<TSipSCprMessages::TSipSessionTerminated>())	
+		{
+		TSipSCprMessages::TSipSessionTerminated* msg = Messages::message_cast<TSipSCprMessages::TSipSessionTerminated>(&iContext.iMessage);
+		if (msg->iValue == KErrNone)
+			{							
+			iContext.Node().iStage = SipSCpr::EStopped;
+			return ETrue;
+			}		
+		else
+			{
+			//Set the error for activity and will be cleared using TClearError
+			TInt error = msg->iValue;
+			iContext.iNodeActivity->SetError(error);
+			return ETrue;			
+			}		
+	}
+	return EFalse;
+	}	
+
+
+//=================================================================================================
+//
+//Set Params
+//
+//==================================================================================================
+
+DEFINE_SMELEMENT(TSetParameters,NetStateMachine::MStateTransition, SipSCprStates::TContext)
+void TSetParameters::DoL()
+    {	
+	TRAPD(err, iContext.Node().DoParametersAboutToBeSetL(iContext.Node().iParameterBundle));
+	if(KErrNone != err)
+		{
+		__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("call to DoParemetersAboutToBeSet failed in ASetParameters::DoL() [error=%d]"), err));
+		User::Leave(err);
+		}
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+    iContext.PostToSender(TCFScpr::TSetParamsResponse(iContext.Node().iParameterBundle).CRef());
+#else
+    iContext.PostToSender(TCFScpr::TParamsResponse(iContext.Node().iParameterBundle).CRef());
+#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+    }
+
+
+
+DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, SipSCprStates::TContext)
+void TStoreProvision::DoL()
+	{
+	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("AStoreProvision::DoL()")));
+	PRStates::TStoreProvision storeProvision(iContext);
+	storeProvision.DoL();	
+	  		
+	const TSipCprProvisionInfo* ext = static_cast<const TSipCprProvisionInfo*>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TSipCprProvisionInfo::EUid, TSipCprProvisionInfo::ETypeId)));
+	if (ext)
+    	{
+    	iContext.Node().iTransitionEngine = ext->iTransitionEngine;    	
+    	iContext.Node().iFromField = ext->iFromField;
+    	
+    	// Set the falg for WaitForIncoming connection   	
+    	if (iContext.Node().iAwaitingSubConnection)
+    		{
+    		iContext.Node().iActivityAwaitingResponse = iContext.ActivityId();
+    		}    	    	
+    	// Create the SIP state machine
+    	iContext.Node().CreateStateMachineL();
+    	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("CSipSubConnectionProvider::TStoreProvision() [this=%08x]\t -- SIP State Machine created "), this));
+    		
+        }
+	}   
+}//namespace SipSCprStates
+