realtimenetprots/sipfw/SIP/TransactionUser/src/UserAgentClient.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).627
       
     2 
       
     3 // All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 //
       
     9 // Initial Contributors:
       
    10 // Nokia Corporation - initial contribution.
       
    11 //
       
    12 // Contributors:
       
    13 //
       
    14 // Description:
       
    15 // Name          : UserAgentClient.cpp
       
    16 // Part of       : TransactionUser
       
    17 // Version       : SIP/6.0
       
    18 //
       
    19 
       
    20 
       
    21 
       
    22 #include "siperr.h"
       
    23 #include "SipAssert.h"
       
    24 #include "MSipRegistrations.h"
       
    25 #include "sipcseqheader.h"
       
    26 #include "sipuri.h"
       
    27 #include "uricontainer.h"
       
    28 #include "siphostport.h"
       
    29 #include "sipaddress.h"
       
    30 #include "sipcallidheader.h"
       
    31 #include "sipviaheader.h"
       
    32 #include "sipfromheader.h"
       
    33 #include "siprouteheader.h"
       
    34 #include "sipstrings.h"
       
    35 #include "sipstrconsts.h"
       
    36 #include "sipsec.h"
       
    37 #include "siprequest.h"
       
    38 #include "sipresponse.h"
       
    39 #include "Transmitter.h"
       
    40 
       
    41 #include "UserAgentClient.h"
       
    42 #include "UserAgentState.h"
       
    43 #include "CTransactionStore.h"
       
    44 #include "SIPMessageUtility.h"
       
    45 #include "SIPRequestUtility.h"
       
    46 #include "MTransactionUser.h"
       
    47 #include "MTransactionOwner.h"
       
    48 #include "RouteSet.h"
       
    49 #include "ResolvingResults.h"
       
    50 #include "StopUserAgent.h"
       
    51 #include "RestoreUaState.h"
       
    52 #include "MSIPSecUser.h"
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // CUserAgentClient::CUserAgentClient
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 CUserAgentClient::CUserAgentClient(CUserAgentCreateParams& aParams,
       
    59 								   MSipUriResolver& aResolver,
       
    60                                    CSIPSec& aSIPSec,
       
    61 					               TUint32 aCSeqNumber) :
       
    62 	CUserAgent(aParams),
       
    63 	iSIPSec(aSIPSec),
       
    64 	iCSeqNumber(aCSeqNumber),
       
    65 	iResolver(aResolver),
       
    66 	iSipSecError(KErrNone),
       
    67     iFinalRespPassed(EFalse),
       
    68     iOutboundProxyHasBeenTried(EFalse),
       
    69     iLastError(KErrNone),
       
    70     iIgnoreSIPSecCallback(EFalse)
       
    71 	{
       
    72 	}
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CUserAgentClient::ConstructL
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 void CUserAgentClient::ConstructL()
       
    79 	{
       
    80 	iResolvingResults = CResolvingResults::NewL();	
       
    81 	}
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CUserAgentClient::~CUserAgentClient
       
    85 // -----------------------------------------------------------------------------
       
    86 //
       
    87 CUserAgentClient::~CUserAgentClient()
       
    88 	{
       
    89 	iResolver.CancelGetByUri(this);
       
    90 	CancelSIPSecRequest();
       
    91 	delete iResolvingResults;	
       
    92     delete iRemoteTarget;
       
    93     delete iRouteSet;
       
    94     delete iRequestUri;
       
    95 	}
       
    96 
       
    97 // -----------------------------------------------------------------------------
       
    98 // CUserAgentClient::IsUAS
       
    99 // -----------------------------------------------------------------------------
       
   100 //
       
   101 TBool CUserAgentClient::IsUAS() const
       
   102 	{
       
   103 	__TEST_INVARIANT;
       
   104 	return EFalse;
       
   105 	}
       
   106 
       
   107 // -----------------------------------------------------------------------------
       
   108 // CUserAgentClient::RegistrationId
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 TRegistrationId CUserAgentClient::RegistrationId() const
       
   112 	{
       
   113 	__TEST_INVARIANT;
       
   114 	return iRegisterId;
       
   115 	}
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CUserAgentClient::CompletedL
       
   119 // Resolving succeeded so clear the stored error.
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 void CUserAgentClient::CompletedL()
       
   123 	{
       
   124 	__TEST_INVARIANT;
       
   125 
       
   126 	if (!HasStopped())
       
   127 		{
       
   128 		iLastError = KErrNone;
       
   129 		delete iIncomingMsg;
       
   130 		iIncomingMsg = NULL;
       
   131 		State().AddressResolvedL(*this);
       
   132 		}
       
   133 
       
   134 	__TEST_INVARIANT;
       
   135 	}
       
   136 
       
   137 // -----------------------------------------------------------------------------
       
   138 // CUserAgentClient::ErrorOccured
       
   139 // -----------------------------------------------------------------------------
       
   140 //
       
   141 void CUserAgentClient::ErrorOccured(TInt aError)
       
   142 	{
       
   143 	__TEST_INVARIANT;
       
   144 
       
   145 	if (!HasStopped())
       
   146 		{
       
   147 		if (aError == KErrSIPResolvingFailure)
       
   148 			{
       
   149 			// URI fully resolved. Old results not needed.
       
   150 			iResolvingResults->ClearAll();
       
   151 			State().ResolvingFailed(*this);
       
   152 			}
       
   153 		else
       
   154 			{
       
   155 			// Leave came in MSIPServerResolverObserver::CompletedL
       
   156 			Stop(aError);
       
   157 			}
       
   158 		}
       
   159 
       
   160 	__TEST_INVARIANT;
       
   161 	}
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CUserAgentClient::SIPSecCacheUpdated
       
   165 // Don't use __TEST_INVARIANT as destructor may lead here.
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 void CUserAgentClient::SIPSecCacheUpdated(TBool aSuccess)
       
   169 	{
       
   170 	if (!iIgnoreSIPSecCallback)
       
   171 		{
       
   172 		SIPSecReady(aSuccess);
       
   173 		}
       
   174 	}
       
   175 
       
   176 // -----------------------------------------------------------------------------
       
   177 // CUserAgentClient::SIPSecTimerExpiredL
       
   178 // -----------------------------------------------------------------------------
       
   179 //
       
   180 void CUserAgentClient::SIPSecTimerExpiredL()
       
   181 	{
       
   182 	__TEST_INVARIANT;
       
   183 
       
   184 	TInt err = SIPSecReady(ETrue);
       
   185 	if (err != KErrNone)
       
   186 		{
       
   187 		User::Leave(err);
       
   188 		}
       
   189 
       
   190 	__TEST_INVARIANT;
       
   191 	}
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CUserAgentClient::SIPSecReady
       
   195 // TRAP may delete UA. Check if UA exists before stopping. Don't use
       
   196 // __TEST_INVARIANT after Stop.
       
   197 // -----------------------------------------------------------------------------
       
   198 //
       
   199 TInt CUserAgentClient::SIPSecReady(TBool aSuccess)
       
   200 	{
       
   201 	__TEST_INVARIANT;
       
   202 
       
   203     TTransactionId transactionId = TransactionId();
       
   204     CTransactionStore& store = iTransactionStore;
       
   205 
       
   206 	TRAPD(err, State().SIPSecCacheUpdatedL(*this, aSuccess));
       
   207 	if (err != KErrNone && store.SearchById(transactionId))
       
   208 		{
       
   209         Stop(err);
       
   210 		}
       
   211 
       
   212 	return err;
       
   213 	}
       
   214 
       
   215 // -----------------------------------------------------------------------------
       
   216 // CUserAgentClient::HandleSendRequestL
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 void CUserAgentClient::HandleSendRequestL(CSIPRequest* aReq,
       
   220 										  TRegistrationId aRegisterId,
       
   221 										  const CURIContainer& aRemoteTarget,
       
   222                                           const CUserAgentState& aResolve)
       
   223 	{
       
   224 	__TEST_INVARIANT;
       
   225     __SIP_ASSERT_LEAVE(aReq, KErrArgument);
       
   226     __SIP_ASSERT_LEAVE(!iRouteSet && !iRemoteTarget, KErrAlreadyExists);
       
   227 
       
   228 	iRegisterId = aRegisterId;
       
   229     StoreRemoteTargetL(aRemoteTarget);
       
   230     iRouteSet = CRouteSet::NewL(*aReq, iRegistrations, iRegisterId);
       
   231 
       
   232     SIPRequestUtility::CheckOutgoingRequestL(*aReq);
       
   233 	FillRequestL(*aReq);
       
   234 	StoreRequestUriL(*aReq);
       
   235 	
       
   236 	TBool isRegMsg = (SIPStrings::StringF(SipStrConsts::ERegister) == aReq->Method());
       
   237 	ResolveNextHopL(ETrue,!isRegMsg);
       
   238 
       
   239 	UpdateInfoToStoreL(aReq);
       
   240 	StoreOutgoingMsg(aReq);
       
   241     ChangeState(aResolve);
       
   242 
       
   243 	__TEST_INVARIANT;
       
   244 	}
       
   245 
       
   246 // -----------------------------------------------------------------------------
       
   247 // CUserAgentClient::FillRequestL
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 void CUserAgentClient::FillRequestL(CSIPRequest& aReq) const
       
   251 	{
       
   252 	__TEST_INVARIANT;
       
   253 	__SIP_ASSERT_LEAVE(iRouteSet && iRemoteTarget, KErrNotFound);
       
   254 
       
   255 	CSIPMessageUtility::FillCSeqL(aReq, iCSeqNumber, aReq.Method());
       
   256 
       
   257 	if (!aReq.HasHeader(SIPStrings::StringF(SipStrConsts::ECallIDHeader)))
       
   258 		{
       
   259         FillNewCallIdL(aReq);
       
   260 		}
       
   261 
       
   262 	if (!aReq.HasHeader(SIPStrings::StringF(SipStrConsts::EMaxForwardsHeader)))
       
   263 		{
       
   264 		SIPRequestUtility::FillNewMaxForwardsL(aReq);
       
   265 		}
       
   266 
       
   267 	CheckContactHeadersL(aReq, aReq.From());
       
   268 	SIPRequestUtility::FillRouteAndRequestUriL(aReq,
       
   269 											   *iRouteSet,
       
   270 											   *iRemoteTarget);
       
   271     FillNewViaL(aReq, SIPStrings::StringF(SipStrConsts::EEmpty));
       
   272 
       
   273     CSIPFromHeader* from = aReq.From();
       
   274     __SIP_ASSERT_LEAVE(from != NULL, KErrArgument);
       
   275 	if (!from->HasParam(SIPStrings::StringF(SipStrConsts::ETag)))
       
   276 		{
       
   277 		AddTagL(*from);
       
   278 		}
       
   279 	}
       
   280 
       
   281 // -----------------------------------------------------------------------------
       
   282 // CUserAgentClient::UpdateViaAndCSeqL
       
   283 // -----------------------------------------------------------------------------
       
   284 //
       
   285 void CUserAgentClient::UpdateViaAndCSeqL() const
       
   286 	{
       
   287 	__TEST_INVARIANT;
       
   288     __SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound);
       
   289 
       
   290 	CSIPRequest* req = static_cast<CSIPRequest*>(iOutgoingMsg);
       
   291     FillNewViaL(*req, SIPStrings::StringF(SipStrConsts::EEmpty));
       
   292 
       
   293     CSIPCSeqHeader* cseqHeader = req->CSeq();
       
   294     __SIP_ASSERT_LEAVE(cseqHeader != NULL, KErrSIPMalformedMessage);
       
   295 	TUint cseq = cseqHeader->Seq();
       
   296 
       
   297 	if (iObserver)
       
   298 		{
       
   299 		User::LeaveIfError(iObserver->NextCSeq(cseq));
       
   300 		}
       
   301 	else
       
   302 		{
       
   303 		++cseq;
       
   304 		}
       
   305 	cseqHeader->SetSeq(cseq);
       
   306 	}
       
   307 
       
   308 // -----------------------------------------------------------------------------
       
   309 // CUserAgentClient::FillNewCallIdL
       
   310 // -----------------------------------------------------------------------------
       
   311 //
       
   312 void CUserAgentClient::FillNewCallIdL(CSIPRequest& aReq) const
       
   313 	{
       
   314 	__TEST_INVARIANT;
       
   315 
       
   316 	TBuf8<MTransactionUser::KCallIDLength> callID;
       
   317 	AddRandomStringL(callID, MTransactionUser::KCallIDLength, ETrue);
       
   318 	CSIPCallIDHeader* callIdHeader = CSIPCallIDHeader::DecodeL(callID);
       
   319 	CleanupStack::PushL(callIdHeader);
       
   320 	aReq.AddHeaderL(callIdHeader);
       
   321 	CleanupStack::Pop(callIdHeader);
       
   322 	}
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 // CUserAgentClient::SetBranchL
       
   326 // -----------------------------------------------------------------------------
       
   327 //
       
   328 void CUserAgentClient::SetBranchL(CSIPViaHeader& aVia, RStringF aBranch) const
       
   329 	{
       
   330 	__TEST_INVARIANT;
       
   331 
       
   332 	if (aBranch == SIPStrings::StringF(SipStrConsts::EEmpty))
       
   333 		{
       
   334 		const TInt KBranchLength = 30;
       
   335     	__ASSERT_DEBUG(
       
   336     		KBranchLength > CSIPMessageUtility::BranchMagicCookie().Length(),
       
   337 			User::Panic(_L("UAC:SetBranchL"), KErrOverflow));
       
   338 		TBuf8<KBranchLength> branchBuf;
       
   339 		branchBuf.Append(CSIPMessageUtility::BranchMagicCookie());
       
   340 		AddRandomStringL(branchBuf, KBranchLength - branchBuf.Length(), EFalse);
       
   341 
       
   342 		RStringF branch = SIPStrings::Pool().OpenFStringL(branchBuf);
       
   343 		CleanupClosePushL(branch);
       
   344 		aVia.SetParamL(SIPStrings::StringF(SipStrConsts::EBranch), branch);	
       
   345 		CleanupStack::PopAndDestroy(); // branch
       
   346 		}
       
   347 	else
       
   348 		{
       
   349 		aVia.SetParamL(SIPStrings::StringF(SipStrConsts::EBranch), aBranch);
       
   350 		}
       
   351 	}
       
   352 
       
   353 // -----------------------------------------------------------------------------
       
   354 // CUserAgentClient::FillNewViaL
       
   355 // -----------------------------------------------------------------------------
       
   356 //
       
   357 void CUserAgentClient::FillNewViaL(CSIPRequest& aReq, RStringF aBranch) const
       
   358 	{
       
   359 	__TEST_INVARIANT;
       
   360 
       
   361 	CSIPViaHeader* via = CSIPMessageUtility::TopVia(aReq);
       
   362 	if (via)
       
   363 		{
       
   364 		SetBranchL(*via, aBranch);
       
   365 		via->SetTransportL(iTransportProtocol);
       
   366 		}
       
   367 	else
       
   368 		{
       
   369 		CSIPHostPort* hp = CSIPHostPort::DecodeL(
       
   370 			SIPStrings::StringF(SipStrConsts::ELocalHost).DesC());
       
   371 		CleanupStack::PushL(hp);
       
   372 		via = CSIPViaHeader::NewL(iTransportProtocol, hp);
       
   373 		CleanupStack::Pop(hp);
       
   374 		CleanupStack::PushL(via);
       
   375 	
       
   376 		SetBranchL(*via, aBranch);
       
   377 
       
   378 		aReq.AddHeaderL(via);
       
   379 		CleanupStack::Pop(via);
       
   380 		}
       
   381 	}
       
   382 
       
   383 // -----------------------------------------------------------------------------
       
   384 // CUserAgentClient::StoreRequestUriL
       
   385 // -----------------------------------------------------------------------------
       
   386 //
       
   387 void CUserAgentClient::StoreRequestUriL(CSIPRequest &aReq)
       
   388 	{
       
   389 	__TEST_INVARIANT;
       
   390 	__SIP_ASSERT_LEAVE(aReq.RequestURI() != NULL, KErrArgument);
       
   391 
       
   392 	CURIContainer* newUri = CURIContainer::NewL(*aReq.RequestURI());
       
   393 	delete iRequestUri;
       
   394 	iRequestUri = newUri;
       
   395 
       
   396 	__TEST_INVARIANT;
       
   397 	}
       
   398 
       
   399 // -----------------------------------------------------------------------------
       
   400 // CUserAgentClient::UpdateInfoToStoreL
       
   401 // -----------------------------------------------------------------------------
       
   402 //
       
   403 void CUserAgentClient::UpdateInfoToStoreL(CSIPRequest* aReq) const
       
   404 	{
       
   405 	__TEST_INVARIANT;
       
   406 
       
   407 	iTransactionStore.UpdateL(TransactionId(), iTransaction, aReq);
       
   408 	}
       
   409 
       
   410 // -----------------------------------------------------------------------------
       
   411 // CUserAgentClient::ResolveNextHopL
       
   412 // -----------------------------------------------------------------------------
       
   413 //
       
   414 void CUserAgentClient::ResolveNextHopL(TBool aCheckSigComp,TBool aUseResolvedProxy)
       
   415 	{
       
   416 	__TEST_INVARIANT;
       
   417 
       
   418 	CURIContainer& uri = NextHopL(aUseResolvedProxy);
       
   419 	if (aCheckSigComp)
       
   420 		{
       
   421 		CheckSigCompL(uri);
       
   422 		}
       
   423 
       
   424 	iResolver.GetByURIL(uri,
       
   425 						iResolvingResults->Addresses(),
       
   426 						TransportParams(),
       
   427 						this);
       
   428 	__TEST_INVARIANT;
       
   429 	}
       
   430 
       
   431 // -----------------------------------------------------------------------------
       
   432 // CUserAgentClient::CopyRemoteAddress
       
   433 // Clear resolving results as CANCEL must use only one ip-address.
       
   434 // -----------------------------------------------------------------------------
       
   435 //
       
   436 void CUserAgentClient::CopyRemoteAddress(const CUserAgentClient& aSrc)
       
   437 	{
       
   438 	__TEST_INVARIANT;
       
   439 
       
   440 	iRemoteAddr = aSrc.iRemoteAddr;
       
   441 	iForceUDP = aSrc.iForceUDP;
       
   442 
       
   443 	iTransportProtocol.Close();
       
   444 	if (aSrc.iTransaction)
       
   445 		{
       
   446 		iTransportProtocol = aSrc.iTransaction->TransportProtocol().Copy();
       
   447 		}
       
   448 	else
       
   449 		{
       
   450 		RStringF protocol = aSrc.iTransportProtocol;
       
   451 		iTransportProtocol = protocol.Copy();
       
   452 		}
       
   453 
       
   454 	iResolvingResults->ClearAll();
       
   455 
       
   456 	__TEST_INVARIANT;
       
   457 	}
       
   458 
       
   459 // -----------------------------------------------------------------------------
       
   460 // CUserAgentClient::CopyRouteSetAndRemoteTargetL
       
   461 // -----------------------------------------------------------------------------
       
   462 //
       
   463 void
       
   464 CUserAgentClient::CopyRouteSetAndRemoteTargetL(const CUserAgentClient& aSrc)
       
   465 	{
       
   466 	__TEST_INVARIANT;
       
   467 	__SIP_ASSERT_LEAVE(!iRouteSet && !iRemoteTarget, KErrAlreadyExists);
       
   468 	__SIP_ASSERT_LEAVE(aSrc.iRouteSet && aSrc.iRemoteTarget, KErrNotFound);
       
   469 
       
   470 	iRouteSet = CRouteSet::NewL(*aSrc.iRouteSet);
       
   471 	iRemoteTarget = CURIContainer::NewL(*aSrc.iRemoteTarget);
       
   472 
       
   473     __TEST_INVARIANT;
       
   474 	}
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // CUserAgentClient::StoreRemoteTargetL
       
   478 // -----------------------------------------------------------------------------
       
   479 //
       
   480 void CUserAgentClient::StoreRemoteTargetL(const CURIContainer& aRemoteTarget)
       
   481 	{
       
   482 	__TEST_INVARIANT;
       
   483 
       
   484 	CURIContainer* newRemoteTarget = CURIContainer::NewL(aRemoteTarget);
       
   485 	delete iRemoteTarget;
       
   486 	iRemoteTarget = newRemoteTarget;
       
   487 
       
   488 	__TEST_INVARIANT;
       
   489 	}
       
   490 
       
   491 // -----------------------------------------------------------------------------
       
   492 // CUserAgentClient::NextHopL
       
   493 // -----------------------------------------------------------------------------
       
   494 //
       
   495 CURIContainer& CUserAgentClient::NextHopL(TBool aUseResolvedProxy) const
       
   496 	{
       
   497 	__TEST_INVARIANT;
       
   498 	__ASSERT_ALWAYS(iRouteSet && iRemoteTarget,
       
   499         			User::Panic(_L("UAC:NextHop"), KErrNotFound)); 
       
   500 	
       
   501 	if (aUseResolvedProxy && iRegistrations.HasOutboundProxy(iRegisterId))
       
   502 	    {
       
   503 	    if(iRegistrations.OutboundProxy(iRegisterId)->SIPAddress().URI() == 
       
   504 	    	iRouteSet->NextHop(*iRemoteTarget))
       
   505 	    	{
       
   506 		    if(iRegistrations.IsCacheOutboundProxyIPEanbled(iRegisterId))
       
   507 		    	{
       
   508 		    	TRAPD(err,iRegistrations.OutboundProxyIPL(iRegisterId))
       
   509 		    	if(KErrNone == err)
       
   510 		    		{
       
   511 		    		return iRegistrations.OutboundProxyIPL(iRegisterId).SIPAddress().URI();
       
   512 		    		}
       
   513 		    	}
       
   514 		    }
       
   515 	    }
       
   516 	return iRouteSet->NextHop(*iRemoteTarget);
       
   517 	}
       
   518 
       
   519 // -----------------------------------------------------------------------------
       
   520 // CUserAgentClient::SetRequestOwnership
       
   521 // -----------------------------------------------------------------------------
       
   522 //
       
   523 void CUserAgentClient::SetRequestOwnership(TBool aOwnsRequest)
       
   524 	{
       
   525 	__TEST_INVARIANT;
       
   526 
       
   527 	iOwnsOutgoingMsg = aOwnsRequest;
       
   528 
       
   529 	__TEST_INVARIANT;
       
   530 	}
       
   531 
       
   532 // -----------------------------------------------------------------------------
       
   533 // CUserAgentClient::StoreResponse
       
   534 // -----------------------------------------------------------------------------
       
   535 //
       
   536 void CUserAgentClient::StoreResponse(CSIPResponse* aResponse)
       
   537 	{
       
   538 	__TEST_INVARIANT;
       
   539 	__SIP_ASSERT_RETURN(!iIncomingMsg, KErrAlreadyExists);
       
   540 
       
   541 	iIncomingMsg = aResponse;
       
   542 
       
   543 	__TEST_INVARIANT;
       
   544 	}
       
   545 
       
   546 // -----------------------------------------------------------------------------
       
   547 // CUserAgentClient::SelectNextRemoteAddressL
       
   548 // -----------------------------------------------------------------------------
       
   549 //
       
   550 TBool CUserAgentClient::SelectNextRemoteAddressL()
       
   551 	{
       
   552 	__TEST_INVARIANT;
       
   553 
       
   554 	iSIPSecCounter = 0; // Remote address changes, reset counter
       
   555 	if (!iResolvingResults->GetNext(iRemoteAddr, iTransportProtocol, iForceUDP))
       
   556 		{
       
   557 		return EFalse;
       
   558 		}
       
   559 	if(iRemoteAddr.IsUnspecified())
       
   560 		{
       
   561 		return EFalse;
       
   562 		}
       
   563 
       
   564 	__SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound);
       
   565 	CSIPMessageUtility::UpdateViaTransportL(*iOutgoingMsg, iTransportProtocol);
       
   566 
       
   567 	__TEST_INVARIANT;
       
   568 	return ETrue;
       
   569 	}
       
   570 
       
   571 // -----------------------------------------------------------------------------
       
   572 // CUserAgentClient::RemoteAddressResolvedL
       
   573 // -----------------------------------------------------------------------------
       
   574 //
       
   575 void CUserAgentClient::RemoteAddressResolvedL(const CUserAgentState& aNextState)
       
   576 	{
       
   577 	__TEST_INVARIANT;
       
   578 	__SIP_ASSERT_LEAVE(SelectNextRemoteAddressL(), KErrNotFound);
       
   579 
       
   580 	if (FillSecurityParamsL())	
       
   581 		{
       
   582 	    CreateTransactionL();
       
   583 		UpdateInfoToStoreL(NULL /* don't update message headers */);
       
   584 		SendRequestToNetworkL();
       
   585 		ChangeState(aNextState);
       
   586 		}
       
   587 
       
   588 	__TEST_INVARIANT;
       
   589 	}
       
   590 
       
   591 // -----------------------------------------------------------------------------
       
   592 // CUserAgentClient::HandleResolvingFailure
       
   593 // -----------------------------------------------------------------------------
       
   594 //
       
   595 void
       
   596 CUserAgentClient::HandleResolvingFailure(const CUserAgentState& aResolve,
       
   597 				  					     const CUserAgentState& aWaitResponse)
       
   598 	{
       
   599 	__TEST_INVARIANT;
       
   600 
       
   601 	TBool retry(ETrue);
       
   602 	TRAPD(err, retry = TryNextAddressL(KErrSIPResolvingFailure,
       
   603 							 		   aResolve,
       
   604 							 		   aWaitResponse));
       
   605 	if (err != KErrNone || !retry)
       
   606 		{
       
   607 		StopWithLastError();
       
   608 		}
       
   609 
       
   610 	__TEST_INVARIANT;
       
   611 	}
       
   612 
       
   613 // -----------------------------------------------------------------------------
       
   614 // CUserAgentClient::FillSecurityParamsL
       
   615 // -----------------------------------------------------------------------------
       
   616 //
       
   617 TBool CUserAgentClient::FillSecurityParamsL()
       
   618 	{
       
   619 	__TEST_INVARIANT;
       
   620 	__SIP_ASSERT_LEAVE(iOutgoingMsg && iRemoteTarget, KErrNotFound);
       
   621 
       
   622 	if (!iObserver)
       
   623 		{
       
   624 		Stop(KErrNone);
       
   625 		return EFalse;
       
   626 		}
       
   627 
       
   628 	if (UseSIPSec())
       
   629 		{
       
   630 		CUri8* remoteTarget = iRemoteTarget->CloneAsUri8L();
       
   631 		CleanupStack::PushL(remoteTarget);
       
   632 		TRAPD(err, iSIPSec.AddSecurityParamsL(
       
   633 					iTransportParams,
       
   634 					static_cast<CSIPRequest&>(*iOutgoingMsg),
       
   635 					RegistrationId(),
       
   636 					TransactionId(),
       
   637 					iRemoteAddr,
       
   638 					CSIPMessageUtility::UriDescriptor(NextHopL()),
       
   639 					*remoteTarget,
       
   640 					ProxyL(),
       
   641 					const_cast<MSIPSecUser&>(*iObserver->SIPSecUser())));
       
   642 		CleanupStack::PopAndDestroy(remoteTarget);
       
   643 		HandleSIPSecErrorL(err);
       
   644 		}
       
   645 
       
   646 	__TEST_INVARIANT;
       
   647 	return ETrue;
       
   648 	}
       
   649 
       
   650 // -----------------------------------------------------------------------------
       
   651 // CUserAgentClient::HandleSIPSecErrorL
       
   652 // -----------------------------------------------------------------------------
       
   653 //
       
   654 void CUserAgentClient::HandleSIPSecErrorL(TInt aError)
       
   655 	{
       
   656 	__TEST_INVARIANT;
       
   657 	
       
   658 	if (aError != KErrNone)		
       
   659 		{
       
   660 		if (aError != KErrNoMemory)
       
   661 			{
       
   662 			aError = KErrSIPForbidden;
       
   663 			}
       
   664 		Stop(aError);
       
   665 		User::Leave(aError);
       
   666 		}
       
   667 	}
       
   668 
       
   669 // -----------------------------------------------------------------------------
       
   670 // CUserAgentClient::SIPSecCacheUpdatedL
       
   671 // -----------------------------------------------------------------------------
       
   672 //
       
   673 void CUserAgentClient::SIPSecCacheUpdatedL(TBool aSuccess,
       
   674 	const CUserAgentState& aResolve,
       
   675 	const CUserAgentState& aWaitResponse,
       
   676 	const CUserAgentState& aWaitAckFromApp,
       
   677 	const CUserAgentState& aWaitTransactionToEnd)
       
   678 	{
       
   679 	__TEST_INVARIANT;
       
   680     __SIP_ASSERT_LEAVE(iIncomingMsg, KErrNotFound);
       
   681 
       
   682 	if (aSuccess)
       
   683 		{
       
   684 		CSIPResponse* resp = static_cast<CSIPResponse*>(iIncomingMsg);
       
   685 		iIncomingMsg = NULL;
       
   686 		CleanupStack::PushL(resp);
       
   687 		ReceiveResponseL(resp,
       
   688 						 aResolve,
       
   689 					 	 aWaitResponse,
       
   690 						 aWaitAckFromApp,
       
   691 						 aWaitTransactionToEnd);
       
   692 		CleanupStack::Pop(resp);
       
   693 		}
       
   694 	else
       
   695 		{
       
   696         Stop(KErrSIPForbidden);
       
   697 		}
       
   698 
       
   699     __TEST_INVARIANT;
       
   700 	}
       
   701 
       
   702 // -----------------------------------------------------------------------------
       
   703 // CUserAgentClient::ProxyL
       
   704 // -----------------------------------------------------------------------------
       
   705 //
       
   706 const TDesC8& CUserAgentClient::ProxyL() const
       
   707 	{
       
   708 	__TEST_INVARIANT;
       
   709 
       
   710 	CURIContainer& nextHop = NextHopL();
       
   711 	if (iRegistrations.IsOutboundProxy(nextHop))
       
   712 		{
       
   713 		return CSIPMessageUtility::UriDescriptor(nextHop);
       
   714 		}
       
   715 	return KNullDesC8;
       
   716 	}
       
   717 
       
   718 // -----------------------------------------------------------------------------
       
   719 // CUserAgentClient::SendRequestToNetworkL
       
   720 // -----------------------------------------------------------------------------
       
   721 //
       
   722 void CUserAgentClient::SendRequestToNetworkL()
       
   723 	{
       
   724 	__TEST_INVARIANT;
       
   725     __SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound);
       
   726 
       
   727 	CUri8* proxy(NULL);
       
   728     const CSIPRouteHeader* route = iRegistrations.OutboundProxy(iRegisterId);
       
   729     if (route)
       
   730         {
       
   731         proxy = route->SIPAddress().URI().CloneAsUri8L();
       
   732 		}
       
   733 	CleanupStack::PushL(proxy);
       
   734 
       
   735 	if (CSIPMessageUtility::IsAck(*iOutgoingMsg))
       
   736 		{
       
   737     	__SIP_ASSERT_LEAVE(iTransmitter, KErrNotFound);
       
   738 		iTransmitter->SendRequestL(static_cast<CSIPRequest&>(*iOutgoingMsg),
       
   739 							   	   iRemoteAddr,
       
   740 							   	   iForceUDP,
       
   741 							   	   TransportParams(),
       
   742 							   	   proxy,
       
   743 							   	   this);
       
   744 		CleanupStack::PopAndDestroy(proxy);
       
   745 		}
       
   746 	else
       
   747 		{
       
   748 		__SIP_ASSERT_LEAVE(iTransaction, KErrNotFound);
       
   749 		iTransaction->SendRequestL(static_cast<CSIPRequest&>(*iOutgoingMsg),
       
   750 							   	   iRemoteAddr,
       
   751 							   	   iTransportProtocol,
       
   752 							   	   iForceUDP,
       
   753 							   	   TransportParams(),
       
   754 							   	   proxy);
       
   755 		CleanupStack::Pop(proxy);
       
   756 		}
       
   757 	__TEST_INVARIANT;
       
   758 	}
       
   759 
       
   760 // -----------------------------------------------------------------------------
       
   761 // CUserAgentClient::PassRespToTransactionOwnerL
       
   762 // -----------------------------------------------------------------------------
       
   763 //
       
   764 void CUserAgentClient::PassRespToTransactionOwnerL(CSIPResponse* aResp,
       
   765 												   CUserAgent* aUserAgent,
       
   766 												   CUserAgentTimer* aTimer)
       
   767 	{
       
   768 	__TEST_INVARIANT;
       
   769     __SIP_ASSERT_LEAVE(aResp, KErrArgument);
       
   770     __SIP_ASSERT_LEAVE(!iFinalRespPassed, KErrAlreadyExists);
       
   771 
       
   772     if (aResp->ResponseCode() == 100 && !IsInviteUAC())
       
   773         {
       
   774         delete aResp;
       
   775         }
       
   776     else
       
   777     	{
       
   778         TRestoreUaState restoreState(iFinalRespPassed, aUserAgent, aTimer);
       
   779         CleanupStack::PushL(restoreState.CleanupItem());
       
   780     	iFinalRespPassed = CSIPMessageUtility::IsFinalResponse(*aResp);
       
   781 
       
   782 		PassMsgToTransactionOwnerL(aResp);
       
   783 
       
   784         CleanupStack::Pop(); // cleanupItem
       
   785     	}
       
   786 
       
   787 	__TEST_INVARIANT;
       
   788 	}
       
   789 
       
   790 // -----------------------------------------------------------------------------
       
   791 // CUserAgentClient::FinalRespPassed
       
   792 // -----------------------------------------------------------------------------
       
   793 //
       
   794 TBool CUserAgentClient::FinalRespPassed() const
       
   795 	{
       
   796 	__TEST_INVARIANT;
       
   797 	return iFinalRespPassed;
       
   798 	}
       
   799 
       
   800 // -----------------------------------------------------------------------------
       
   801 // CUserAgentClient::PassResponseToSIPSecL
       
   802 // If no iObserver, ignore response and wait transaction to end.
       
   803 // -----------------------------------------------------------------------------
       
   804 //
       
   805 TBool CUserAgentClient::PassResponseToSIPSecL(CSIPResponse& aResp)
       
   806 	{
       
   807 	__TEST_INVARIANT;
       
   808 	__SIP_ASSERT_LEAVE(iOutgoingMsg && iRemoteTarget, KErrNotFound);
       
   809 
       
   810 	iResponseReceived = ETrue;
       
   811 	TBool mustWait(EFalse);
       
   812 
       
   813 	if (UseSIPSec() && CSIPMessageUtility::IsFinalResponse(aResp))  
       
   814 		{
       
   815 		CUri8* remoteTarget = iRemoteTarget->CloneAsUri8L();
       
   816 		TRAPD(err, mustWait = iSIPSec.ResponseReceivedL(iTransportParams,
       
   817 						 aResp,
       
   818 					     static_cast<CSIPRequest&>(*iOutgoingMsg),
       
   819 					     RegistrationId(),
       
   820 					     TransactionId(),
       
   821 	                     iRemoteAddr,
       
   822 	                     CSIPMessageUtility::UriDescriptor(NextHopL()),              
       
   823 	                     *remoteTarget,
       
   824 	                   	 ProxyL(),
       
   825 		                 const_cast<MSIPSecUser&>(*iObserver->SIPSecUser()),
       
   826 		                 *this));
       
   827 		delete remoteTarget;
       
   828 		if( err != KErrNone )
       
   829 			{
       
   830 			User::Leave( KErrSIPForbidden );
       
   831 			}
       
   832     	}
       
   833 
       
   834     __TEST_INVARIANT;
       
   835 	return mustWait;
       
   836 	}
       
   837 
       
   838 // -----------------------------------------------------------------------------
       
   839 // CUserAgentClient::ShouldUaTryAgainL
       
   840 // If no iObserver ignore response. If send leaves, ConnectionMgr calls old
       
   841 // transaction's MReceiverObserver::LeaveOccurred and cleanupItem stops UA.
       
   842 // -----------------------------------------------------------------------------
       
   843 //
       
   844 TBool CUserAgentClient::ShouldUaTryAgainL(CSIPResponse* aResp,
       
   845 										  const CUserAgentState& aResolve,
       
   846 										  const CUserAgentState& aWaitResponse)
       
   847 	{
       
   848 	__TEST_INVARIANT;
       
   849     __SIP_ASSERT_LEAVE(aResp, KErrArgument);
       
   850 
       
   851     TBool retry(EFalse);
       
   852 	if (!FinalRespPassed() && iObserver)
       
   853 		{
       
   854         TStopUserAgent stopUa(TransactionId(),
       
   855         					  iTransactionStore,
       
   856         					  KErrSIPForbidden);
       
   857         CleanupStack::PushL(stopUa.CleanupItem());
       
   858 
       
   859 		TInt respCode = aResp->ResponseCode();
       
   860 		if (respCode == 503 || respCode == 408)
       
   861 			{
       
   862 			retry =	TryNextAddressL(KErrNone, aResolve, aWaitResponse, aResp);
       
   863 			}
       
   864 		
       
   865 		if ((respCode == 401 || respCode == 407 || respCode == 494) && UseSIPSec())
       
   866 		    {
       
   867 		    if(iSipSecError)
       
   868 		        {
       
   869 		        __SIP_LOG( "Request can't be resubmitted because of insufficient information" ) 
       
   870 		        }
       
   871 		    else if(FillSecurityParamsL())
       
   872 		        {
       
   873 		        if (iSIPSecCounter > SIPRequestUtility::EMaxForwardsValue)
       
   874 				{
       
   875 				User::Leave(KErrSIPForbidden);
       
   876 				}
       
   877 		        ++iSIPSecCounter;
       
   878 		        UpdateAndSendRequestL(aWaitResponse);
       
   879 		        delete aResp;
       
   880 		        retry = ETrue;
       
   881 		        }
       
   882 		    }
       
   883         CleanupStack::Pop(); // cleanupItem
       
   884 		}
       
   885 
       
   886 	__TEST_INVARIANT;
       
   887 	return retry;
       
   888 	}
       
   889 
       
   890 // -----------------------------------------------------------------------------
       
   891 // CUserAgentClient::TransactionEndsWithoutFinalResponseL
       
   892 // -----------------------------------------------------------------------------
       
   893 //
       
   894 void CUserAgentClient::TransactionEndsWithoutFinalResponseL(TInt aReason,
       
   895 										const CUserAgentState& aResolve,
       
   896 										const CUserAgentState& aWaitResponse)
       
   897 	{
       
   898 	__TEST_INVARIANT;
       
   899 
       
   900 	TStopUserAgent stopUa(TransactionId(), iTransactionStore, KErrNoMemory);
       
   901     CleanupStack::PushL(stopUa.CleanupItem());
       
   902 
       
   903 	TBool retry(EFalse);
       
   904 	if (!IsCanceled())
       
   905 		{
       
   906 		if (aReason == KErrTimedOut)
       
   907 			{
       
   908 			retry = HandleTimeoutL(aResolve, aWaitResponse);
       
   909 			}
       
   910 		if (aReason == KErrSIPTransportFailure ||
       
   911 			aReason == KErrSIPICMPFailure)
       
   912 			{
       
   913 			retry = TryNextAddressL(aReason, aResolve, aWaitResponse);
       
   914 			}
       
   915 		}
       
   916 
       
   917     CleanupStack::Pop(); // cleanupItem
       
   918     if (!retry)
       
   919     	{
       
   920 		Stop(aReason);
       
   921 		}
       
   922 
       
   923 	__TEST_INVARIANT;
       
   924 	}
       
   925 
       
   926 // -----------------------------------------------------------------------------
       
   927 // CUserAgentClient::HandleTimeoutL
       
   928 // If SigComp used, delete the compartment and close TCP connection.
       
   929 // -----------------------------------------------------------------------------
       
   930 //
       
   931 TBool CUserAgentClient::HandleTimeoutL(const CUserAgentState& aResolve,
       
   932 									   const CUserAgentState& aWaitResponse)
       
   933     {
       
   934     __TEST_INVARIANT;
       
   935     __SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound);
       
   936 
       
   937     if (CSIPMessageUtility::HasSigCompParam(NextHopL()))
       
   938         {
       
   939         UpdateTransportProtocol(*iOutgoingMsg);
       
   940         if (iTransportProtocol == SIPStrings::StringF(SipStrConsts::ETCP) ||
       
   941             iTransportProtocol == SIPStrings::StringF(SipStrConsts::ETLS))
       
   942             {
       
   943             iTransmitter->TcpDisconnect(iRemoteAddr, TransportParams());
       
   944             }
       
   945 		CSIPURI* uri = NextHopL().SIPURI();
       
   946 		__SIP_ASSERT_LEAVE(uri, KErrNotFound);
       
   947 
       
   948         iSigComp.SendFailedL(iTransportParams.CompartmentId());
       
   949         iTransportParams.SetCompartmentId(0);
       
   950         uri->DeleteParam(SIPStrings::StringF(SipStrConsts::EComp));
       
   951         SIPRequestUtility::FillRouteAndRequestUriL(
       
   952         							static_cast<CSIPRequest&>(*iOutgoingMsg),
       
   953 									*iRouteSet,
       
   954 									*iRemoteTarget);
       
   955         UpdateAndSendRequestL(aWaitResponse);
       
   956 
       
   957         __TEST_INVARIANT;
       
   958         return ETrue;
       
   959         }
       
   960 
       
   961     return TryNextAddressL(KErrTimedOut, aResolve, aWaitResponse);
       
   962     }
       
   963 
       
   964 // -----------------------------------------------------------------------------
       
   965 // CUserAgentClient::IgnoreResponseRetransmissionsL
       
   966 // -----------------------------------------------------------------------------
       
   967 //
       
   968 void CUserAgentClient::IgnoreResponseRetransmissionsL()
       
   969     {
       
   970     __TEST_INVARIANT;
       
   971     __SIP_ASSERT_LEAVE(!iTransaction, KErrSIPInvalidTransactionState);
       
   972 
       
   973     RemoveFromStore();
       
   974     CleanupStack::PushL(this);
       
   975 
       
   976     CTransactionBase::TTransactionType taType =
       
   977         CTransactionBase::KClientTransaction;
       
   978     if (IsInviteUAC())
       
   979         {
       
   980         taType = CTransactionBase::KClientInviteTransaction;
       
   981         }
       
   982 
       
   983     // Set message NULL, to prevent responses being routed to UAC
       
   984     iTransactionStore.AddL(TransactionId(), this, NULL, NULL, taType);
       
   985     CleanupStack::Pop(this);
       
   986 
       
   987     __TEST_INVARIANT;
       
   988     }
       
   989 
       
   990 // -----------------------------------------------------------------------------
       
   991 // CUserAgentClient::CancelSIPSecRequest
       
   992 // No __TEST_INVARIANT as destructor may lead here.
       
   993 // -----------------------------------------------------------------------------
       
   994 //
       
   995 void CUserAgentClient::CancelSIPSecRequest()
       
   996     {
       
   997     iIgnoreSIPSecCallback = ETrue;
       
   998     iSIPSec.CancelPendingOperations(*this);
       
   999     iIgnoreSIPSecCallback = EFalse;
       
  1000     }
       
  1001 
       
  1002 // -----------------------------------------------------------------------------
       
  1003 // CUserAgentClient::TryNextAddressL
       
  1004 // -----------------------------------------------------------------------------
       
  1005 //
       
  1006 TBool CUserAgentClient::TryNextAddressL(TInt aError,
       
  1007 										const CUserAgentState& aResolve,
       
  1008 										const CUserAgentState& aWaitResponse,
       
  1009 										CSIPResponse* aResp)
       
  1010 	{
       
  1011 	__TEST_INVARIANT;
       
  1012 	__SIP_INT_LOG1( "CUserAgentClient TryNextAddressL Error",
       
  1013 					aError )
       
  1014 	__SIP_ASSERT_LEAVE((aError != KErrNone && !aResp) ||
       
  1015 					   (aError == KErrNone && aResp), KErrArgument);
       
  1016 
       
  1017 	if (SelectNextRemoteAddressL())
       
  1018 		{
       
  1019 		UpdateAndSendRequestL(aWaitResponse);
       
  1020 		delete aResp;
       
  1021 		return ETrue;
       
  1022 		}
       
  1023 
       
  1024 	if (iResolvingResults->ContinueResolvingCurrentUri())
       
  1025 		{
       
  1026 		__SIP_ASSERT_LEAVE(!iIncomingMsg, KErrAlreadyExists);
       
  1027 
       
  1028 		UpdateAndResolveL(ETrue, aResolve);
       
  1029 		iLastError = aError;
       
  1030 		iIncomingMsg = aResp;
       
  1031 		return ETrue;
       
  1032 		}
       
  1033 
       
  1034     if (iLastError != KErrNone)
       
  1035         {
       
  1036         aError = iLastError;
       
  1037         }
       
  1038     
       
  1039 	// If a stored response exists, next hop has responded.
       
  1040 	// Stateless proxy can result KErrTimedOut if its next hop doesn't respond,
       
  1041 	// even if the proxy is ok. So URIFailed isn't used for KErrTimedOut.	
       
  1042 	if ((aError == KErrSIPTransportFailure ||
       
  1043 		 aError == KErrSIPResolvingFailure ||
       
  1044 		 aError == KErrSIPICMPFailure) &&
       
  1045 		 !iIncomingMsg && !iResponseReceived)
       
  1046 		{
       
  1047 		iRegistrations.URIFailed(NextHopL());
       
  1048 		// Registrations may've used ClearTransactionOwner, stopping UA
       
  1049 		if (HasStopped())
       
  1050 			{
       
  1051 			return EFalse;
       
  1052 			}
       
  1053 		}
       
  1054 
       
  1055 	TBool retry = TryOutboundProxyL(aResolve);
       
  1056 	if (retry)
       
  1057 		{
       
  1058 		delete aResp;
       
  1059 		}
       
  1060 	__TEST_INVARIANT;
       
  1061 	return retry;
       
  1062 	}
       
  1063 
       
  1064 // -----------------------------------------------------------------------------
       
  1065 // CUserAgentClient::TryOutboundProxyL
       
  1066 // -----------------------------------------------------------------------------
       
  1067 //
       
  1068 TBool CUserAgentClient::TryOutboundProxyL(const CUserAgentState& aResolve)
       
  1069 	{
       
  1070 	__TEST_INVARIANT;
       
  1071 	__SIP_ASSERT_LEAVE(iRouteSet && iRemoteTarget && iRequestUri, KErrNotFound);
       
  1072 
       
  1073     const CSIPRouteHeader* proxy = iRegistrations.OutboundProxy(iRegisterId);
       
  1074 	if (iRouteSet->PreconfigRouteExists() &&
       
  1075         !iOutboundProxyHasBeenTried && proxy)
       
  1076 		{
       
  1077         const CURIContainer& proxyUri = proxy->SIPAddress().URI();
       
  1078 
       
  1079       	if ( !((NextHopL() == proxyUri) || proxyUri == *iRequestUri) )
       
  1080             {
       
  1081 			iRouteSet->AddToBeginningL(*proxy, EFalse /* append */);
       
  1082 			SIPRequestUtility::FillRouteAndRequestUriL(
       
  1083 							static_cast<CSIPRequest&>(*iOutgoingMsg),
       
  1084 							*iRouteSet,
       
  1085 							*iRemoteTarget);
       
  1086 			UpdateAndResolveL(ETrue, aResolve);
       
  1087 			iOutboundProxyHasBeenTried = ETrue;
       
  1088 
       
  1089 			__TEST_INVARIANT;
       
  1090 			return ETrue;
       
  1091             }
       
  1092 		}
       
  1093 	return EFalse;
       
  1094 	}
       
  1095 
       
  1096 // -----------------------------------------------------------------------------
       
  1097 // CUserAgentClient::DetachCurrentTransactionL
       
  1098 // Request must've been updated or there'd be 2 transactions with a same branch
       
  1099 // -----------------------------------------------------------------------------
       
  1100 //
       
  1101 void CUserAgentClient::DetachCurrentTransactionL()
       
  1102 	{
       
  1103 	__TEST_INVARIANT;
       
  1104 
       
  1105 	if (iTransaction)
       
  1106 		{
       
  1107 		if (iTransaction->HasTerminated())
       
  1108 			{
       
  1109             // Cancel transaction's send so new transaction can send
       
  1110 			iTransmitter->Cancel();
       
  1111             RequestDeletionOfTransactionL();
       
  1112 			RemoveFromStore();
       
  1113 			}
       
  1114 		else
       
  1115 			{			
       
  1116 			TTransactionId newId = iTransactionStore.NewTransactionId();
       
  1117             PrepareTxForNewRequestL(newId);
       
  1118 			User::LeaveIfError(iTransactionStore.UpdateTransactionId(
       
  1119 										            TransactionId(), newId));
       
  1120 			if (IsInviteUAC())
       
  1121 				{
       
  1122 				__SIP_INT_LOG2( "TU taID changed, old -> new",
       
  1123 				                TransactionId(), newId )
       
  1124                 }
       
  1125 			iTransaction->DetachFromUserAgent();
       
  1126 			iTransaction->ClearSendBuffer();
       
  1127 			iTransaction = NULL;
       
  1128 
       
  1129 			iTransactionStore.ClearUserAgent(newId);
       
  1130 			}
       
  1131 
       
  1132 		CleanupStack::PushL(this);
       
  1133         __SIP_ASSERT_LEAVE(!iTransaction, KErrAlreadyExists);
       
  1134         __SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound);
       
  1135 
       
  1136 		iTransactionStore.AddL(TransactionId(),
       
  1137 				   this,
       
  1138 				   iTransaction,
       
  1139 				   iOutgoingMsg,
       
  1140                    CSIPMessageUtility::TransactionType(*iOutgoingMsg, EFalse));
       
  1141 		CleanupStack::Pop(this);
       
  1142 		}
       
  1143 	__TEST_INVARIANT;
       
  1144 	}
       
  1145 
       
  1146 // -----------------------------------------------------------------------------
       
  1147 // CUserAgentClient::UpdateAndSendRequestL
       
  1148 // -----------------------------------------------------------------------------
       
  1149 //
       
  1150 void
       
  1151 CUserAgentClient::UpdateAndSendRequestL(const CUserAgentState& aWaitResponse)
       
  1152 	{
       
  1153 	__TEST_INVARIANT;
       
  1154     __SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound);
       
  1155 
       
  1156 	UpdateViaAndCSeqL();
       
  1157 	if (!CSIPMessageUtility::IsAck(*iOutgoingMsg))
       
  1158 		{
       
  1159 		DetachCurrentTransactionL();
       
  1160 		CreateTransactionL();
       
  1161 		}
       
  1162 
       
  1163 	UpdateInfoToStoreL(static_cast<CSIPRequest*>(iOutgoingMsg));
       
  1164 	SendRequestToNetworkL();
       
  1165 	ChangeState(aWaitResponse);
       
  1166 
       
  1167 	__TEST_INVARIANT;
       
  1168 	}
       
  1169 
       
  1170 // -----------------------------------------------------------------------------
       
  1171 // CUserAgentClient::UpdateAndResolveL
       
  1172 // -----------------------------------------------------------------------------
       
  1173 //
       
  1174 void CUserAgentClient::UpdateAndResolveL(TBool aCheckSigComp,
       
  1175 										 const CUserAgentState& aResolve)
       
  1176 	{
       
  1177 	__TEST_INVARIANT;
       
  1178 	__SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound);
       
  1179 
       
  1180 	UpdateViaAndCSeqL();	
       
  1181 	DetachCurrentTransactionL();
       
  1182 	UpdateInfoToStoreL(static_cast<CSIPRequest*>(iOutgoingMsg));
       
  1183 	ResolveNextHopL(aCheckSigComp);
       
  1184 	ChangeState(aResolve);
       
  1185 
       
  1186 	__TEST_INVARIANT;
       
  1187 	}
       
  1188 
       
  1189 // -----------------------------------------------------------------------------
       
  1190 // CUserAgentClient::StopWithLastError
       
  1191 // -----------------------------------------------------------------------------
       
  1192 //
       
  1193 void CUserAgentClient::StopWithLastError()
       
  1194 	{
       
  1195 	__TEST_INVARIANT;
       
  1196 
       
  1197 	if (iIncomingMsg)
       
  1198 		{
       
  1199 		CSIPMessage* msg = iIncomingMsg;
       
  1200 		iIncomingMsg = NULL;
       
  1201 		TRAPD(err, PassMsgToTransactionOwnerL(msg));
       
  1202 		if (err != KErrNone)
       
  1203 			{
       
  1204 			delete msg;
       
  1205 			}
       
  1206 		}
       
  1207 	else
       
  1208 		{
       
  1209 		if (iLastError == KErrNone)
       
  1210 			{
       
  1211 			// Resolving URI for the first time fails
       
  1212 			iLastError = KErrSIPResolvingFailure;
       
  1213 			}
       
  1214 		}
       
  1215 	Stop(iLastError);
       
  1216 	}
       
  1217 
       
  1218 // -----------------------------------------------------------------------------
       
  1219 // CUserAgentClient::DetachOutgoingMsg
       
  1220 // If transaction can't proceed w/o the message, terminate it silently.
       
  1221 // -----------------------------------------------------------------------------
       
  1222 //
       
  1223 void CUserAgentClient::DetachOutgoingMsg()
       
  1224 	{
       
  1225 	__TEST_INVARIANT;
       
  1226 
       
  1227 	iOutgoingMsg = NULL;
       
  1228 	iTransmitter->Cancel();
       
  1229     CancelSIPSecRequest();
       
  1230 
       
  1231 	if (iTransaction && !iTransaction->ClearSendBuffer())
       
  1232 		{
       
  1233 		iTransaction->DetachFromUserAgent();
       
  1234 		iTransaction->Terminated();
       
  1235 		}
       
  1236 	else
       
  1237 		{
       
  1238 		if (State().CanContinueWithoutOutgoingMsg(iFinalRespPassed))
       
  1239 			{
       
  1240 			return;
       
  1241 			}
       
  1242 		}
       
  1243 
       
  1244 	Stop(KErrNone);
       
  1245 	__TEST_INVARIANT;
       
  1246 	}
       
  1247 
       
  1248 // -----------------------------------------------------------------------------
       
  1249 // CUserAgentClient::UseSIPSec
       
  1250 // -----------------------------------------------------------------------------
       
  1251 //
       
  1252 TBool CUserAgentClient::UseSIPSec() const
       
  1253 	{
       
  1254 	__TEST_INVARIANT;
       
  1255 	return (iObserver && 
       
  1256 	        iObserver->SIPSecUser() && 
       
  1257 	        !iObserver->SIPSecUser()->ByPassSIPSec());
       
  1258 	}
       
  1259 
       
  1260 // -----------------------------------------------------------------------------
       
  1261 // CUserAgentClient::NextHopIP
       
  1262 // -----------------------------------------------------------------------------
       
  1263 //
       
  1264 const TInetAddr& CUserAgentClient::NextHopIP() const
       
  1265     {
       
  1266     return iRemoteAddr;
       
  1267     }
       
  1268 
       
  1269 // -----------------------------------------------------------------------------
       
  1270 // CUserAgentClient::__DbgTestInvariant
       
  1271 // -----------------------------------------------------------------------------
       
  1272 //
       
  1273 
       
  1274 void CUserAgentClient::__DbgTestInvariant() const
       
  1275 	{
       
  1276 	if ((iOutgoingMsg && !iOutgoingMsg->IsRequest()) ||
       
  1277 		(iIncomingMsg && iIncomingMsg->IsRequest()) ||
       
  1278         (iSIPSecCounter > SIPRequestUtility::EMaxForwardsValue + 1) ||        
       
  1279         !iResolvingResults)
       
  1280 		{
       
  1281 		User::Invariant();
       
  1282 		}
       
  1283 	}