sipproviderplugins/sipprovider/sipstatemachine/src/transitionengine.cpp
changeset 0 307788aac0a8
child 4 dd3853b8dc3f
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2005-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 // CSIPTransitionEngine implementation file.
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22  
       
    23 
       
    24 #include "transitionengine.h"
       
    25 #include "SipStateMachine.h"
       
    26 #include <siphlerr.h>
       
    27 
       
    28 
       
    29 CSIPTransitionEngine* CSIPTransitionEngine::NewL(CSIP& aSip, TInt aIapId)
       
    30 /**
       
    31 Transition Engine Instantiation Function
       
    32 */
       
    33 	{	
       
    34 	CSIPTransitionEngine * self = new (ELeave) CSIPTransitionEngine(aSip, aIapId);
       
    35 	CleanupStack::PushL (self);
       
    36 	self->ConstructL();
       
    37 	CleanupStack::Pop();
       
    38 	return self;	
       
    39 	}
       
    40  
       
    41 
       
    42 void CSIPTransitionEngine::ConstructL()
       
    43 /**
       
    44 2nd Phase construction
       
    45 */
       
    46 	{
       
    47 	__FLOG_1(_L("CSIPTransitionEngine %08x:\tConstructL(), expect 'ConstructL successful', otherwise the method left"), this);
       
    48 	ASSERT(iConnection == NULL);
       
    49 	
       
    50 	// Startup Nokia Stack Related Objects
       
    51 	iConnState = CSIPConnection::EInactive;
       
    52 
       
    53 	__FLOG_1(_L("CSIPTransitionEngine %08x:\tInstantiating CSIPProfileRegistry - may leave"), this);
       
    54 	iProfileRegistry = CSIPProfileRegistry::NewL(iSIP, *this);
       
    55 	CleanupStack::PushL(iProfileRegistry);
       
    56 	__FLOG_1(_L("CSIPTransitionEngine %08x:\tInstantiating CSIPHttpDigest - may leave"), this);
       
    57 	iDigest = CSIPHttpDigest::NewL(iSIP, *this );
       
    58 	CleanupStack::PushL(iDigest);
       
    59 	__FLOG_1(_L("CSIPTransitionEngine %08x:\tInstantiating CSIPConnection - may leave"), this);
       
    60     iConnection = CSIPConnection::NewL(iSIP, iIapId, *this );
       
    61 
       
    62 	// Wait for the connectio to become Active 
       
    63 	if( iConnection->State() == CSIPConnection::EInit )
       
    64 		{
       
    65 		iActiveWait.Start();
       
    66 		}
       
    67 		
       
    68 	__FLOG_1(_L("CSIPTransitionEngine %08x:\tConstructL successful"), this);		
       
    69     CleanupStack::Pop(2);
       
    70 	}
       
    71 	
       
    72 CSIPTransitionEngine::CSIPTransitionEngine(CSIP& aSip, TInt aIapId)
       
    73 :iIapId(aIapId),
       
    74  iSIP(aSip)
       
    75 /**
       
    76 constructor
       
    77 */
       
    78 	{
       
    79 	// Open Logs
       
    80 	__FLOG_OPEN(_L8("SipStateMachine"), _L8("TransitionEngine"));
       
    81 	__FLOG_1(_L("[TransitionEngine]:[%x]::CSIPTransitionEngine() "), this);	
       
    82 	}
       
    83 	
       
    84 	
       
    85 CSIPTransitionEngine::~CSIPTransitionEngine()
       
    86 /**
       
    87 Destructor , cleanup wil be done here
       
    88 */
       
    89 	{
       
    90 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine [%x]::~CSIPTransitionEngine"), this);
       
    91 	// Delete all the State Machines that are there registered
       
    92 	// with the TE
       
    93 	CHLStateMachine *hlSm = NULL;
       
    94 	TInt numElements = iSMArray.Count();
       
    95 	for(TInt count=0; count<numElements; count++)
       
    96 		{
       
    97 		hlSm = (CHLStateMachine*)iSMArray[count];
       
    98 		hlSm->iDialog = NULL;
       
    99 		hlSm->iTransaction = NULL;
       
   100 		delete hlSm;
       
   101 		}
       
   102 	iSMArray.Close();
       
   103 	
       
   104 	// Clean Profiles
       
   105 	numElements = iProfileArray.Count();
       
   106 	for (TInt count = 0; count<numElements; count++)
       
   107 		{
       
   108 		CSIPProfile* profile = iProfileArray[count];
       
   109 		delete profile;
       
   110 		}
       
   111 	iProfileArray.Close();
       
   112 	
       
   113 	//Close RegClientArray
       
   114 	//TransitionEngine will be deleted only when no SIPConnProviders are using this
       
   115 	iRegClientArray.Close();
       
   116 	
       
   117 	delete iProfileRegistry;
       
   118 	delete iConnection;
       
   119     __FLOG_1(_L("<<completed...>> CSIPTransitionEngine [%x]::~CSIPTransitionEngine"), this);
       
   120 	__FLOG_CLOSE;	
       
   121 	}
       
   122 
       
   123 void CSIPTransitionEngine::ConnectionStateChanged( CSIPConnection::TState aState )
       
   124 	{
       
   125 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine [%x]::ConnectionStateChanged()"), this);
       
   126 	// No Matter what the connection state is become we have to stop the wait
       
   127 	if (iActiveWait.IsStarted())
       
   128 		{
       
   129 			iActiveWait.AsyncStop();
       
   130 		}
       
   131 	
       
   132 	if (iConnState == CSIPConnection::EActive && aState != CSIPConnection::EActive)
       
   133 		{
       
   134 		//CSIP Connection Lost
       
   135 		//Notify all Registration Clients
       
   136 		for ( TInt count = 0; count<iRegClientArray.Count(); count++)
       
   137 			{
       
   138 			iRegClientArray[count]->ErrorOccurred(KErrSIPTransportFailure);
       
   139 			}
       
   140 			
       
   141 		}
       
   142 	}
       
   143 
       
   144 
       
   145 void CSIPTransitionEngine::IncomingRequest( CSIPServerTransaction* aTransaction )
       
   146 /**
       
   147 Incoming request recieved outside a dialog
       
   148 */	
       
   149 	{
       
   150 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<Recieved Outside of a Dialog>>"),this);
       
   151 	CleanupStack::PushL(aTransaction); //we're take over the ownership.
       
   152 	
       
   153 	RStringF method = aTransaction->RequestElements()->Method();
       
   154 	if(method == SIPStrings::StringF(SipStrConsts::EInvite))
       
   155 		{
       
   156 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<Received Request Invite>>"),this);
       
   157 		TSipMsgBundle	msgBundle;
       
   158 		// Create a dialog Association and set server transaction
       
   159 		CSIPInviteDialogAssoc*	dialogassoc = CSIPInviteDialogAssoc::NewL(*aTransaction);
       
   160 		CleanupStack::PushL(dialogassoc);
       
   161 		msgBundle.iRequest = TSipHLConsts::ERequestInvite;
       
   162 		msgBundle.iDialog = dialogassoc;
       
   163 		msgBundle.iServTransaction = aTransaction;
       
   164 		// Look For the state machine which is responsible for handling 
       
   165 	 	// this particular request
       
   166 	 	CSipStateMachine*	smPtr = FindSMForIncomingCall();
       
   167 	 	if(smPtr)
       
   168 	 		{
       
   169 	 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<Found State Machine to Handle the Request>>"),this);
       
   170 	 		smPtr->IncomingRequestOutsideDialog(msgBundle);	
       
   171 	 		CleanupStack::Pop(dialogassoc);
       
   172 	 		CleanupStack::Pop(aTransaction);
       
   173 	 		}
       
   174 	 	else
       
   175 	 		{// return NotFound
       
   176 	 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<No State Machine found to Handle the Request>>"),this);
       
   177 	 		__FLOG_0(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<sending 404>>"));
       
   178 	 		CSIPResponseElements *ResElem = CSIPResponseElements::NewLC(
       
   179 							404, SIPStrings::StringF(SipStrConsts::EPhraseNotFound));
       
   180 			aTransaction->SendResponseL(ResElem);
       
   181 			CleanupStack::Pop(ResElem);		
       
   182 			CleanupStack::PopAndDestroy(aTransaction);
       
   183 			CleanupStack::PopAndDestroy(dialogassoc);
       
   184 	 		}
       
   185 		}
       
   186 	 else
       
   187 	 	{ // bad request , not supported here
       
   188 	 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<Received Request other than Invite>>"),this);
       
   189 	 	__FLOG_0(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<sending 404>>"));
       
   190 	 	CSIPResponseElements *ResElem = CSIPResponseElements::NewLC(
       
   191 							400, SIPStrings::StringF(SipStrConsts::EPhraseBadRequest));
       
   192 		aTransaction->SendResponseL(ResElem);
       
   193 		CleanupStack::Pop(ResElem);		
       
   194 		CleanupStack::PopAndDestroy(aTransaction);
       
   195 	 	}		
       
   196 	}
       
   197 	
       
   198 void CSIPTransitionEngine::IncomingRequest( CSIPServerTransaction* aTransaction, CSIPDialog& aDialog )
       
   199 /**
       
   200 Incoming request recieved on an established dialog
       
   201 */
       
   202 	{
       
   203 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<Recieved on Established Dialog>>"),this);
       
   204 	//find state machine from associated DialogAssoc
       
   205 	CSipStateMachine* smPtr = FindStateMachine(aDialog);
       
   206 	//Extract Method
       
   207 	RStringF method = aTransaction->RequestElements()->Method();
       
   208 	TSipMsgBundle msgBundle;
       
   209 	
       
   210 	if (method == SIPStrings::StringF(SipStrConsts::EInvite))
       
   211 		{
       
   212 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<INVITE>>"),this);
       
   213 		msgBundle.iRequest = TSipHLConsts::ERequestInvite;		
       
   214 		}
       
   215 	else if (method == SIPStrings::StringF(SipStrConsts::EAck))
       
   216 		{
       
   217 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<ACK>>"),this);
       
   218 		msgBundle.iRequest = TSipHLConsts::ERequestAck;
       
   219 		}
       
   220 	else if (method == SIPStrings::StringF(SipStrConsts::EBye))
       
   221 		{
       
   222 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<BYE>>"),this);
       
   223 		msgBundle.iRequest = TSipHLConsts::ERequestBye;
       
   224 		}
       
   225 	else if (method == SIPStrings::StringF(SipStrConsts::ECancel))
       
   226 		{
       
   227 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<CANCEL>>"),this);
       
   228 		msgBundle.iRequest = TSipHLConsts::ERequestCancel;
       
   229 		}
       
   230 	else if (method == SIPStrings::StringF(SipStrConsts::ENotify))
       
   231 		{
       
   232 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<NOTIFY>>"),this);
       
   233 		msgBundle.iRequest = TSipHLConsts::ERequestNotify;
       
   234 		}
       
   235 	
       
   236 	msgBundle.iServTransaction = aTransaction;
       
   237 	// Match the state machine which is associated with this message
       
   238 	if(smPtr)
       
   239 		{
       
   240 		__FLOG_0(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <<Found state machine for handling this request>>"));
       
   241 		smPtr->IncomingRequestInsideDialog(msgBundle);	
       
   242 		}
       
   243 	}
       
   244 
       
   245 
       
   246 void CSIPTransitionEngine::IncomingResponse( CSIPClientTransaction& /*aTransaction*/ )
       
   247 	{
       
   248 	// We will Not handle this case
       
   249 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<Not HANDLED CASE CALLED < ITS AN ERROR>>"),this);
       
   250 	}
       
   251 
       
   252 void CSIPTransitionEngine::IncomingResponse( CSIPClientTransaction& aTransaction,
       
   253 							   CSIPDialogAssocBase& aDialogAssoc )
       
   254 /**
       
   255 Incoming Response inside an established dialog is received
       
   256 */
       
   257 	{
       
   258 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<Recieved on Established Dialog>>"),this);
       
   259 	CSIPCSeqHeader* CseqHdr = (CSIPCSeqHeader*)aTransaction.ResponseElements()->CSeqHeader();
       
   260 	RStringF method = CseqHdr->Method();
       
   261 	TSipMsgBundle msgBundle;
       
   262 	msgBundle.iStatusCode = aTransaction.ResponseElements()->StatusCode();
       
   263 	msgBundle.iClientTransaction = &aTransaction;
       
   264 	
       
   265 	if (method == SIPStrings::StringF(SipStrConsts::EInvite))
       
   266 		{
       
   267 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<INVITE>>"),this);
       
   268 		msgBundle.iResponse = TSipHLConsts::EResponseInvite;		
       
   269 		}
       
   270 	else if (method == SIPStrings::StringF(SipStrConsts::EAck))
       
   271 		{
       
   272 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<ACK>>"),this);
       
   273 		msgBundle.iResponse = TSipHLConsts::EResponseAck;
       
   274 		}
       
   275 	else if (method == SIPStrings::StringF(SipStrConsts::EBye))
       
   276 		{
       
   277 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<BYE>>"),this);
       
   278 		msgBundle.iResponse = TSipHLConsts::EResponseBye;
       
   279 		}
       
   280 	else if (method == SIPStrings::StringF(SipStrConsts::ECancel))
       
   281 		{
       
   282 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<CANCEL>>"),this);
       
   283 		msgBundle.iResponse = TSipHLConsts::EResponseCancel;
       
   284 		}
       
   285 	else if (method == SIPStrings::StringF(SipStrConsts::ESubscribe))
       
   286 		{
       
   287 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<SUBSCRIBE>>"),this);
       
   288 		msgBundle.iResponse = TSipHLConsts::EResponseSubscribe;
       
   289 		}
       
   290 
       
   291 	//Find the StateMachine associated with this Dialog
       
   292 	CSipStateMachine* smPtr = FindStateMachine(aDialogAssoc);
       
   293 	if (smPtr)
       
   294 	{
       
   295 	//Set the error code in case the status code is 3XX 6XX errors.
       
   296 		if(msgBundle.iStatusCode >299)
       
   297 		{
       
   298 		msgBundle.iErrCode= KErrSIPErrorResponse;
       
   299 		smPtr->ErrorOccured(msgBundle);
       
   300 		}
       
   301 		else
       
   302 		{
       
   303 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<Found state machine for handling this response>>"),this);
       
   304 		smPtr->IncomingResponse(msgBundle);
       
   305 		}
       
   306 	}	
       
   307 }	
       
   308 	
       
   309 
       
   310 void CSIPTransitionEngine::IncomingResponse( CSIPClientTransaction& aTransaction,
       
   311 							   CSIPInviteDialogAssoc* aDialogAssoc )
       
   312 	{
       
   313 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<Recieved on InviteDialog Assoc>>"),this);
       
   314 	CSIPCSeqHeader * CseqHdr = (CSIPCSeqHeader*)aTransaction.ResponseElements()->CSeqHeader();
       
   315 	RStringF method = CseqHdr->Method();
       
   316 	TSipMsgBundle msgBundle;
       
   317 	msgBundle.iStatusCode = aTransaction.ResponseElements()->StatusCode();
       
   318 	
       
   319 	if (method == SIPStrings::StringF(SipStrConsts::EInvite))
       
   320 		{
       
   321 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<INVITE>>"),this);
       
   322 		msgBundle.iResponse = TSipHLConsts::EResponseInvite;		
       
   323 		}
       
   324 	else if (method == SIPStrings::StringF(SipStrConsts::EAck))
       
   325 		{
       
   326 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<ACK>>"),this);
       
   327 		msgBundle.iResponse = TSipHLConsts::EResponseAck;
       
   328 		}
       
   329 	else if (method == SIPStrings::StringF(SipStrConsts::EBye))
       
   330 		{
       
   331 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<BYE>>"),this);
       
   332 		msgBundle.iResponse = TSipHLConsts::EResponseBye;
       
   333 		}
       
   334 	else if (method == SIPStrings::StringF(SipStrConsts::ECancel))
       
   335 		{
       
   336 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<CANCEL>>"),this);
       
   337 		msgBundle.iResponse = TSipHLConsts::EResponseCancel;
       
   338 		}
       
   339 	else if (method == SIPStrings::StringF(SipStrConsts::ESubscribe))
       
   340 		{
       
   341 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<SUBSCRIBE>>"),this);
       
   342 		msgBundle.iResponse = TSipHLConsts::EResponseSubscribe;
       
   343 		}
       
   344 		
       
   345 	//Find the StateMachine associated with this Dialog
       
   346 	CSipStateMachine* smPtr = FindStateMachine(reinterpret_cast<CSIPDialogAssocBase*>(aDialogAssoc));
       
   347 	if (smPtr)
       
   348 		{
       
   349 		__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<Found state machine for handling this response>>"),this);
       
   350 		smPtr->IncomingResponse(msgBundle);
       
   351 		}
       
   352 	}
       
   353 
       
   354 void CSIPTransitionEngine::IncomingResponse( CSIPClientTransaction& aTransaction,
       
   355 							   CSIPRegistrationBinding& aRegistration )
       
   356 	{
       
   357 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<Recieved on Registration Assoc>>"),this);
       
   358 
       
   359 	CSipStateMachine* smPtr = FindStateMachine(aTransaction);
       
   360 	if (smPtr)
       
   361 		{
       
   362 		TSipMsgBundle	msgBundle;
       
   363 		if (aRegistration.IsContextActive()) // Registeration Response
       
   364 			{
       
   365 			__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<REGISTER>>"),this);
       
   366 			msgBundle.iResponse = TSipHLConsts::EResponseRegister;
       
   367 			msgBundle.iStatusCode = aTransaction.ResponseElements()->StatusCode();
       
   368 			smPtr->IncomingResponse(msgBundle);
       
   369 			}
       
   370 		else // Unregistration Response
       
   371 			{
       
   372 			__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <<UNREGISTER>>"),this);
       
   373 			msgBundle.iResponse = TSipHLConsts::EResponseUnRegister;
       
   374 			msgBundle.iStatusCode = aTransaction.ResponseElements()->StatusCode();
       
   375 			smPtr->IncomingResponse(msgBundle);
       
   376 			}
       
   377 		}
       
   378 	}
       
   379 
       
   380 void CSIPTransitionEngine::ErrorOccured( TInt aError,
       
   381 						   CSIPTransactionBase& aTransaction )
       
   382 /**
       
   383 This function will ask the particular state machine to handle the 
       
   384 error
       
   385 */						   
       
   386 	{
       
   387 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPTransactionBase& aTransaction)"),this);
       
   388 	CSipStateMachine* smPtr = FindStateMachine(aTransaction);
       
   389 	if(smPtr)
       
   390 		{
       
   391 		TSipMsgBundle 	errBundle;
       
   392 		errBundle.iErrCode = aError;
       
   393 		smPtr->ErrorOccured(errBundle);
       
   394 		}
       
   395 	}
       
   396 
       
   397 void CSIPTransitionEngine::ErrorOccured( TInt aError,
       
   398 						   CSIPClientTransaction& aTransaction,
       
   399 						   CSIPRegistrationBinding& /*aRegistration*/ )
       
   400 /**
       
   401 Handle errors related to Failed Registration. The registration binding is destroyed by
       
   402 the state machine, so need not to be destroyed here
       
   403 */						   
       
   404 	{
       
   405 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPTransactionBase& aTransaction, CSIPRegistrationBinding & aRegistration)"),this);
       
   406 	CSipStateMachine* smPtr = FindStateMachine(aTransaction);
       
   407 	if(smPtr)
       
   408 		{
       
   409 		__FLOG_0(_L("[TransitionEngine]: <<Found State Machine to Handle the Error>>"));
       
   410 		TSipMsgBundle msgBundle;
       
   411 		msgBundle.iErrCode = aError;
       
   412 		msgBundle.iResponse = TSipHLConsts::EResponseRegister;
       
   413 		const CSIPResponseElements * resElems = aTransaction.ResponseElements();
       
   414 		if(resElems)
       
   415 			{
       
   416 			msgBundle.iStatusCode = resElems->StatusCode();		
       
   417 			}
       
   418 		else
       
   419 			{
       
   420 			msgBundle.iStatusCode = -1;			
       
   421 			}
       
   422 		msgBundle.iClientTransaction = &aTransaction;
       
   423 		smPtr->ErrorOccured(msgBundle);
       
   424 		}
       
   425 	else
       
   426 		{
       
   427 		__FLOG_0(_L("[TransitionEngine]: <<Not Found State Machine to Handle the Error>>"));	
       
   428 		}
       
   429 	}
       
   430 
       
   431 void CSIPTransitionEngine::ErrorOccured( TInt aError,
       
   432 						   CSIPTransactionBase& /*aTransaction*/,
       
   433 						   CSIPDialogAssocBase& aDialogAssoc)
       
   434 /**
       
   435 Handles the errors related to failed transaction. No need delete the transaction
       
   436 or the dialogassoc , as state machine will delete those upon termination
       
   437 */						   
       
   438 	{
       
   439 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPTransactionBase& aTransaction, CSIPDialogAssocBase & aDialogAssoc)"),this);
       
   440 	CSipStateMachine* smPtr = FindStateMachine(aDialogAssoc);
       
   441 	if(smPtr)
       
   442 		{
       
   443 		__FLOG_0(_L("[TransitionEngine]: <<Found State Machine to Handle the Error>>"));
       
   444 		TSipMsgBundle	errBundle;
       
   445 		errBundle.iErrCode = aError;
       
   446 		// we cant get status code from response
       
   447 		errBundle.iStatusCode = -1;	
       
   448 		smPtr->ErrorOccured(errBundle);
       
   449 		}
       
   450 	else
       
   451 		{
       
   452 		__FLOG_0(_L("[TransitionEngine]: <<Not Found State Machine to Handle the Error>>"));
       
   453 		// No State Machine, Nothing to do , SM might have been terminated by some 
       
   454 		// other request
       
   455 		return;	
       
   456 		}
       
   457 	}
       
   458 
       
   459 void CSIPTransitionEngine::ErrorOccured(TInt aError, CSIPRefresh & aSIPRefresh)
       
   460 /**
       
   461 Handles Errors related to refresh 
       
   462 */
       
   463 	{
       
   464 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPRefresh & aSIPRefresh)"),this);
       
   465 	TSipMsgBundle	errBundle;
       
   466 	// Get The state machine associated with this particular Refresh request 
       
   467 	const CSIPClientTransaction * clientTnx = aSIPRefresh.SIPTransaction();
       
   468 	if(clientTnx)
       
   469 		{
       
   470 		__FLOG_0(_L("[TransitionEngine]: <<Found State Machine to Handle the Error>>"));
       
   471 		CSipStateMachine* smPtr = FindStateMachine(clientTnx);
       
   472 		if(smPtr)
       
   473 			{
       
   474 			errBundle.iErrCode = aError;
       
   475 			const CSIPResponseElements * resElems = clientTnx->ResponseElements();
       
   476 			if(resElems)
       
   477 				{
       
   478 				errBundle.iStatusCode = resElems->StatusCode();
       
   479 				}
       
   480 			else
       
   481 				{
       
   482 				errBundle.iStatusCode = -1;	
       
   483 				}
       
   484 			smPtr->ErrorOccured(errBundle);
       
   485 			}
       
   486 		else
       
   487 			{
       
   488 			// NO SM , nothing to do	
       
   489 			}
       
   490 		}
       
   491 	else
       
   492 		{
       
   493 		__FLOG_0(_L("[TransitionEngine]: <<Not Found State Machine to Handle the Error>>"));
       
   494 		// No Client Transaction , Noting can be done	
       
   495 		}
       
   496 	}
       
   497 	
       
   498 void CSIPTransitionEngine::ErrorOccured( TInt aError,
       
   499 						   CSIPRegistrationBinding& aRegistration)
       
   500 /**
       
   501 Handles the error occurred with the periodic refreshing of an registration
       
   502 binding
       
   503 */						   
       
   504 	{
       
   505 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPRegistrationBinding& aRegistration)"),this);
       
   506 	TSipMsgBundle	errBundle;
       
   507 	// Get The state machine to Handle this condition 
       
   508 	CSIPRefresh * refresh = aRegistration.SIPRefresh();
       
   509 	if(refresh)
       
   510 		{
       
   511 		const CSIPClientTransaction *clientTxn = refresh->SIPTransaction();
       
   512 		if(clientTxn)
       
   513 			{
       
   514 			CSipStateMachine* smPtr = FindStateMachine(clientTxn);
       
   515 			if(smPtr)
       
   516 				{
       
   517 				errBundle.iErrCode = aError;
       
   518 				const CSIPResponseElements * resElems = clientTxn->ResponseElements();
       
   519 				if(resElems)
       
   520 					{
       
   521 					errBundle.iStatusCode = resElems->StatusCode();
       
   522 					}
       
   523 				else
       
   524 					{
       
   525 					errBundle.iStatusCode = -1;	
       
   526 					}
       
   527 				smPtr->ErrorOccured(errBundle);
       
   528 				}
       
   529 			else
       
   530 				{
       
   531 				// NO SM , nothing to do	
       
   532 				}
       
   533 			}
       
   534 		else
       
   535 			{
       
   536 			// No client Txn , Nothing can be done	
       
   537 			}
       
   538 		}
       
   539 	else
       
   540 		{
       
   541 		// No Refesh inside nothing can be done	
       
   542 		}
       
   543 	}
       
   544 	
       
   545 void CSIPTransitionEngine::ErrorOccured( TInt aError,
       
   546 						CSIPDialogAssocBase& aDialogAssoc)
       
   547 /**
       
   548 Handles SIP errors based That happens on a Existing Dialog association
       
   549 */						   
       
   550 	{
       
   551 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPDialogAssocBase& aDialogAssoc)"),this);
       
   552 	TSipMsgBundle errBundle;
       
   553 	// Find the state machine to Handle this error condition
       
   554 	CSipStateMachine* smPtr = FindStateMachine(aDialogAssoc);
       
   555 	if(smPtr)
       
   556 		{
       
   557 		__FLOG_0(_L("[TransitionEngine]: <<Found State Machine to Handle the Error>>"));
       
   558 		errBundle.iErrCode = aError;
       
   559 		// we dont have handle to SIP message elements from here
       
   560 		errBundle.iStatusCode = -1;	
       
   561 		smPtr->ErrorOccured(errBundle);
       
   562 		}
       
   563 	else
       
   564 		{
       
   565 		__FLOG_0(_L("[TransitionEngine]: <<Not Found State Machine to Handle the Error>>"));
       
   566 		// NO SM , nothing to do	
       
   567 		}
       
   568 	}
       
   569 
       
   570 void CSIPTransitionEngine::InviteCompleted( CSIPClientTransaction& aTransaction )
       
   571 /**
       
   572 Handles the case related to the Completion of Invite Request
       
   573 */
       
   574 	{
       
   575 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::InviteCompleted()"),this);
       
   576 	CSipStateMachine*	smPtr = FindStateMachine(aTransaction);
       
   577 	smPtr->InviteCompleted(aTransaction);
       
   578 	}
       
   579 
       
   580 
       
   581 void CSIPTransitionEngine::InviteCanceled( CSIPServerTransaction& aTransaction )
       
   582 /**
       
   583 This callback will be called when a incoming Invite is cancelled by the remote machine
       
   584 */
       
   585 	{
       
   586 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::InviteCanceled()"),this);
       
   587 	CSipStateMachine*	smPtr = FindStateMachine(aTransaction);
       
   588 	TSipMsgBundle	msgBundle;
       
   589 	msgBundle.iServTransaction = &aTransaction;
       
   590 	msgBundle.iRequest = TSipHLConsts::ERequestCancel;
       
   591 	smPtr->IncomingRequest(msgBundle);
       
   592 	}
       
   593 
       
   594 //From MSIPProfileRegistryObserver
       
   595 void CSIPTransitionEngine::ProfileRegistryErrorOccurred(TUint32 aProfileId, TInt aError)
       
   596 	{
       
   597 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryErrorOccurred()"),this);
       
   598 	//if(iActiveWait.IsStarted())
       
   599     //	iActiveWait.AsyncStop();
       
   600 	CSIPProfile* profile = NULL;
       
   601 	TUint32 profileId;
       
   602 	MSIPRegistrationClient* regClient = FindRegistrationClient(aProfileId);
       
   603 	
       
   604 	TInt size = iProfileArray.Count();
       
   605 	for (TInt count = 0; count<size; count++)
       
   606 		{
       
   607 		profile = iProfileArray[count];
       
   608 		profile->GetParameter(KSIPProfileId, profileId);
       
   609 		if (profileId == aProfileId)
       
   610 			{
       
   611 			iProfileRegistry->Disable(*profile);
       
   612 			iProfileArray.Remove(count);
       
   613 			delete profile;
       
   614 			break;	
       
   615 			}
       
   616 		}
       
   617 
       
   618 	//MSIPRegistrationClient* regClient = FindRegistrationClient(aProfileId);
       
   619 	if(regClient)
       
   620 		{
       
   621 		regClient->ErrorOccurred(aError);
       
   622 		}
       
   623 	}
       
   624 	
       
   625 void CSIPTransitionEngine::ProfileRegistryEventOccurred(TUint32 aProfileId, TEvent aEvent)
       
   626 /**
       
   627 Handle the registry event for Registration and Deregistration
       
   628 */
       
   629 	{
       
   630 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryEventOccurred()"),this);
       
   631 	//if(iActiveWait.IsStarted())
       
   632     //	iActiveWait.AsyncStop();
       
   633 	
       
   634 	TUint32 		profileId;
       
   635 	CSIPProfile*	profile = NULL;
       
   636 	MSIPRegistrationClient* regClient = FindRegistrationClient(aProfileId);
       
   637 	if(regClient == NULL)
       
   638 		{
       
   639 		_LIT(KSipConnProvPanic, "SIPCPR");
       
   640 		User::Panic(KSipConnProvPanic, KSIPProfileNotFound);
       
   641 		}
       
   642 	switch(aEvent)
       
   643 		{
       
   644 		case EProfileRegistered: 
       
   645 			{
       
   646 			__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryEventOccurred()  <<EProfileRegistered>>"),this);
       
   647 			regClient->RegistrationComplete(KErrNone);	
       
   648 			}
       
   649 			break;		
       
   650 			
       
   651 		case EProfileDeregistered:
       
   652 			{
       
   653 			__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryEventOccurred()  <<EProfileDeRegistered>>"),this);
       
   654 			TInt size = iProfileArray.Count();
       
   655 			for (TInt count = 0; count<size; count++)
       
   656 				{
       
   657 				profile = iProfileArray[count];
       
   658 				profile->GetParameter(KSIPProfileId, profileId);
       
   659 				if (profileId == aProfileId)
       
   660 					{
       
   661 					iProfileArray.Remove(count);
       
   662 					delete profile;
       
   663 					break;	
       
   664 					}
       
   665 				}
       
   666 			regClient->DeRegistrationComplete(KErrNone);	
       
   667 			break;
       
   668 			}
       
   669 		default:
       
   670 			{
       
   671 			__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryEventOccurred()  <<ERROR..>>"),this);
       
   672 			regClient->ErrorOccurred(KErrUnknown);	
       
   673 			}
       
   674 		}
       
   675 				
       
   676 	}
       
   677 
       
   678 CSipStateMachine*	CSIPTransitionEngine::FindStateMachine(CSIPTransactionBase& aTransaction)
       
   679 /**
       
   680 Finds the associated state machine with the SIP transaction
       
   681 */
       
   682 	{
       
   683 	for(TInt count = 0;count<iSMArray.Count();count++)
       
   684 		{
       
   685 		if(*(iSMArray[count]->iTransaction) == aTransaction)
       
   686 			{
       
   687 			return iSMArray[count]->iStateMachine;
       
   688 			}
       
   689 		}
       
   690 	return NULL;
       
   691 	};
       
   692 
       
   693 CSipStateMachine*	CSIPTransitionEngine::FindStateMachine(const CSIPTransactionBase* aTransaction)
       
   694 /**
       
   695 Finds the associated state machine with the SIP transaction
       
   696 */
       
   697 	{
       
   698 	for(TInt count = 0;count<iSMArray.Count();count++)
       
   699 		{
       
   700 		if(iSMArray[count]->iTransaction == aTransaction)
       
   701 			{
       
   702 			return iSMArray[count]->iStateMachine;
       
   703 			}
       
   704 		}
       
   705 	return NULL;
       
   706 	};
       
   707 
       
   708 CSipStateMachine*	CSIPTransitionEngine::FindStateMachine(CSIPDialogAssocBase* aDialogAssoc)
       
   709 /**
       
   710 Finds the associated state machine with the SIP Dialog
       
   711 */
       
   712 	{
       
   713 	TInt numElements = iSMArray.Count();
       
   714 	for(TInt count=0; count<numElements; count++)
       
   715 		{
       
   716 		if (iSMArray[count]->iDialog == aDialogAssoc)
       
   717 			{
       
   718 			return iSMArray[count]->iStateMachine;
       
   719 			}
       
   720 		}
       
   721 	return NULL;
       
   722 	
       
   723 	};
       
   724 
       
   725 
       
   726 CSipStateMachine*	CSIPTransitionEngine::FindStateMachine(CSIPDialog& aDialog)
       
   727 /**
       
   728 Finds the associated state machine with the SIP Dialog
       
   729 */
       
   730 	{
       
   731 	TInt numElements = iSMArray.Count();
       
   732 	for(TInt count=0; count<numElements; count++)
       
   733 		{
       
   734 		if(aDialog.IsAssociated(*(iSMArray[count]->iDialog)))
       
   735 			{
       
   736 			return iSMArray[count]->iStateMachine;
       
   737 			}
       
   738 		}
       
   739 	return NULL;	
       
   740 	};
       
   741 
       
   742 	
       
   743 CSipStateMachine*	CSIPTransitionEngine::FindStateMachine(CSIPDialogAssocBase& aDialogAssoc)
       
   744 /**
       
   745 Finds the associated state machine with the SIP Dialog Assocition
       
   746 */
       
   747 	{
       
   748 	TInt numElements = iSMArray.Count();
       
   749 	for(TInt count=0; count<numElements; count++)
       
   750 		{
       
   751 		if (iSMArray[count]->iDialog == &aDialogAssoc)
       
   752 			{
       
   753 			return iSMArray[count]->iStateMachine;
       
   754 			}
       
   755 		}
       
   756 	return NULL;
       
   757 	};
       
   758 
       
   759 EXPORT_C void CSIPTransitionEngine::AddStateMachineL(CSipStateMachine* aStateMachine)
       
   760 /**
       
   761 Using this call The client will register the state machine with the Transition 
       
   762 Engine
       
   763 */
       
   764 	{
       
   765 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::AddStateMachineL()"),this);
       
   766 	CHLStateMachine *hlSm = new(ELeave) CHLStateMachine;
       
   767 	hlSm->iStateMachine = aStateMachine;
       
   768 	hlSm->iDialog		= NULL;
       
   769 	hlSm->iTransaction  = NULL;
       
   770 	iSMArray.AppendL(hlSm);
       
   771 	}
       
   772 
       
   773 void CSIPTransitionEngine::Cleanup(CSipStateMachine * aStateMachine)
       
   774 /**
       
   775 Handles the cleanup related to the transition Engine
       
   776 */
       
   777 	{
       
   778 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::Cleanup()"),this);
       
   779 	CHLStateMachine *hlSm = NULL;
       
   780 	TInt numElements = iSMArray.Count();
       
   781 	for(TInt count=0; count<numElements; count++)
       
   782 		{
       
   783 		if (iSMArray[count]->iStateMachine == aStateMachine)
       
   784 			{
       
   785 			hlSm = (CHLStateMachine*)iSMArray[count];
       
   786 			hlSm->iDialog = NULL;
       
   787 			hlSm->iTransaction = NULL;
       
   788 			delete hlSm;
       
   789 			}
       
   790 		}
       
   791 	}
       
   792 	
       
   793 	
       
   794 void	CSIPTransitionEngine::SetTransaction(CSipStateMachine* aStateMachine, CSIPTransactionBase* aTransaction)
       
   795 /**
       
   796 Sets The transaction for a particular state machine
       
   797 */
       
   798 	{
       
   799 	TInt numElements = iSMArray.Count();
       
   800 	for(TInt count=0; count<numElements; count++)
       
   801 		{
       
   802 		if (iSMArray[count]->iStateMachine == aStateMachine)
       
   803 			{
       
   804 			iSMArray[count]->iTransaction = aTransaction;
       
   805 			}
       
   806 		}
       
   807 	}
       
   808 
       
   809 void	CSIPTransitionEngine::SetDialogAssoc(CSipStateMachine* aStateMachine, CSIPDialogAssocBase* aDialoAssoc)
       
   810 /**
       
   811 Sets the dialog association for a particular state machine
       
   812 */
       
   813 	{
       
   814 	TInt numElements = iSMArray.Count();
       
   815 	for(TInt count=0; count<numElements; count++)
       
   816 		{
       
   817 		if (iSMArray[count]->iStateMachine == aStateMachine)
       
   818 			{
       
   819 			iSMArray[count]->iDialog = aDialoAssoc;
       
   820 			}
       
   821 		}
       
   822 	}
       
   823 
       
   824 CSipStateMachine *  CSIPTransitionEngine::FindSMForIncomingCall()
       
   825 /**
       
   826 Find the empty state machine for handling the incoming calls
       
   827 */
       
   828 	{
       
   829 	TInt numElements = iSMArray.Count();
       
   830 	for(TInt count=0; count<numElements; count ++)
       
   831 		{
       
   832 		if(iSMArray[count]->iTransaction == NULL && iSMArray[count]->iDialog == NULL)
       
   833 			{
       
   834 			// Check if this empty state machine is for incoming
       
   835 			if(iSMArray[count]->iStateMachine->GetIncomingStatus())
       
   836 				{
       
   837 				return iSMArray[count]->iStateMachine;
       
   838 				}
       
   839 			}
       
   840 		}
       
   841 	return NULL;
       
   842 	}
       
   843 	
       
   844 
       
   845 EXPORT_C void  CSIPTransitionEngine::RegisterL(MSIPRegistrationClient* aRegistrationClient)
       
   846 	{
       
   847 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::RegisterL()"),this);	
       
   848 	TUint32 profileId = aRegistrationClient->GetProfileId();
       
   849 	CSIPProfile* profile = NULL;
       
   850 	iRegClientArray.AppendL(aRegistrationClient);
       
   851 	
       
   852 	TInt err = KErrNone;
       
   853 	if(profileId == KSIPDefaultProfileId)
       
   854 		{
       
   855 		TRAP(err,profile = iProfileRegistry->DefaultProfileL());
       
   856 		}
       
   857 	else
       
   858 		{
       
   859 		TRAP(err, profile = iProfileRegistry->ProfileL(profileId));	
       
   860 		}
       
   861 	if(err != KErrNone)
       
   862 		{
       
   863     	__FLOG_2(_L("CSIPTransitionEngine %08x:The profile [%d] hasn't been found, aborting..."), this, profileId);
       
   864 		User::Leave(KSIPProfileNotFound);
       
   865 		}
       
   866 	if (!iProfileRegistry->IsEnabled(*profile))
       
   867 		{
       
   868     	__FLOG_2(_L("CSIPTransitionEngine %08x:The profile [%d] found, enabling..."), this, profileId);
       
   869 		TRAP(err,iProfileRegistry->EnableL( *profile, *this ));
       
   870 		if(err != KErrNone)
       
   871 			{
       
   872 			User::Leave(KSIPProfileNotFound);
       
   873 			}
       
   874 		iProfileArray.AppendL(profile);
       
   875 		}
       
   876 	}
       
   877 	
       
   878 
       
   879 EXPORT_C void  CSIPTransitionEngine::Deregister(MSIPRegistrationClient* aRegistrationClient)
       
   880 	{
       
   881 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::Deregister()"),this);	
       
   882 	TUint32 regProfId = aRegistrationClient->GetProfileId();
       
   883 	TUint32 profileId;
       
   884 	CSIPProfile* profile;
       
   885 	TInt size = iProfileArray.Count();
       
   886 	
       
   887 	for (TInt count = 0; count<size; count++)
       
   888 		{
       
   889 		profile = iProfileArray[count];
       
   890 		profile->GetParameter(KSIPProfileId, profileId);
       
   891 		if (profileId == regProfId)
       
   892 			{
       
   893 			iProfileRegistry->Disable(*profile);
       
   894 			break;		
       
   895 			}
       
   896 		}
       
   897 	}
       
   898 	
       
   899 	
       
   900 EXPORT_C TUint32  CSIPTransitionEngine::FindDuplicateProfile(TUint32 aProfileId)
       
   901 	{
       
   902 	__FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::FindDuplicateProfile()"),this);	
       
   903 	// IAP,Registrar,User AOR,Contacts, Proxy, Digest User Name, Digest Realm, SecMechanism
       
   904 	if (aProfileId == KSIPInvalidProfileId)
       
   905 		{
       
   906 		return KSIPInvalidProfileId;
       
   907 		}
       
   908 	
       
   909 	CSIPProfile* profile = NULL;
       
   910 	TRAPD(err,	profile = iProfileRegistry->ProfileL(aProfileId));
       
   911 	
       
   912 	if (err != KErrNone)
       
   913 		{
       
   914 		return KErrNone;
       
   915 		}
       
   916 	
       
   917 	TUint32	thisIapId;
       
   918 	TUint32 thisProfileId;
       
   919 	const TDesC8*	thisAor = NULL;
       
   920 	const TDesC8*	thisRegistrar = NULL;
       
   921 	const TDesC8*	thisProxy = NULL;
       
   922 	const TDesC8*	thisRegRealm = NULL;
       
   923 	const TDesC8*	thisProxyRealm = NULL;
       
   924 	const TDesC8*	thisRegUser = NULL;
       
   925 	const TDesC8*	thisProxyUser = NULL;
       
   926 	
       
   927 	profile->GetParameter(KSIPProfileId, thisProfileId);
       
   928 	profile->GetParameter(KSIPAccessPointId, thisIapId);
       
   929 	profile->GetParameter(KSIPUserAor, thisAor);
       
   930 	profile->GetParameter(KSIPRegistrar,KSIPServerAddress, thisRegistrar);
       
   931 	profile->GetParameter(KSIPOutboundProxy,KSIPServerAddress, thisProxy);
       
   932 	profile->GetParameter(KSIPRegistrar,KSIPDigestRealm, thisRegRealm);
       
   933 	profile->GetParameter(KSIPRegistrar,KSIPDigestUserName, thisRegUser);
       
   934 	profile->GetParameter(KSIPOutboundProxy,KSIPDigestRealm, thisProxyRealm);
       
   935 	profile->GetParameter(KSIPOutboundProxy,KSIPDigestUserName, thisProxyUser);
       
   936 	
       
   937 					 	
       
   938 	TInt size = iProfileArray.Count();
       
   939 		
       
   940 	TUint32	iapId;
       
   941 	TUint32 profileId;
       
   942 	const TDesC8*	aor = NULL;
       
   943 	const TDesC8*	registrar = NULL;
       
   944 	const TDesC8*	proxy = NULL;
       
   945 	const TDesC8*	regRealm = NULL;
       
   946 	const TDesC8*	proxyRealm = NULL;
       
   947 	const TDesC8*	regUser = NULL;
       
   948 	const TDesC8*	proxyUser = NULL;
       
   949 	
       
   950 	//Iterate through profiles in iProfileArray
       
   951 	//and match
       
   952 	
       
   953 	for (TInt count=0; count<size; count++)
       
   954 		{
       
   955 		iProfileArray[count]->GetParameter(KSIPProfileId, profileId);
       
   956 		if (profileId == thisProfileId)
       
   957 			{
       
   958 			//profile Id for an existing profile was passed
       
   959 			return profileId;
       
   960 			}
       
   961 		iProfileArray[count]->GetParameter(KSIPAccessPointId, iapId);
       
   962 		if (iapId != thisIapId)
       
   963 			{
       
   964 		    continue;
       
   965 			}
       
   966 		iProfileArray[count]->GetParameter(KSIPUserAor, aor);
       
   967 		if (aor != thisAor)
       
   968 			{
       
   969 		    continue;
       
   970 			}
       
   971 		
       
   972 		iProfileArray[count]->GetParameter(KSIPRegistrar,KSIPServerAddress, registrar);
       
   973 		if (registrar != thisRegistrar)
       
   974 			{
       
   975 			continue;
       
   976 			}
       
   977 			
       
   978 		iProfileArray[count]->GetParameter(KSIPOutboundProxy,KSIPServerAddress, proxy);
       
   979 		if (proxy != thisProxy)
       
   980 			{
       
   981 			continue;
       
   982 			}
       
   983 		
       
   984 		iProfileArray[count]->GetParameter(KSIPRegistrar,KSIPDigestRealm, regRealm);
       
   985 		if(regRealm != thisRegRealm)
       
   986 			{
       
   987 			continue;
       
   988 			}
       
   989 		iProfileArray[count]->GetParameter(KSIPOutboundProxy,KSIPDigestRealm, proxyRealm);
       
   990 		if (proxyRealm != thisProxyRealm)
       
   991 			{
       
   992 			continue;
       
   993 			}
       
   994 		iProfileArray[count]->GetParameter(KSIPRegistrar,KSIPDigestUserName, regUser);
       
   995 		if (regUser != thisRegUser)
       
   996 			{
       
   997 			continue;
       
   998 			}
       
   999 		
       
  1000 		iProfileArray[count]->GetParameter(KSIPOutboundProxy,KSIPDigestUserName, proxyUser);
       
  1001 		if (proxyUser != thisProxyUser)
       
  1002 			{
       
  1003 			continue;
       
  1004 			}
       
  1005 		//Duplicate profile found
       
  1006 		return profileId;
       
  1007 		}
       
  1008 		
       
  1009 	return KSIPInvalidProfileId;
       
  1010 	}
       
  1011 	
       
  1012 	
       
  1013 
       
  1014 EXPORT_C void CSIPTransitionEngine::AddCredentialsL(TSIPCredentials aCredential)
       
  1015 	{
       
  1016 	iCredentialsArray.AppendL(aCredential);
       
  1017 	}
       
  1018 	
       
  1019 EXPORT_C const TDesC8* CSIPTransitionEngine::GetFromField(TUint32 aProfileId) const
       
  1020     {
       
  1021 	TInt size = iProfileArray.Count();
       
  1022 	CSIPProfile* profile = NULL;
       
  1023     const TDesC8* userName = NULL;
       
  1024     TUint32 profileId = KSIPInvalidProfileId;
       
  1025 	
       
  1026 	for (TInt count = 0; count<size; count++)
       
  1027 		{
       
  1028 		profile = iProfileArray[count];
       
  1029 		profile->GetParameter(KSIPProfileId, profileId);
       
  1030 		if (profileId == aProfileId)
       
  1031 			{
       
  1032 			profile->GetParameter(KSIPUserAor, userName);
       
  1033 			}
       
  1034 		}
       
  1035 	return userName;
       
  1036     }	
       
  1037 	
       
  1038 	
       
  1039 MSIPRegistrationClient*	CSIPTransitionEngine::FindRegistrationClient(TUint32 aProfileId)
       
  1040 	{
       
  1041 	TInt size = iRegClientArray.Count();
       
  1042 	for (TInt count = 0; count<size; count++)
       
  1043 		{
       
  1044 		if(aProfileId == iRegClientArray[count]->GetProfileId())
       
  1045 			{
       
  1046 			return iRegClientArray[count];
       
  1047 			}
       
  1048 		}
       
  1049 		return NULL;
       
  1050 	}
       
  1051 
       
  1052 //From MSIPHttpDigestChallengeObserver
       
  1053 void CSIPTransitionEngine::ChallengeReceived(const TDesC8& aRealm)
       
  1054 	{
       
  1055 	//Walkthrough the list of Realms to find credentials
       
  1056 	if (!FindAndSetCredentials(aRealm))
       
  1057 		{
       
  1058 		TInt size = iSMArray.Count();
       
  1059 		//Walk through State Machines and find the current outgoing active state machine
       
  1060 		for (TInt count=0; count<size; count++)
       
  1061 			{
       
  1062 			CSipStateMachine* smPtr= iSMArray[count]->iStateMachine;
       
  1063 			if(!smPtr->GetIncomingStatus() && smPtr->GetOutgoingStatus())
       
  1064 				{
       
  1065 				iDigest->IgnoreChallenge(aRealm);
       
  1066 				smPtr->ChallengeIgnored(aRealm);
       
  1067 				}
       
  1068 			}
       
  1069 		}
       
  1070 	
       
  1071 	}
       
  1072 	
       
  1073 	
       
  1074 TBool CSIPTransitionEngine::FindAndSetCredentials(const TDesC8& aRealm)
       
  1075 	{
       
  1076 	TInt size = iCredentialsArray.Count();
       
  1077 	
       
  1078 	for (TInt count=0; count<size; count++)
       
  1079 		{
       
  1080 		if (aRealm == iCredentialsArray[count].iRealm)
       
  1081 			{
       
  1082 			TRAPD(err, iDigest->SetCredentialsL(iCredentialsArray[count].iRealm,
       
  1083 												iCredentialsArray[count].iUserName,
       
  1084 												iCredentialsArray[count].iPasswd));
       
  1085 			if(err != KErrNone)
       
  1086 				{
       
  1087 				return ETrue;
       
  1088 				}
       
  1089 			}
       
  1090 		}
       
  1091 	return EFalse;
       
  1092 	}