sipproviderplugins/sipprovider/sipconnectionplugins/src/sipcprstates.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 Connection Provider States/Transitions
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22  
       
    23 
       
    24 #include "sipcprstates.h"
       
    25 #include <comms-infras/ss_subconnprov.h>
       
    26 #include <elements/nm_messages_base.h>
       
    27 #include <comms-infras/ss_nodemessages_dataclient.h>
       
    28 #include <comms-infras/ss_nodemessages_factory.h>
       
    29 
       
    30 using namespace SipCpr;
       
    31 using namespace SipCprStates;
       
    32 using namespace ESock;
       
    33 using namespace NetStateMachine;
       
    34 
       
    35       
       
    36 namespace SipCprStates
       
    37 {
       
    38 
       
    39 //=======================================================================================================================
       
    40 //
       
    41 // BinderRequest Activity
       
    42 //
       
    43 //==========================================================================================================================
       
    44 DEFINE_SMELEMENT(TIntializeWaitForIncmgParams, NetStateMachine::MStateTransition, SipCprStates::TContext)
       
    45 void TIntializeWaitForIncmgParams::DoL()
       
    46 	{	
       
    47 	TCFServiceProvider::TCommsBinderRequest* binderReq = Messages::message_cast<TCFServiceProvider::TCommsBinderRequest>(&iContext.iMessage);
       
    48 	if (binderReq)
       
    49     	{
       
    50     	TSubConnOpen::TSubConnType subconType = (TSubConnOpen::TSubConnType)binderReq->iValue;
       
    51     	iContext.Node().iSubconType = subconType;
       
    52     	if (subconType == RSubConnection::EWaitIncoming)
       
    53     		{
       
    54     		iContext.Node().iConnStatus = SipCpr::EConnIncoming ;    		
       
    55 	    	}
       
    56 	    	else
       
    57 	    	{
       
    58 	    	iContext.Node().iConnStatus = SipCpr::EConnOutgoing ;    			
       
    59 	    	}    		
       
    60     	}    	    
       
    61 	}
       
    62 	
       
    63 
       
    64 //=====================================================
       
    65 //
       
    66 // Provision Activity
       
    67 //
       
    68 //=============================================================
       
    69 DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, SipCprStates::TContext)
       
    70 void TStoreProvision::DoL()
       
    71 	{
       
    72 	__CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("AStoreProvision::DoL()")));
       
    73 	PRStates::TStoreProvision storeProvision(iContext);
       
    74 	storeProvision.DoL();
       
    75 	
       
    76 	//Retrieve profileId, appUid and ptr to TransitionEngineMgr;
       
    77 
       
    78 	const TSipMcprProvisionInfo* ext = static_cast<const TSipMcprProvisionInfo*>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TSipMcprProvisionInfo::EUid, TSipMcprProvisionInfo::ETypeId)));
       
    79 	if (ext)
       
    80     	{
       
    81     	iContext.Node().iProfileId = ext->iProfileId;
       
    82     	iContext.Node().iAppUid	= ext->iAppUid;
       
    83     	iContext.Node().iTransitionEngineMgr = ext->iTransitionEngineMgr;
       
    84     	// Create the transition engine here so that it can be sent in
       
    85     	// send provision to SCPR 
       
    86     	
       
    87     	CTransitionEngineMgr* mgr = iContext.Node().iTransitionEngineMgr;
       
    88 		TUint32 profileId = iContext.Node().iProfileId;
       
    89     	TUid appUid = iContext.Node().GetAppUid();
       
    90     	CSIPTransitionEngine* transitionEngine = NULL;
       
    91 		TInt err;
       
    92 		TRAP(err, transitionEngine = mgr->FindOrCreateL(appUid, profileId));
       
    93 		if(KErrNone != err)
       
    94 			{
       
    95 			__CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("ARegister::DoL: Error [%d] while executing CTransitionEngineMgr::FindOrCreate")));			
       
    96 			User::Leave(err);
       
    97 			}
       
    98 			else
       
    99 			{
       
   100 			__CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("ARegister::DoL: Transition Engine has created")));			
       
   101 			iContext.Node().iTransitionEngine = transitionEngine;
       
   102 			if (profileId == KSIPDefaultProfileId)
       
   103 				{
       
   104 				profileId = mgr->DefaultProfileId();	
       
   105 				}					
       
   106 			}		
       
   107          }	
       
   108 	}
       
   109 	
       
   110 DEFINE_SMELEMENT(TSendProvision, NetStateMachine::MStateTransition, SipCprStates::TContext)
       
   111 void SipCprStates::TSendProvision::DoL()
       
   112 	{	 
       
   113 	//Adds the extension to Access Config which will beretrieved in 
       
   114 	// non-default SCPR and ignored in default SCPR. 	
       
   115 	iContext.Node().SetConfigL();    		    
       
   116 	
       
   117 	PRStates::TSendProvision  cprSendProvision(iContext);
       
   118 	cprSendProvision.DoL();
       
   119 	}	
       
   120 	
       
   121 //============================================================================
       
   122 //
       
   123 // Start Activity
       
   124 //
       
   125 //===========================================================================
       
   126 DEFINE_SMELEMENT(TRegisterCpr,NetStateMachine::MStateTransition, SipCprStates::TContext)
       
   127 DEFINE_SMELEMENT(TAwaitingRegistrationComplete,NetStateMachine::MState, SipCprStates::TContext)
       
   128 DEFINE_SMELEMENT(TAwaitingIncomingConnection,NetStateMachine::MState, SipCprStates::TContext)
       
   129 DEFINE_SMELEMENT(TSetPostedToScpr,NetStateMachine::MStateTransition, SipCprStates::TContext)
       
   130 
       
   131 void TSetPostedToScpr::DoL()
       
   132 	{
       
   133 	// Get the SCPR node ID and wait for the IncomingConneciton message from him
       
   134 	Messages::RNodeInterface* client = iContext.iNode.FindClient(Messages::message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage).iNodeId);
       
   135 	if (client)
       
   136 		{
       
   137 		iContext.iNodeActivity->SetPostedTo(client->RecipientId());	
       
   138 		}	
       
   139 	}
       
   140 
       
   141 void TRegisterCpr::DoL()
       
   142 	{	
       
   143 	//check if profile ID has been set by passed by MCPR
       
   144 	//if no profile Id was paseed as part of conn preferences
       
   145 	//profile id is set to KSIPDefaultProfileId (which is a filler because 0 wont work)
       
   146 	if (iContext.Node().iProfileId == KSIPDefaultProfileId)
       
   147 		{
       
   148 		iContext.Node().iProfileId = iContext.Node().iTransitionEngineMgr->DefaultProfileId();	
       
   149 		}
       
   150 	// Call the SIP High-level API for the Registration
       
   151 	if (iContext.Node().iTransitionEngine == NULL)
       
   152 		{				
       
   153 		iContext.iNodeActivity->SetError(KErrNotFound);
       
   154 		
       
   155 		const Messages::TNodeId& self = iContext.Node().Id();		
       
   156 		// Post RegistrationComplete msg with error set
       
   157 		Messages::RClientInterface::OpenPostMessageClose(self,self,TSipCprMessages::TRegistrationComplete(KErrNotFound).CRef());				
       
   158 		}
       
   159 		else
       
   160 		{
       
   161 		iContext.Node().iTransitionEngine->RegisterL(&(iContext.Node()));
       
   162 		iContext.Node().iStage = SipCpr::EStarting;		
       
   163 		}
       
   164 	//Expect Response
       
   165     iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();
       
   166     iContext.iNodeActivity->SetPostedTo(iContext.Node().Id());			
       
   167 	}	
       
   168 	
       
   169 TBool TAwaitingIncomingConnection::Accept()
       
   170 	{
       
   171 	if(iContext.iMessage.IsMessage<TSipCprMessages::TIncomingConnection>())		
       
   172 		{		
       
   173 		// reset it to the initial value so that so that it is taken care in next time
       
   174 		// around. That i.e after Rconn.Waitforincoming() if subcon open is called 
       
   175 		// on Rcon like subcon.open(Rcon) then it run into problems. 
       
   176 		iContext.Node().iConnStatus = SipCpr::EConnOutgoing ;		
       
   177 		return ETrue;
       
   178 		}
       
   179 	return EFalse;					
       
   180 	}
       
   181 
       
   182 TBool TAwaitingRegistrationComplete::Accept()
       
   183 	{	
       
   184 	if(iContext.iMessage.IsMessage<TSipCprMessages::TRegistrationComplete>())	
       
   185 		{
       
   186 		TSipCprMessages::TRegistrationComplete* msg = Messages::message_cast<TSipCprMessages::TRegistrationComplete>(&iContext.iMessage);
       
   187 		if (msg->iValue == KErrNone)
       
   188 			{
       
   189 			iContext.Node().iStage = SipCpr::EActive;			
       
   190 			}
       
   191 			else
       
   192 			{
       
   193 			//Set the error for activity and will be raised
       
   194 			TInt error = msg->iValue;
       
   195 			iContext.iNodeActivity->SetError(error);			
       
   196 			}
       
   197 		
       
   198 		return ETrue;	
       
   199 		}
       
   200 	return EFalse;
       
   201 	}
       
   202 
       
   203 DEFINE_SMELEMENT(TNoTagOrRegistered,NetStateMachine::MStateFork, SipCprStates::TContext)
       
   204 TInt TNoTagOrRegistered::TransitionTag()
       
   205 	{
       
   206 	if(iContext.Node().iStage == SipCpr::EActive)
       
   207 		{
       
   208 		return SipCprStates::KRegistered;
       
   209 		}
       
   210 	return MeshMachine::KNoTag;
       
   211 	}
       
   212 	
       
   213 //===============================================================================
       
   214 //
       
   215 // Stop Activity
       
   216 //
       
   217 //===============================================================================  
       
   218 
       
   219 DEFINE_SMELEMENT(TDeRegisterCpr,NetStateMachine::MStateTransition, SipCprStates::TContext)
       
   220 DEFINE_SMELEMENT(TAwaitingDeRegistrationComplete,NetStateMachine::MState, SipCprStates::TContext)
       
   221 
       
   222 void TDeRegisterCpr::DoL()
       
   223 	{
       
   224 	// Call the SIP high level API for de-registraiton
       
   225 	iContext.Node().iTransitionEngine->Deregister(&(iContext.Node()));	
       
   226 	if(iContext.Node().iStage <= SipCpr::EStopping)
       
   227 		{
       
   228 		//We haven't recieved a DeRegister Request yet
       
   229 		iContext.Node().iStage = SipCpr::EStopping;
       
   230 		}
       
   231 	
       
   232 	//Expect Response
       
   233     iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();
       
   234     iContext.iNodeActivity->SetPostedTo(iContext.Node().NodeId());
       
   235 	}
       
   236 	
       
   237 	
       
   238 TBool TAwaitingDeRegistrationComplete::Accept()
       
   239 	{
       
   240 	//catch only messages generated by the SIPCPR 
       
   241 	ASSERT(iContext.iSender == iContext.Node().Id());
       
   242 	if(iContext.iMessage.IsMessage<TSipCprMessages::TDeRegistrationComplete>())
       
   243 		{
       
   244 		TSipCprMessages::TDeRegistrationComplete* msg = Messages::message_cast<TSipCprMessages::TDeRegistrationComplete>(&iContext.iMessage);
       
   245 		if (msg->iValue == KErrNone)
       
   246 			{
       
   247 			iContext.Node().iStage = SipCpr::EStopped;
       
   248 			}
       
   249 			else
       
   250 			{
       
   251 			//Set the error for activity so that it can be forwarded to applicaiton
       
   252 			TInt error = msg->iValue;
       
   253 			iContext.iNodeActivity->SetError(error);				
       
   254 			}
       
   255 		return ETrue;	
       
   256 		}
       
   257 	return EFalse;	
       
   258 	}
       
   259 
       
   260 /*
       
   261 DEFINE_SMELEMENT(TSendStopped,NetStateMachine::MStateTransition, SipCprStates::TContext)
       
   262 void TSendStopped::DoL()
       
   263 	{
       
   264 	
       
   265 	TInt stopCode = iContext.Node().iStashedStoppedCode;
       
   266 		//the section below is reproduced intoto from the CoreStates::TSendStopped :-)
       
   267 	TCFMessage::TStopped msg(iContext.iNode(), iContext.iCFMessageSig.ActivityId(), stopCode);
       
   268 	if (iContext.iNodeActivity)
       
   269 		{
       
   270 		iContext.iNodeActivity->PostToOriginators(msg);
       
   271 		}
       
   272 	else
       
   273 		{
       
   274 		//This transition can also be used from a single tripple activity
       
   275 		ASSERT(iContext.iCFMessageSig.iPeer); //Always a peer message
       
   276 		iContext.iCFMessageSig.iPeer->PostMessage(msg);
       
   277 		}
       
   278 	if (iContext.Node().CountActivities(ECFActivityStart) == 0)
       
   279     	{
       
   280         TCFMessage::TGoneDown goneDown(iContext.iNode(), ECFActivityNull, stopCode);
       
   281         TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(RNodeInterface::ECtrl);
       
   282        	for (TInt i = 0; iter[i]; i++)
       
   283            	{
       
   284            	//Send TGoneDown to every Ctrl client except the originator (who would be recieving TStopped)
       
   285            	if ((iContext.iNodeActivity && iContext.iNodeActivity->FindOriginator(*iter[i]) != KErrNone) ||
       
   286            	    (iContext.iNodeActivity == NULL && iter[i] != iContext.iCFMessageSig.iPeer))
       
   287                	{
       
   288                	iter[i]->PostMessage(goneDown);
       
   289                	}
       
   290            	}
       
   291     	}
       
   292 	if (iContext.iNodeActivity)
       
   293     	{
       
   294         iContext.iNodeActivity->SetError(KErrNone);
       
   295     	}
       
   296 	}
       
   297 */	
       
   298 
       
   299 /**
       
   300 Comms-binder activity will use this function. 
       
   301 It returns KWaitForIncoming if the connection type is WaitForIncoming
       
   302 otherwise returns KUseExisting
       
   303 */
       
   304 DEFINE_SMELEMENT(TWaitForIncomingOrUseExisting,NetStateMachine::MStateFork, SipCprStates::TContext)
       
   305 TInt TWaitForIncomingOrUseExisting::TransitionTag()
       
   306 	{
       
   307 	if(iContext.Node().iConnStatus == SipCpr::EConnIncoming)
       
   308 		{
       
   309 		return CoreNetStates::KWaitForIncoming;
       
   310 		}
       
   311 		else
       
   312 		{		
       
   313 		return CoreStates::KUseExisting;
       
   314 		}
       
   315 	}
       
   316 		
       
   317 DEFINE_SMELEMENT(TNoTagOrDeRegister,NetStateMachine::MStateFork, SipCprStates::TContext)
       
   318 TInt TNoTagOrDeRegister::TransitionTag()
       
   319 	{	
       
   320 	MeshMachine::CNodeActivityBase* activity = iContext.iNodeActivity;
       
   321 	Messages::TSignatureBase& message = iContext.iMessage;
       
   322 	TInt code = KErrCancel;
       
   323 	if (activity && activity->Error() != KErrNone)
       
   324         {
       
   325         code = activity->Error();
       
   326         }
       
   327     
       
   328 	if (message.IsTypeOf(Messages::TSigNumber::TypeId()))
       
   329 		{
       
   330    		code = static_cast<const Messages::TSigNumber&>(message).iValue;
       
   331    		}
       
   332     else if (message.IsTypeOf(Messages::TSigNumberNumber::TypeId()))
       
   333 		{
       
   334    		code = static_cast<const Messages::TSigNumberNumber&>(message).iValue1;
       
   335    		}
       
   336 	
       
   337 	//stash the stop code to be used after we get DeRegistrationComplete
       
   338 	iContext.Node().iStashedStoppedCode = code;
       
   339 	
       
   340 	//Now do the regular fork
       
   341 	if(iContext.Node().iStage == SipCpr::EActive)
       
   342 		{
       
   343 		return SipCprStates::KDeRegister;
       
   344 		}
       
   345 	return MeshMachine::KNoTag;
       
   346 	}	
       
   347 }// namespace SipCprStates