sipproviderplugins/sipprovider/sipconnectionplugins/src/sipscprstates.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // SIP SubConnection Provider states/transitions
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include "sipdeftscpr.h"
       
    24 #include "sipscpr.h"
       
    25 #include "sipscprstates.h"
       
    26 
       
    27 
       
    28 
       
    29 using namespace ESock;
       
    30 using namespace NetStateMachine;
       
    31 using namespace SipSCpr;
       
    32 using namespace SipSCprStates;
       
    33 
       
    34 
       
    35 //===========================================
       
    36 //
       
    37 //	SIP Sub Connection Provider States
       
    38 //
       
    39 //===========================================
       
    40 namespace SipSCprStates
       
    41 {
       
    42 
       
    43 //===================================================================================
       
    44 //
       
    45 // StartConnection Activity
       
    46 //
       
    47 //====================================================================================
       
    48 
       
    49 DEFINE_SMELEMENT(TNoTagOrAlreadyStarted,NetStateMachine::MStateFork, SipSCprStates::TContext)
       
    50 DEFINE_SMELEMENT(TStartSession, NetStateMachine::MStateTransition, SipSCprStates::TContext)
       
    51 DEFINE_SMELEMENT(TAwaitingSessionEstablished,NetStateMachine::MState, SipSCprStates::TContext)
       
    52 
       
    53 	
       
    54 TInt TNoTagOrAlreadyStarted::TransitionTag()
       
    55 	{
       
    56 	if(iContext.Node().iStage == SipSCpr::EActive)
       
    57 		{
       
    58 		return CoreNetStates::KAlreadyStarted;
       
    59 		}
       
    60 	return MeshMachine::KNoTag;
       
    61 	}
       
    62 
       
    63 void TStartSession::DoL()
       
    64 	{
       
    65 	//check error conditions before starting sip session
       
    66 	TInt stage = iContext.Node().iStage;
       
    67 	const Messages::TNodeId& self = iContext.Node().NodeId();
       
    68 	if(stage != SipSCpr::EFresh)
       
    69 		{
       
    70 		switch(stage)
       
    71 			{
       
    72 			case SipSCpr::EStopped:
       
    73 				__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start stopped subconnection")));				
       
    74 				
       
    75             	Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStart,self),TSipSCprMessages::TSipSessionEstablished(KErrAbort).CRef());	
       
    76 				break;
       
    77 			case SipSCpr::EStopping:
       
    78 				__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start stopping subconnection")));				
       
    79             	Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStart,self),TSipSCprMessages::TSipSessionEstablished(KErrAbort).CRef());	
       
    80 				break;
       
    81 			}
       
    82 		}		
       
    83 	
       
    84 	//In the case of SIP SubConnection, the session params should be be set before we start a call.
       
    85 	TSipParams& sipParams = iContext.Node().iSipSm->GetSipParams();
       
    86 	// Check should be made only to non-incoming request. For incoming request the 
       
    87 	// sipParams won't be set in SIP SCPR. The incoming params will be saved in iParameterBundle
       
    88 	TInt err;		
       
    89 	if(!(iContext.Node().iAwaitingSubConnection) && sipParams.iRequest == TSipHLConsts::ERequestNone)
       
    90 		{
       
    91 		__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start SIP subconnection if Params are notset")));
       
    92 		err = KErrNotSupported;		
       
    93 		}
       
    94 		else
       
    95 		{				
       
    96 		if (iContext.Node().subconType == RSubConnection::EWaitIncoming)
       
    97         	{    	
       
    98     		__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("appears to be an incoming call subconection, accepting")));
       
    99         	err = iContext.Node().iSipSm->AcceptCall();        
       
   100         	}
       
   101         	else
       
   102         	{        
       
   103         	err = iContext.Node().iSipSm->StartCall();			        	
       
   104         	}		
       
   105 		}
       
   106 			
       
   107 	if (KErrNone != err)
       
   108      	{
       
   109      	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start SIP subconnection if Params are notset")));       	
       
   110        	Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStart,self),TSipSCprMessages::TSipSessionEstablished(err).CRef());	
       
   111 		}
       
   112 	//Expect Response
       
   113 	iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();       
       
   114     iContext.iNodeActivity->SetPostedTo(iContext.Node().NodeId());
       
   115 	iContext.Node().iStage = SipSCpr::EStarting;
       
   116 	}	
       
   117 
       
   118 TBool TAwaitingSessionEstablished::Accept()
       
   119 	{
       
   120 	if(iContext.iMessage.IsMessage<TSipSCprMessages::TSipSessionEstablished>())	
       
   121 		{
       
   122 		TSipSCprMessages::TSipSessionEstablished* msg = Messages::message_cast<TSipSCprMessages::TSipSessionEstablished>(&iContext.iMessage);
       
   123 		if (msg->iValue == KErrNone)
       
   124 			{
       
   125 			// This means we have a successful session
       
   126 			iContext.Node().iStage = SipSCpr::EActive;
       
   127 			return ETrue;
       
   128 			}
       
   129 			else
       
   130 			{
       
   131 			//session start failed
       
   132 			//Set the error for activity and will be cleared using TClearError
       
   133 			TInt error = msg->iValue;
       
   134 			iContext.iNodeActivity->SetError(error);
       
   135 			return ETrue;							
       
   136 			}
       
   137 		}
       
   138 	
       
   139 	return EFalse;
       
   140 	}
       
   141 
       
   142 //========================================================================================================
       
   143 //
       
   144 // Stop Activiity
       
   145 //
       
   146 //========================================================================================================
       
   147 
       
   148 DEFINE_SMELEMENT(TNoTagOrAlreadyStopped, NetStateMachine::MStateFork, SipSCprStates::TContext)
       
   149 DEFINE_SMELEMENT(TStopSession, NetStateMachine::MStateTransition, SipSCprStates::TContext)
       
   150 DEFINE_SMELEMENT(TAwaitingSessionTerminated,NetStateMachine::MState, SipSCprStates::TContext)
       
   151 
       
   152 
       
   153 TInt TNoTagOrAlreadyStopped::TransitionTag()
       
   154 	{
       
   155 
       
   156 	//iStage defined only for non-deft SCPR
       
   157 	TInt stage = iContext.Node().iStage;
       
   158 	if (iContext.Node().iStage && iContext.Node().iStage >= SipSCpr::EStopping)
       
   159 		{
       
   160 		return CoreNetStates::KAlreadyStopped;	
       
   161 		}
       
   162 		return MeshMachine::KNoTag;
       
   163 	}
       
   164 
       
   165 void TStopSession::DoL()
       
   166 	{
       
   167 	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("AStopSession::DoL")));		
       
   168 
       
   169 	//there's no need to check message type before casting as it should've been checked
       
   170 	//by the State::Accept() => cast & assert if not the desired type
       
   171 	iContext.Node().iStopCode = Messages::message_cast<TCFServiceProvider::TStop>(iContext.iMessage).iValue;
       
   172 	TInt err;	
       
   173 	
       
   174 	if (iContext.Node().iStage == SipSCpr::EFresh)
       
   175 	{
       
   176 		err = KErrNotReady;
       
   177 	}
       
   178 	//If this is an incoming call that hasn't been accepted yet. We should
       
   179 	//reject it. Otherwise we should just stop it.
       
   180 	else if (iContext.Node().iAwaitingSubConnection && iContext.Node().iStage == SipSCpr::EStarting)
       
   181         {
       
   182     	err = iContext.Node().iSipSm->RejectCall();
       
   183         }
       
   184     else
       
   185         {
       
   186     	err = iContext.Node().iSipSm->StopCall();
       
   187         }
       
   188     
       
   189     if (KErrNone != err)
       
   190      	{
       
   191      	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot stop SIP subconnection if Params are notset")));
       
   192        	const Messages::TNodeId& self = iContext.Node().NodeId();
       
   193        	Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStop,self),TSipSCprMessages::TSipSessionTerminated(err).CRef());	
       
   194 		}
       
   195 		
       
   196     iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();    
       
   197     iContext.iNodeActivity->SetPostedTo(iContext.Node().NodeId());
       
   198     iContext.Node().iStage = SipSCpr::EStopping;
       
   199 	}
       
   200 	
       
   201 TBool TAwaitingSessionTerminated::Accept()
       
   202 	{		
       
   203 	if(iContext.iMessage.IsMessage<TSipSCprMessages::TSipSessionTerminated>())	
       
   204 		{
       
   205 		TSipSCprMessages::TSipSessionTerminated* msg = Messages::message_cast<TSipSCprMessages::TSipSessionTerminated>(&iContext.iMessage);
       
   206 		if (msg->iValue == KErrNone)
       
   207 			{							
       
   208 			iContext.Node().iStage = SipSCpr::EStopped;
       
   209 			return ETrue;
       
   210 			}		
       
   211 		else
       
   212 			{
       
   213 			//Set the error for activity and will be cleared using TClearError
       
   214 			TInt error = msg->iValue;
       
   215 			iContext.iNodeActivity->SetError(error);
       
   216 			return ETrue;			
       
   217 			}		
       
   218 	}
       
   219 	return EFalse;
       
   220 	}	
       
   221 
       
   222 
       
   223 //=================================================================================================
       
   224 //
       
   225 //Set Params
       
   226 //
       
   227 //==================================================================================================
       
   228 
       
   229 DEFINE_SMELEMENT(TSetParameters,NetStateMachine::MStateTransition, SipSCprStates::TContext)
       
   230 void TSetParameters::DoL()
       
   231     {	
       
   232 	TRAPD(err, iContext.Node().DoParametersAboutToBeSetL(iContext.Node().iParameterBundle));
       
   233 	if(KErrNone != err)
       
   234 		{
       
   235 		__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("call to DoParemetersAboutToBeSet failed in ASetParameters::DoL() [error=%d]"), err));
       
   236 		User::Leave(err);
       
   237 		}
       
   238 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   239     iContext.PostToSender(TCFScpr::TSetParamsResponse(iContext.Node().iParameterBundle).CRef());
       
   240 #else
       
   241     iContext.PostToSender(TCFScpr::TParamsResponse(iContext.Node().iParameterBundle).CRef());
       
   242 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   243     }
       
   244 
       
   245 
       
   246 
       
   247 DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, SipSCprStates::TContext)
       
   248 void TStoreProvision::DoL()
       
   249 	{
       
   250 	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("AStoreProvision::DoL()")));
       
   251 	PRStates::TStoreProvision storeProvision(iContext);
       
   252 	storeProvision.DoL();	
       
   253 	  		
       
   254 	const TSipCprProvisionInfo* ext = static_cast<const TSipCprProvisionInfo*>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TSipCprProvisionInfo::EUid, TSipCprProvisionInfo::ETypeId)));
       
   255 	if (ext)
       
   256     	{
       
   257     	iContext.Node().iTransitionEngine = ext->iTransitionEngine;    	
       
   258     	iContext.Node().iFromField = ext->iFromField;
       
   259     	
       
   260     	// Set the falg for WaitForIncoming connection   	
       
   261     	if (iContext.Node().iAwaitingSubConnection)
       
   262     		{
       
   263     		iContext.Node().iActivityAwaitingResponse = iContext.ActivityId();
       
   264     		}    	    	
       
   265     	// Create the SIP state machine
       
   266     	iContext.Node().CreateStateMachineL();
       
   267     	__CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("CSipSubConnectionProvider::TStoreProvision() [this=%08x]\t -- SIP State Machine created "), this));
       
   268     		
       
   269         }
       
   270 	}   
       
   271 }//namespace SipSCprStates
       
   272