realtimenetprots/sipfw/SIP/Refreshes/src/CSipRefreshBase.cpp
changeset 0 307788aac0a8
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 // Name          : CSipRefreshBase.cpp
       
    15 // Part of       : SIPRefreshes
       
    16 // Version       : SIP/4.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "SipStackServerDefs.h"
       
    22 #include "MTransactionUser.h"
       
    23 #include "MRefreshOwner.h"
       
    24 #include "CSipRefreshMgr.h"
       
    25 #include "siprequest.h"
       
    26 #include "sipresponse.h"
       
    27 #include "sipcontactheader.h"
       
    28 #include "sipaddress.h"
       
    29 #include "sipcseqheader.h"
       
    30 #include "sipexpiresheader.h"
       
    31 #include "siptoheader.h"
       
    32 #include "sipfromheader.h"
       
    33 #include "SipLogs.h"
       
    34 #include "sipcallidheader.h"
       
    35 #include "uricontainer.h"
       
    36 #include "siprouteheader.h"
       
    37 #include "siprecordrouteheader.h"
       
    38 #include "sipheaderbase.h"
       
    39 #include "siperr.h"
       
    40 #include "SipAssert.h"
       
    41 #include "sipstrings.h"
       
    42 #include "sipstrconsts.h"
       
    43 #include "TSIPTransportParams.h"
       
    44 #include "CSipRefreshBase.h"
       
    45 #include "sipsec.h"
       
    46 
       
    47 
       
    48 const TInt KOneSecInMilliSecs = 1000; // one second is 1000 millisecond
       
    49 
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CSipRefreshBase::CSipRefreshBase
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 CSipRefreshBase::CSipRefreshBase (MTransactionUser& aTU,
       
    56                                   MTimerManager& aTimerMgr,
       
    57                                   CSIPSec& aSIPSec,
       
    58 				                  CSipRefreshMgr& aRefreshMgr,
       
    59 				                  TRegistrationId aRegistrationId,
       
    60                                   MRefreshOwner* aOwner,
       
    61                                   MSIPSecUser& aSIPSecUser)
       
    62  : iRefreshMgr              (aRefreshMgr),
       
    63    iRefreshId               (aRefreshMgr.NextRefreshId()),
       
    64    iCurrentTransactionId    (KEmptyTransactionId),
       
    65    iFirstRequest            (ETrue),
       
    66    iSIPSecUser              (aSIPSecUser), 
       
    67    iOwner                   (aOwner),
       
    68    iTU                      (aTU),
       
    69    iTimerMgr                (aTimerMgr),
       
    70    iSIPSec                  (aSIPSec),
       
    71    iTransactionOwnerCleared (EFalse),
       
    72    iIntervalUpdated         (EFalse),
       
    73    iRegistrationId          (aRegistrationId),
       
    74    iOwnRequest              (ETrue),
       
    75    iRemoveRouteHeaders      (EFalse)
       
    76 	{
       
    77 	}
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 // CSipRefreshBase::BaseConstructL
       
    81 // -----------------------------------------------------------------------------
       
    82 //
       
    83 void CSipRefreshBase::BaseConstructL(CURIContainer& aRemoteTarget,
       
    84                                      CSIPRequest& aRequest)
       
    85 	{
       
    86 	iRemoteTarget = CURIContainer::NewL(aRemoteTarget);
       
    87 	TInt expiresInSeconds = ExpirationTimeFromRequestL(aRequest);
       
    88 	iIntervalInMilliSeconds = CalculateInterval(expiresInSeconds);
       
    89 	}
       
    90 
       
    91 // -----------------------------------------------------------------------------
       
    92 // CSipRefreshBase::~CSipRefreshBase
       
    93 // -----------------------------------------------------------------------------
       
    94 //
       
    95 CSipRefreshBase::~CSipRefreshBase ()
       
    96 	{
       
    97 	if (iTimerMgr.IsRunning(iTimerId)) 
       
    98 		{
       
    99 		iTimerMgr.Stop(iTimerId);
       
   100 		}
       
   101 
       
   102 	if (!iTransactionOwnerCleared)
       
   103 		{
       
   104 		iTU.ClearTransactionOwner (this);
       
   105 		}
       
   106 
       
   107 	if (iOwnRequest)
       
   108 		{
       
   109 		delete iRequest;
       
   110 		}
       
   111 
       
   112 	delete iRemoteTarget;
       
   113 	delete iUpdatedHeader;
       
   114     iSIPSec.ClearCache(this);
       
   115 	iUpdatedRouteHeaders.ResetAndDestroy();
       
   116 	}
       
   117 
       
   118 // -----------------------------------------------------------------------------
       
   119 // CSipRefreshBase::ClearTransactionOwner
       
   120 // Needs to be called before the refresh is put to DeleteMgr, 
       
   121 // so that TU will not call this refresh anymore.
       
   122 // -----------------------------------------------------------------------------
       
   123 //
       
   124 void CSipRefreshBase::ClearTransactionOwner()
       
   125 	{
       
   126 	iTU.ClearTransactionOwner (this);
       
   127 	iTransactionOwnerCleared = ETrue;
       
   128 	}
       
   129 
       
   130 // -----------------------------------------------------------------------------
       
   131 // CSipRefreshBase::Owner
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 MRefreshOwner* CSipRefreshBase::Owner()
       
   135 	{
       
   136 	return iOwner;
       
   137 	}
       
   138     
       
   139 // -----------------------------------------------------------------------------
       
   140 // CSipRefreshBase::Id
       
   141 // -----------------------------------------------------------------------------
       
   142 //
       
   143 const TRefreshId& CSipRefreshBase::Id() const
       
   144 	{
       
   145 	return iRefreshId;
       
   146 	}
       
   147 
       
   148 // -----------------------------------------------------------------------------
       
   149 // CSipRefreshBase::CurrentTransactionId
       
   150 // -----------------------------------------------------------------------------
       
   151 //	
       
   152 TTransactionId CSipRefreshBase::CurrentTransactionId() const
       
   153     {
       
   154     return iCurrentTransactionId;
       
   155     }	
       
   156 	
       
   157 // -----------------------------------------------------------------------------
       
   158 // CSipRefreshBase::Request
       
   159 // -----------------------------------------------------------------------------
       
   160 //
       
   161 CSIPRequest* CSipRefreshBase::Request()
       
   162 	{
       
   163 	return iRequest;
       
   164 	}
       
   165 	
       
   166 // -----------------------------------------------------------------------------
       
   167 // CSipRefreshBase::Request
       
   168 // -----------------------------------------------------------------------------
       
   169 //	
       
   170 void CSipRefreshBase::SetIntervalL(TInt aInterval)
       
   171     {
       
   172     __ASSERT_ALWAYS(aInterval > 0, User::Leave(KErrArgument));
       
   173     
       
   174     TInt tmp = CalculateInterval(aInterval);    
       
   175 	if (iTimerMgr.IsRunning(iTimerId)) 
       
   176 		{
       
   177 		iTimerMgr.Stop(iTimerId);
       
   178         StartTimerL(tmp);		
       
   179 		}
       
   180     iIntervalInMilliSeconds = tmp;
       
   181 	iIntervalUpdated = ETrue;
       
   182     }
       
   183 	
       
   184 // -----------------------------------------------------------------------------
       
   185 // CSipRefreshBase::Request
       
   186 // -----------------------------------------------------------------------------
       
   187 //	
       
   188 TInt CSipRefreshBase::Interval() const
       
   189     {
       
   190     if (iIntervalInMilliSeconds < KOneSecInMilliSecs)
       
   191         {
       
   192         return 1;
       
   193         }
       
   194     return iIntervalInMilliSeconds/KOneSecInMilliSecs;
       
   195     }
       
   196 
       
   197 // -----------------------------------------------------------------------------
       
   198 // CSipRefreshBase::ReceiveL
       
   199 // -----------------------------------------------------------------------------
       
   200 //
       
   201 void CSipRefreshBase::ReceiveL (TUint32        /*aIapId*/,
       
   202 								TTransactionId /*aTransactionId*/, 
       
   203 								CSIPRequest*   /*aRequest*/)
       
   204 	{
       
   205 	 // Must not ever receive SIP requests from TU.
       
   206 	__SIP_ASSERT_LEAVE (EFalse, KErrArgument);
       
   207 	}
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 // CSipRefreshBase::ReceiveL
       
   211 // -----------------------------------------------------------------------------
       
   212 //
       
   213 void CSipRefreshBase::ReceiveL (TTransactionId aTransactionId, 
       
   214 								CSIPResponse*  aResponse)
       
   215 	{
       
   216 	__SIP_ASSERT_LEAVE (iRequest, KErrArgument);
       
   217 
       
   218 	__SIP_ASSERT_LEAVE (aResponse, KErrArgument);
       
   219 
       
   220     __SIP_ASSERT_LEAVE (aTransactionId == iCurrentTransactionId, KErrArgument);
       
   221 
       
   222 	__SIP_MESSAGE_LOG ("Refreshes", *aResponse)
       
   223   
       
   224 	if (aResponse->Type() == CSIPResponse::E1XX)
       
   225 		{
       
   226 		ReceivedProvisonalResponseL (aResponse);
       
   227 		}
       
   228 	else if (aResponse->Type() == CSIPResponse::E2XX)
       
   229 		{
       
   230 		Received200ClassResponseL (aResponse);
       
   231 		}		
       
   232 	else // error response
       
   233 		{
       
   234 		ReceivedErrorResponseL (aResponse);	
       
   235 		}
       
   236 	}
       
   237 
       
   238 // -----------------------------------------------------------------------------
       
   239 // CSipRefreshBase::TransactionEnded
       
   240 // -----------------------------------------------------------------------------
       
   241 //
       
   242 TInt CSipRefreshBase::TransactionEnded(TUint32 /*aIapId*/,
       
   243                                        TTransactionId aTransactionId, 
       
   244 									   TInt aReason)
       
   245 	{
       
   246 	__SIP_ASSERT_RETURN_VALUE (aTransactionId == iCurrentTransactionId, 
       
   247 		                       KErrArgument);
       
   248 
       
   249 	TInt err = KErrNone;
       
   250 	if (aReason != KErrNone) 
       
   251 		{
       
   252 		RefreshErrorOccured(aTransactionId,aReason);
       
   253 		err = iRefreshMgr.RemoveRefreshBy (this);
       
   254 		}
       
   255 
       
   256 	return err;
       
   257 	}
       
   258 
       
   259 // -----------------------------------------------------------------------------
       
   260 // CSipRefreshBase::NextCSeq
       
   261 // -----------------------------------------------------------------------------
       
   262 //
       
   263 TInt CSipRefreshBase::NextCSeq (TUint& aCSeq)
       
   264 	{
       
   265 	return iOwner->NextRefreshCSeq (aCSeq);
       
   266 	}
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 // CSipRefreshBase::SIPSecUser
       
   270 // -----------------------------------------------------------------------------
       
   271 //	
       
   272 const MSIPSecUser* CSipRefreshBase::SIPSecUser() const
       
   273     {
       
   274     return this;
       
   275     }
       
   276 
       
   277 // -----------------------------------------------------------------------------
       
   278 // CSipRefreshBase::TimerExpiredL
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 void CSipRefreshBase::TimerExpiredL (TTimerId aTimerId, TAny* /*aTimerParam*/)
       
   282 	{
       
   283 	__ASSERT_ALWAYS (aTimerId == iTimerId, User::Leave (KErrNotFound));
       
   284 
       
   285 	if(NULL == iRequest)
       
   286 	{
       
   287 		StopTimer();
       
   288 		return;
       
   289 	}
       
   290 
       
   291 	UpdateCSeqValueL(*iRequest); 
       
   292 
       
   293 	TRAPD (err, SendL(iCurrentTransactionId, iRequest));
       
   294 
       
   295 	if (err != KErrNone)
       
   296 		{
       
   297         // Convert network states to a SIP stack error
       
   298         if (err == CSIPConnection::ESuspended ||
       
   299             err == CSIPConnection::EInactive ||
       
   300             err == CSIPConnection::EUnavailable)
       
   301             {
       
   302             err = KErrSIPTransportFailure;
       
   303             }
       
   304 		User::LeaveIfError(RefreshErrorOccured(iCurrentTransactionId, err));
       
   305 		User::LeaveIfError(iRefreshMgr.RemoveRefreshBy(this));
       
   306 		}
       
   307 	}
       
   308 	
       
   309 // -----------------------------------------------------------------------------
       
   310 // CSipRefreshBase::PassOnlyRealmsToUser
       
   311 // From MSIPSecUser
       
   312 // -----------------------------------------------------------------------------
       
   313 //
       
   314 TBool CSipRefreshBase::PassOnlyRealmsToUser() const
       
   315     {
       
   316     return iSIPSecUser.PassOnlyRealmsToUser();
       
   317     }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CSipRefreshBase::RequestCredentialsL
       
   321 // From MSIPSecUser
       
   322 // -----------------------------------------------------------------------------
       
   323 //
       
   324 void CSipRefreshBase::RequestCredentialsL(const TDesC8& aRealm)
       
   325     {
       
   326     iSIPSecUser.RequestCredentialsL(aRealm);
       
   327     }
       
   328 
       
   329 // -----------------------------------------------------------------------------
       
   330 // CSipRefreshBase::RequestCredentialsL
       
   331 // From MSIPSecUser
       
   332 // -----------------------------------------------------------------------------
       
   333 //
       
   334 void CSipRefreshBase::RequestCredentialsL(
       
   335     CSIPResponse& aResponse,
       
   336     TTransactionId aTransactionId,
       
   337     TRefreshId /*aRefreshId*/)
       
   338     {
       
   339     iSIPSecUser.RequestCredentialsL(aResponse,aTransactionId,iRefreshId);
       
   340     }	
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // CSipRefreshBase::TrustedUser
       
   344 // From MSIPSecUser
       
   345 // -----------------------------------------------------------------------------
       
   346 //	
       
   347 const MSIPSecUser* CSipRefreshBase::TrustedUser(TRegistrationId aRegistrationId)
       
   348     {
       
   349     return iSIPSecUser.TrustedUser(aRegistrationId);
       
   350     }
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 // CSipRefreshBase::ByPassSIPSec
       
   354 // From MSIPSecUser
       
   355 // -----------------------------------------------------------------------------
       
   356 //
       
   357 TBool CSipRefreshBase::ByPassSIPSec() const
       
   358     {
       
   359     return iSIPSecUser.ByPassSIPSec();
       
   360     }
       
   361 	
       
   362 // -----------------------------------------------------------------------------
       
   363 // CSipRefreshBase::SetRequest
       
   364 // -----------------------------------------------------------------------------
       
   365 //
       
   366 void CSipRefreshBase::SetRequest (CSIPRequest* aRequest,
       
   367 								  TBool aDeleteRequest)
       
   368 	{
       
   369 	if (iOwnRequest)
       
   370 		{
       
   371 		delete iRequest;
       
   372 		}
       
   373 	iRequest = aRequest;
       
   374 	iOwnRequest = aDeleteRequest;
       
   375 	}
       
   376 
       
   377 // -----------------------------------------------------------------------------
       
   378 // CSipRefreshBase::SendL
       
   379 // -----------------------------------------------------------------------------
       
   380 //
       
   381 void CSipRefreshBase::SendL (TTransactionId& aTransactionId, 
       
   382 							 CSIPRequest* aRequest)
       
   383 	{
       
   384 	if (iUpdatedHeader)
       
   385 		{
       
   386 		UpdateHeaderForL(*aRequest);
       
   387 		}
       
   388 	if (iRemoveRouteHeaders)
       
   389 		{
       
   390 		RemoveRouteHeadersFor(*aRequest);
       
   391 		}
       
   392 	if (iUpdatedRouteHeaders.Count() > 0)
       
   393 		{
       
   394 		UpdateRouteHeadersForL(*aRequest);
       
   395 		}
       
   396 
       
   397 	iTU.SendL (aTransactionId, iRegistrationId, aRequest,
       
   398 		       this, *iRemoteTarget, 
       
   399 		       iOwner->TransportParams(iRegistrationId), EFalse);
       
   400 		       
       
   401 	iIntervalUpdated = EFalse;      
       
   402 	iCurrentTransactionId = aTransactionId;
       
   403 	}
       
   404 
       
   405 // -----------------------------------------------------------------------------
       
   406 // CSipRefreshBase::SendAndGetHeadersL
       
   407 // -----------------------------------------------------------------------------
       
   408 //
       
   409 MTransactionHeaders* CSipRefreshBase::SendAndGetHeadersL (
       
   410 	TTransactionId& aTransactionId, 
       
   411 	CSIPRequest*    aRequest)
       
   412 	{
       
   413 	MTransactionHeaders* headers = iTU.SendAndGetHeadersL(
       
   414 		aTransactionId, iRegistrationId, aRequest, this,
       
   415 		*iRemoteTarget, iOwner->TransportParams(iRegistrationId), EFalse);
       
   416 	iCurrentTransactionId = aTransactionId;
       
   417 	return headers;
       
   418 	}
       
   419 	
       
   420 // -----------------------------------------------------------------------------
       
   421 // CSipRefreshBase::UpdateRemoteTargetL
       
   422 // -----------------------------------------------------------------------------
       
   423 //
       
   424 void CSipRefreshBase::UpdateRemoteTargetL(CURIContainer& aRemoteTarget)
       
   425 	{
       
   426 	CURIContainer* tempRemoteTarget = CURIContainer::NewL(aRemoteTarget);	
       
   427 	delete iRemoteTarget;
       
   428 	iRemoteTarget = tempRemoteTarget;
       
   429 	}
       
   430 
       
   431 // -----------------------------------------------------------------------------
       
   432 // CSipRefreshBase::SetUpdatedHeader
       
   433 // -----------------------------------------------------------------------------
       
   434 //
       
   435 void CSipRefreshBase::SetUpdatedHeader(CSIPHeaderBase* aHeader)
       
   436 	{
       
   437 	delete iUpdatedHeader;
       
   438 	iUpdatedHeader = aHeader;
       
   439 	}
       
   440 
       
   441 // -----------------------------------------------------------------------------
       
   442 // CSipRefreshBase::SetUpdatedRouteHeadersL
       
   443 // -----------------------------------------------------------------------------
       
   444 //
       
   445 void CSipRefreshBase::SetUpdatedRouteHeadersL (
       
   446 	const RPointerArray<CSIPRouteHeader>& aHeaderArray)
       
   447 	{
       
   448 	RPointerArray<CSIPHeaderBase> tempHeaderArray;
       
   449 	CSIPHeaderBase::PushLC(&tempHeaderArray);
       
   450 
       
   451 	for (TInt i = 0; i < aHeaderArray.Count(); i++)
       
   452 		{
       
   453 		CSIPHeaderBase* tempHeader = (aHeaderArray[i])->CloneL();
       
   454 		CleanupStack::PushL(tempHeader);
       
   455 		User::LeaveIfError(tempHeaderArray.Append(tempHeader));
       
   456 		CleanupStack::Pop(tempHeader);
       
   457 		}
       
   458 
       
   459 	CleanupStack::Pop(); // tempHeaderArray
       
   460     iUpdatedRouteHeaders.ResetAndDestroy();
       
   461 	iUpdatedRouteHeaders = tempHeaderArray;
       
   462 	}
       
   463 
       
   464 // -----------------------------------------------------------------------------
       
   465 // CSipRefreshBase::RemoveRouteHeaders
       
   466 // -----------------------------------------------------------------------------
       
   467 //
       
   468 void CSipRefreshBase::RemoveRouteHeaders ()
       
   469 	{
       
   470 	// reset the route headers array
       
   471 	iUpdatedRouteHeaders.ResetAndDestroy();
       
   472 	iRemoveRouteHeaders = ETrue;
       
   473 	}
       
   474 
       
   475 // -----------------------------------------------------------------------------
       
   476 // CSipRefreshBase::SendUpdateRequestL
       
   477 // -----------------------------------------------------------------------------
       
   478 //
       
   479 void CSipRefreshBase::SendUpdateRequestL (TTransactionId& aTransactionId,
       
   480 		                                  CSIPRequest*    aRequest)
       
   481 	{
       
   482     CheckUpdateRequestMethodL(*aRequest);
       
   483     CheckUpdateRequestHeadersL(*aRequest);	
       
   484 	
       
   485 	delete iUpdatedHeader; 
       
   486 	iUpdatedHeader = NULL;
       
   487 
       
   488 	iUpdatedRouteHeaders.ResetAndDestroy();
       
   489 
       
   490 	if (iTimerMgr.IsRunning(iTimerId)) 
       
   491 		{
       
   492 		iTimerMgr.Stop(iTimerId);
       
   493 		}
       
   494 
       
   495 	iTU.ClearTransactionOwner(iCurrentTransactionId);
       
   496 
       
   497 	SendL(aTransactionId,aRequest);
       
   498 
       
   499 	iFirstRequest = ETrue;
       
   500 	}
       
   501 
       
   502 // -----------------------------------------------------------------------------
       
   503 // CSipRefreshBase::UpdateRequestL 
       
   504 // -----------------------------------------------------------------------------
       
   505 //
       
   506 void 
       
   507 CSipRefreshBase::UpdateRequestL (TTransactionId& aTransactionId,
       
   508 		                         CSIPRequest* aRequest)
       
   509 	{
       
   510 	CheckUpdateRequestExpiresValueL (*aRequest);
       
   511 	SendUpdateRequestL(aTransactionId, aRequest);
       
   512 	}
       
   513 
       
   514 // -----------------------------------------------------------------------------
       
   515 // CSipRefreshBase::TerminateRequestL 
       
   516 // -----------------------------------------------------------------------------
       
   517 //
       
   518 void 
       
   519 CSipRefreshBase::TerminateRequestL (TTransactionId& aTransactionId,
       
   520 								    CSIPRequest* aRequest)
       
   521 	{
       
   522 	CheckTerminateRequestExpiresValueL(*aRequest);
       
   523 	SendUpdateRequestL(aTransactionId, aRequest);
       
   524 	}
       
   525 
       
   526 // -----------------------------------------------------------------------------
       
   527 // CSipRefreshBase::IAPId
       
   528 // -----------------------------------------------------------------------------
       
   529 //
       
   530 TUint CSipRefreshBase::IAPId () const
       
   531 	{
       
   532 	return iOwner->TransportParams(iRegistrationId).IapId();
       
   533 	}
       
   534 
       
   535 // -----------------------------------------------------------------------------
       
   536 // CSipRefreshBase::ResetRegistrationId
       
   537 // -----------------------------------------------------------------------------
       
   538 //
       
   539 void CSipRefreshBase::ResetRegistrationId()
       
   540 	{
       
   541 	iRegistrationId = KEmptyRegistrationId;
       
   542 	}
       
   543 
       
   544 // -----------------------------------------------------------------------------
       
   545 // CSipRefreshBase::Received200ClassResponseL
       
   546 // -----------------------------------------------------------------------------
       
   547 //
       
   548 void CSipRefreshBase::Received200ClassResponseL (CSIPResponse* aResponse)
       
   549 	{
       
   550 	TInt expirationTimeInRequest = ExpirationTimeFromRequestL(*iRequest);
       
   551 	// if is terminate, expires in request is 0
       
   552 	if (expirationTimeInRequest == 0)
       
   553 		{	
       
   554 		User::LeaveIfError(iRefreshMgr.RemoveRefreshBy (this));
       
   555 		RefreshReceivedL(iCurrentTransactionId, aResponse);
       
   556 		iTU.ClearTransactionOwner(this);
       
   557 		return;
       
   558 		}
       
   559 		
       
   560     TInt expirationTimeInResponse = ExpirationTimeFromResponse(*aResponse);
       
   561 	
       
   562 	// response expire value lowered to 0
       
   563 	if (expirationTimeInResponse == 0)
       
   564 		{
       
   565 		User::LeaveIfError(RefreshErrorOccured(iCurrentTransactionId, 
       
   566 			               KErrSIPMalformedMessage));
       
   567 		User::LeaveIfError(iRefreshMgr.RemoveRefreshBy (this));
       
   568 		delete aResponse;
       
   569 		return;
       
   570 		}
       
   571 
       
   572 	// no expires time from response
       
   573 	if (expirationTimeInResponse == KErrNotFound)
       
   574 		{
       
   575 		// copy the expires value from request to response
       
   576 		SetExpirationTimeToResponseL(*aResponse, expirationTimeInRequest);
       
   577 		expirationTimeInResponse = ExpirationTimeFromResponse(*aResponse);
       
   578 		}
       
   579 
       
   580 	if (!iIntervalUpdated)
       
   581 		{
       
   582 		if(expirationTimeInResponse <= expirationTimeInRequest) 
       
   583 			iIntervalInMilliSeconds = CalculateInterval(expirationTimeInResponse);
       
   584 		else
       
   585 			iIntervalInMilliSeconds = CalculateInterval(expirationTimeInRequest);	
       
   586 		}
       
   587 			
       
   588 	StartTimerL(iIntervalInMilliSeconds);
       
   589 
       
   590 	TRAPD(err, Forward2xxResponseToCallerL(aResponse));
       
   591 
       
   592 	if (err)
       
   593 		{
       
   594 		iTimerMgr.Stop(iTimerId);
       
   595 		User::Leave(err);
       
   596 		}
       
   597 
       
   598 	iTU.ClearTransactionOwner(iCurrentTransactionId);
       
   599 
       
   600 	iFirstRequest = EFalse;
       
   601 	}
       
   602 
       
   603 // -----------------------------------------------------------------------------
       
   604 // CSipRefreshBase::ReceivedErrorResponseL
       
   605 // -----------------------------------------------------------------------------
       
   606 //
       
   607 void CSipRefreshBase::ReceivedErrorResponseL (CSIPResponse* aResponse)
       
   608 	{
       
   609 	User::LeaveIfError(iRefreshMgr.RemoveRefreshBy (this));
       
   610 	RefreshReceivedL(iCurrentTransactionId, aResponse);
       
   611 	}
       
   612 
       
   613 // -----------------------------------------------------------------------------
       
   614 // CSipRefreshBase::ReceivedProvisonalResponseL
       
   615 // -----------------------------------------------------------------------------
       
   616 //
       
   617 void CSipRefreshBase::ReceivedProvisonalResponseL (CSIPResponse* aResponse)
       
   618 	{
       
   619 	// if is first request, send response.
       
   620 	if (iFirstRequest)
       
   621 		{
       
   622 		RefreshReceivedL(iCurrentTransactionId,aResponse);
       
   623 		}
       
   624 	else
       
   625 		{
       
   626 		delete aResponse;
       
   627 		}
       
   628 	}
       
   629 
       
   630 // -----------------------------------------------------------------------------
       
   631 // CSipRefreshBase::UpdateCSeqValueL
       
   632 // -----------------------------------------------------------------------------
       
   633 //
       
   634 void CSipRefreshBase::UpdateCSeqValueL(CSIPRequest& aRequest)
       
   635 	{
       
   636 	CSIPCSeqHeader* cseqHeader = aRequest.CSeq();
       
   637 
       
   638 	__SIP_ASSERT_LEAVE (cseqHeader, KErrArgument);
       
   639 
       
   640 	TUint cseq = cseqHeader->Seq();
       
   641 
       
   642 	// ask Cseq value from refresh owner, leaves if error
       
   643 	User::LeaveIfError(iOwner->NextRefreshCSeq(cseq));
       
   644 
       
   645 	cseqHeader->SetSeq(cseq);
       
   646 	}
       
   647 	
       
   648 // -----------------------------------------------------------------------------
       
   649 // CSipRefreshBase::UpdateHeaderForL
       
   650 // -----------------------------------------------------------------------------
       
   651 //
       
   652 void CSipRefreshBase::UpdateHeaderForL(CSIPRequest& aRequest)
       
   653 	{
       
   654 	if (aRequest.HasHeader(iUpdatedHeader->Name()))
       
   655 		{
       
   656 		CSIPHeaderBase* oldHeader = aRequest.Header(iUpdatedHeader->Name(), 0);
       
   657 		// ownership of iUpdatedHeader is passed.
       
   658 		// the oldHeader is deleted.
       
   659 		aRequest.ReplaceHeaderL(oldHeader, iUpdatedHeader);
       
   660 		oldHeader = NULL; 
       
   661 		}
       
   662 	else
       
   663 		{
       
   664 		// the ownership of iUpdatedHeader header is transferred.
       
   665 		aRequest.AddHeaderL(iUpdatedHeader);
       
   666 		}
       
   667 	iUpdatedHeader = NULL; // detach the iUpdatedHeader.
       
   668 	}
       
   669 
       
   670 // -----------------------------------------------------------------------------
       
   671 // CSipRefreshBase::UpdateRouteHeadersForL
       
   672 // -----------------------------------------------------------------------------
       
   673 //
       
   674 void CSipRefreshBase::UpdateRouteHeadersForL(CSIPRequest& aRequest)
       
   675 	{
       
   676 	if (aRequest.HasHeader(SIPStrings::StringF(SipStrConsts::ERouteHeader)))
       
   677 		{
       
   678 		aRequest.ReplaceHeadersL(iUpdatedRouteHeaders);
       
   679 		}
       
   680 	else
       
   681 		{			 
       
   682 		for (TInt i = 0; i < iUpdatedRouteHeaders.Count(); i++)
       
   683 			{
       
   684 			CSIPHeaderBase* header = (iUpdatedRouteHeaders[i])->CloneL();
       
   685 			CleanupStack::PushL(header);
       
   686 			aRequest.AddHeaderL(header);
       
   687 			CleanupStack::Pop(header);
       
   688 			}
       
   689 		}
       
   690 	// clear the route headers array after update those to aRequest
       
   691 	iUpdatedRouteHeaders.ResetAndDestroy();
       
   692 	}
       
   693 
       
   694 // -----------------------------------------------------------------------------
       
   695 // CSipRefreshBase::RemoveRouteHeadersFor
       
   696 // -----------------------------------------------------------------------------
       
   697 //
       
   698 void CSipRefreshBase::RemoveRouteHeadersFor (CSIPRequest& aRequest)
       
   699 	{	
       
   700 	if (aRequest.HasHeader(SIPStrings::StringF(SipStrConsts::ERouteHeader)))
       
   701 		{
       
   702 		aRequest.DeleteHeaders(SIPStrings::StringF(SipStrConsts::ERouteHeader));
       
   703 		}
       
   704 
       
   705 	// change the flag to EFalse after remove route headers from aRequest
       
   706 	iRemoveRouteHeaders = EFalse; 
       
   707 	}
       
   708 
       
   709 // -----------------------------------------------------------------------------
       
   710 // CSipRefreshBase::SetToFromOriginalRequestL
       
   711 // -----------------------------------------------------------------------------
       
   712 //
       
   713 void CSipRefreshBase::SetToFromOriginalRequestL(CSIPRequest& aRequest)
       
   714 	{
       
   715 	CSIPToHeader* originalTo = 	iRequest->To();
       
   716     __SIP_ASSERT_LEAVE (originalTo, KErrGeneral);
       
   717 	CSIPToHeader* newTo = CSIPToHeader::NewLC(*originalTo);
       
   718 	aRequest.AddHeaderL(newTo);
       
   719 	CleanupStack::Pop(newTo);
       
   720 	}
       
   721 
       
   722 // -----------------------------------------------------------------------------
       
   723 // CSipRefreshBase::SetFromFromOriginalRequestL
       
   724 // -----------------------------------------------------------------------------
       
   725 //
       
   726 void CSipRefreshBase::SetFromFromOriginalRequestL(CSIPRequest& aRequest)
       
   727 	{
       
   728 	CSIPFromHeader* originalFrom = iRequest->From();
       
   729     __SIP_ASSERT_LEAVE (originalFrom, KErrGeneral);	
       
   730 	CSIPFromHeader* newFrom = CSIPFromHeader::NewLC(*originalFrom);
       
   731 	aRequest.AddHeaderL(newFrom);
       
   732 	CleanupStack::Pop(newFrom);
       
   733 	}
       
   734 	
       
   735 // -----------------------------------------------------------------------------
       
   736 // CSipRefreshBase::SetCallIdFromOriginalRequestL
       
   737 // -----------------------------------------------------------------------------
       
   738 //
       
   739 void CSipRefreshBase::SetCallIdFromOriginalRequestL(CSIPRequest& aRequest)
       
   740 	{
       
   741 	const CSIPCallIDHeader* originalCallId = iRequest->CallID();
       
   742 	__SIP_ASSERT_LEAVE (originalCallId != 0, KErrGeneral);	
       
   743 	CSIPHeaderBase* newCallId = originalCallId->CloneL();
       
   744 	CleanupStack::PushL(newCallId);
       
   745 	aRequest.AddHeaderL(newCallId);
       
   746 	CleanupStack::Pop(newCallId);
       
   747 	}
       
   748 
       
   749 // -----------------------------------------------------------------------------
       
   750 // CSipRefreshBase::SetCSeqFromOriginalRequestL
       
   751 // -----------------------------------------------------------------------------
       
   752 //
       
   753 void CSipRefreshBase::SetCSeqFromOriginalRequestL(CSIPRequest& aRequest)
       
   754 	{
       
   755 	const CSIPCSeqHeader* originalCSeq = iRequest->CSeq();
       
   756 	__SIP_ASSERT_LEAVE (originalCSeq != 0, KErrGeneral);
       
   757 
       
   758 	CSIPCSeqHeader* newCseq = 
       
   759 	    static_cast<CSIPCSeqHeader*>(originalCSeq->CloneL());
       
   760 	CleanupStack::PushL(newCseq);    
       
   761 	// ask the next CSeq number
       
   762 	TUint cseq = newCseq->Seq();
       
   763 	User::LeaveIfError(iOwner->NextRefreshCSeq(cseq));
       
   764 	newCseq->SetSeq(cseq);
       
   765 
       
   766 	aRequest.AddHeaderL(newCseq);
       
   767 	CleanupStack::Pop(newCseq);
       
   768 	}
       
   769 
       
   770 // -----------------------------------------------------------------------------
       
   771 // CSipRefreshBase::RefreshErrorOccured
       
   772 // -----------------------------------------------------------------------------
       
   773 //
       
   774 TInt CSipRefreshBase::RefreshErrorOccured(TTransactionId aTransactionId, 
       
   775 										  TInt           aError)
       
   776 	{
       
   777 	return iOwner->RefreshError(iRefreshId, aTransactionId, aError);
       
   778 	}
       
   779 
       
   780 // -----------------------------------------------------------------------------
       
   781 // CSipRefreshBase::RefreshReceivedL
       
   782 // -----------------------------------------------------------------------------
       
   783 //
       
   784 void CSipRefreshBase::RefreshReceivedL(TTransactionId aTransactionId, 
       
   785 		                               CSIPResponse*  aResponse)
       
   786 	{
       
   787     iOwner->RefreshReceivedL(aTransactionId, iRefreshId, aResponse);
       
   788 	}
       
   789 
       
   790 // -----------------------------------------------------------------------------
       
   791 // CSipRefreshBase::StartTimerL
       
   792 // -----------------------------------------------------------------------------
       
   793 //
       
   794 void CSipRefreshBase::StartTimerL(TInt aMilliSeconds)
       
   795 	{	
       
   796 	iTimerId = iTimerMgr.StartL(this,aMilliSeconds);
       
   797 	}
       
   798 
       
   799 // -----------------------------------------------------------------------------
       
   800 // CSipRefreshBase::ExpireTimeFromResponseExpiresHeader
       
   801 // -----------------------------------------------------------------------------
       
   802 //
       
   803 TInt CSipRefreshBase::ExpireTimeFromResponseExpiresHeader (
       
   804     CSIPResponse& aResponse)
       
   805 	{
       
   806 	if(!aResponse.HasHeader(SIPStrings::StringF(SipStrConsts::EExpiresHeader)))
       
   807 		{
       
   808 		return KErrNotFound;
       
   809 		}
       
   810 	CSIPHeaderBase* resHeader = 
       
   811 	    aResponse.Header(SIPStrings::StringF(SipStrConsts::EExpiresHeader), 0);
       
   812 	CSIPExpiresHeader* resContact = static_cast<CSIPExpiresHeader*>(resHeader);
       
   813 	return resContact->Value();
       
   814 	}
       
   815 
       
   816 
       
   817 // -----------------------------------------------------------------------------
       
   818 // CSipRefreshBase::SetExpireTimeToResponseExpiresHeaderL
       
   819 // -----------------------------------------------------------------------------
       
   820 //
       
   821 void CSipRefreshBase::SetExpireTimeToResponseExpiresHeaderL (
       
   822     CSIPResponse& aResponse,
       
   823 	TUint         aTimeInSeconds)
       
   824 	{
       
   825 	CSIPExpiresHeader* expires = static_cast<CSIPExpiresHeader*>(
       
   826 	    aResponse.Header(SIPStrings::StringF(SipStrConsts::EExpiresHeader),0));	
       
   827 	
       
   828 	if(expires)
       
   829 		{
       
   830 		expires->SetValue(aTimeInSeconds);
       
   831 		}
       
   832 	else
       
   833 		{
       
   834 		expires = new(ELeave)CSIPExpiresHeader(aTimeInSeconds);
       
   835 		CleanupStack::PushL(expires);
       
   836 		aResponse.AddHeaderL(expires);
       
   837 		CleanupStack::Pop(expires);
       
   838 		}
       
   839 	}
       
   840 
       
   841 // -----------------------------------------------------------------------------
       
   842 // CSipRefreshBase::CheckUpdateRequestMethodL
       
   843 // -----------------------------------------------------------------------------
       
   844 //
       
   845 void CSipRefreshBase::CheckUpdateRequestMethodL(CSIPRequest& aRequest)
       
   846     {
       
   847     if (aRequest.Method().DesC().Length() == 0) 
       
   848 		{
       
   849 		// copy method from original request
       
   850 		aRequest.SetMethodL(iRequest->Method()); 
       
   851 		}
       
   852 	else
       
   853 		{
       
   854 		if(aRequest.Method() != iRequest->Method())
       
   855 			{
       
   856 			User::Leave(KErrArgument); // methods are different
       
   857 			}
       
   858 		}
       
   859     }
       
   860 
       
   861 // -----------------------------------------------------------------------------
       
   862 // CSipRefreshBase::CheckUpdateRequestHeadersL
       
   863 // -----------------------------------------------------------------------------
       
   864 //
       
   865 void CSipRefreshBase::CheckUpdateRequestHeadersL(CSIPRequest& aRequest)
       
   866     {
       
   867     if (!aRequest.To())
       
   868 		{
       
   869 		SetToFromOriginalRequestL(aRequest);
       
   870 		}
       
   871 	if (!aRequest.From())
       
   872 		{
       
   873 		SetFromFromOriginalRequestL(aRequest);
       
   874 		}
       
   875 	if (!aRequest.CallID())
       
   876 		{
       
   877 		SetCallIdFromOriginalRequestL(aRequest);
       
   878 		}
       
   879 	if (!aRequest.CSeq())
       
   880 		{
       
   881 		SetCSeqFromOriginalRequestL(aRequest);
       
   882 		}
       
   883     }
       
   884     
       
   885 // -----------------------------------------------------------------------------
       
   886 // CSipRefreshBase::CalculateInterval
       
   887 // -----------------------------------------------------------------------------
       
   888 //  
       
   889 TInt CSipRefreshBase::CalculateInterval(TInt aValueInSeconds) const
       
   890     {
       
   891     TInt interval = 0; // milliseconds
       
   892     if (aValueInSeconds > 0)
       
   893         {
       
   894 	    const TInt KDelimiter1 = 1200;
       
   895 	    const TInt KDelimiter2 = 600;
       
   896 	    const TInt KDivider = 2;
       
   897 
       
   898 	    // If expiration time is greater than 1200 seconds, 
       
   899 	    // the interval is set to 600 seconds lower than expiration time.
       
   900 	    // Otherwise, interval is set to half of the expiration time
       
   901 	
       
   902 	    if (aValueInSeconds > KDelimiter1)
       
   903 		    {
       
   904 		    interval = KOneSecInMilliSecs*(aValueInSeconds-KDelimiter2);
       
   905 	
       
   906 		    }
       
   907 	    else 
       
   908 		    {
       
   909 		    interval = (KOneSecInMilliSecs*aValueInSeconds)/KDivider;
       
   910 		    }
       
   911         }
       
   912 	return interval;
       
   913     }
       
   914 
       
   915 // -----------------------------------------------------------------------------
       
   916 // CSipRefreshBase::StopTimer
       
   917 // -----------------------------------------------------------------------------
       
   918 //  
       
   919 void CSipRefreshBase::StopTimer()
       
   920 {
       
   921 	if( iTimerMgr.IsRunning(iTimerId) )
       
   922 	{
       
   923 		iTimerMgr.Stop(iTimerId);
       
   924 	}
       
   925 }