realtimenetprots/sipfw/SIP/Transaction/src/ClientTransaction.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2006-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          : ClientTransaction.cpp
       
    15 // Part of       : Transaction
       
    16 // Version       : SIP/5.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "uri8.h"
       
    22 #include "SipAssert.h"
       
    23 #include "siperr.h"
       
    24 #include "siprequest.h"
       
    25 #include "sipresponse.h"
       
    26 #include "sipfromheader.h"
       
    27 #include "sipstrings.h"
       
    28 #include "sipstrconsts.h"
       
    29 #include "DeleteMgr.h"
       
    30 #include "UserAgentBase.h"
       
    31 #include "SIPMessageUtility.h"
       
    32 #include "MTransactionStore.h"
       
    33 
       
    34 #include "Transmitter.h"
       
    35 #include "ClientTransaction.h"
       
    36 
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CClientTransaction::CClientTransaction
       
    40 // -----------------------------------------------------------------------------
       
    41 //
       
    42 CClientTransaction::CClientTransaction(CUserAgentBase& aUserAgent,
       
    43 									   CTransmitter& aTransmitter,
       
    44 									   MTimerManager& aTimers,
       
    45 									   CTransactionState& aInitialState,
       
    46 									   TTimerValues& aTimerValues,
       
    47 									   MTransactionStore& aTransactionStore) :
       
    48 	CTransaction(aUserAgent,
       
    49 				 aTransmitter,
       
    50 				 aTimers,
       
    51 				 aInitialState,
       
    52 				 aTimerValues),
       
    53 	iTransactionStore(aTransactionStore)
       
    54 	{	
       
    55 	}
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 // CClientTransaction::~CClientTransaction
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 CClientTransaction::~CClientTransaction()
       
    62 	{
       
    63 	delete iOutboundProxy;
       
    64 	}
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CClientTransaction::TransactionId
       
    68 // If transaction is detached from UAC, transaction knows the TransactionId.
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 TTransactionId CClientTransaction::TransactionId() const
       
    72 	{
       
    73 	__TEST_INVARIANT;
       
    74 
       
    75 	if (iUserAgent)
       
    76 		{
       
    77 		return iUserAgent->TransactionId();
       
    78 		}
       
    79 
       
    80 	return iTransactionId;
       
    81 	}
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CClientTransaction::StoreRequest
       
    85 // -----------------------------------------------------------------------------
       
    86 //
       
    87 void CClientTransaction::StoreRequest(CSIPRequest& aReq,
       
    88 									  const TInetAddr& aAddress,
       
    89 									  const TSIPTransportParams& aParams,
       
    90 									  RStringF aTransportProtocol,
       
    91 									  TBool aForceUDP,
       
    92 									  CUri8* aOutboundProxy)
       
    93 	{
       
    94 	__TEST_INVARIANT;
       
    95 	__ASSERT_ALWAYS(!iOutgoingMsg && !iOutboundProxy,
       
    96 					User::Panic(_L("ClientTa:StoreRq"), KErrAlreadyExists));
       
    97 
       
    98 	iOutgoingMsg = &aReq;
       
    99 	iRemoteAddr = aAddress;
       
   100 	iTransportParams = aParams;
       
   101 	iTransportProtocol = aTransportProtocol;
       
   102 	iForceUDP = aForceUDP;
       
   103 	iOutboundProxy = aOutboundProxy;
       
   104 
       
   105 	__TEST_INVARIANT;
       
   106 	}
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // CClientTransaction::ClearProxy
       
   110 // -----------------------------------------------------------------------------
       
   111 //
       
   112 void CClientTransaction::ClearProxy()
       
   113 	{
       
   114 	__TEST_INVARIANT;
       
   115 
       
   116 	iOutboundProxy = NULL;
       
   117 	
       
   118 	__TEST_INVARIANT;
       
   119 	}
       
   120 
       
   121 // -----------------------------------------------------------------------------
       
   122 // CClientTransaction::SendToTransmitterL
       
   123 // -----------------------------------------------------------------------------
       
   124 //
       
   125 void CClientTransaction::SendToTransmitterL()
       
   126 	{
       
   127 	__TEST_INVARIANT;
       
   128 	__SIP_ASSERT_LEAVE(iOutgoingMsg && iTransmitter, KErrNotFound);    
       
   129 
       
   130 	iTransmitter->SendRequestL(static_cast<CSIPRequest&>(*iOutgoingMsg),							   
       
   131 							   iRemoteAddr,
       
   132 							   iForceUDP,
       
   133 							   iTransportParams,
       
   134 							   iOutboundProxy,
       
   135 							   this);
       
   136 	__TEST_INVARIANT;
       
   137 	}
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CClientTransaction::ShouldTaHandleResponse
       
   141 // Drop invalid response, but don't terminate transaction just because a broken
       
   142 // SIP response came from the network.
       
   143 //
       
   144 // A Non-INVITE transaction passes each response to upper layer only once and
       
   145 // filters out retransmissions.
       
   146 //
       
   147 // INVITE transaction passes every 1xx to upper layer, as INVITE may've forked.
       
   148 // -----------------------------------------------------------------------------
       
   149 //
       
   150 TBool CClientTransaction::ShouldTaHandleResponse(CSIPResponse* aResp) const
       
   151 	{
       
   152 	__TEST_INVARIANT;
       
   153 	__ASSERT_DEBUG(aResp,
       
   154 		User::Panic(_L("ClientTa:ShouldTaHandleResp !aResp"), KErrArgument));
       
   155 
       
   156     //After a final response, ShouldTaHandleResponse must not be used
       
   157 	__ASSERT_DEBUG(iReceivedResponseCode < 200,
       
   158 	   User::Panic(_L("ClientTa:ShouldTaHandleResp iRecvRespCode>=200"),
       
   159        KErrSIPInvalidTransactionState));
       
   160 
       
   161 	if ( !CheckReceivedResponse(*aResp) ||
       
   162 		 (!IsInviteTransaction() &&
       
   163 	      (iReceivedResponseCode == aResp->ResponseCode())) )
       
   164 	    {
       
   165 	    delete aResp;
       
   166 	    return EFalse;
       
   167 	    }
       
   168 
       
   169 	return ETrue;
       
   170 	}
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CClientTransaction::PassResponseToUserAgentL
       
   174 // -----------------------------------------------------------------------------
       
   175 //
       
   176 void CClientTransaction::PassResponseToUserAgentL(CSIPResponse* aResp)
       
   177 	{
       
   178 	__TEST_INVARIANT;
       
   179     __SIP_ASSERT_LEAVE(iUserAgent, KErrNotFound);
       
   180     __SIP_ASSERT_LEAVE(aResp, KErrArgument);
       
   181 
       
   182 	TUint respCode = aResp->ResponseCode();
       
   183 	iUserAgent->ReceiveL(aResp);
       
   184 	iReceivedResponseCode = respCode;
       
   185 
       
   186 	__TEST_INVARIANT;
       
   187 	}
       
   188 
       
   189 // -----------------------------------------------------------------------------
       
   190 // CClientTransaction::CheckReceivedResponse
       
   191 // From-tag must match the request's tag. Response must have exactly one Via.
       
   192 // -----------------------------------------------------------------------------
       
   193 //
       
   194 TBool CClientTransaction::CheckReceivedResponse(CSIPResponse& aResp) const
       
   195 	{
       
   196 	__TEST_INVARIANT;
       
   197 
       
   198 	RStringF from = SIPStrings::StringF(SipStrConsts::EFromHeader);	
       
   199 	if (!aResp.HasHeader(from))
       
   200 		{
       
   201 		return EFalse;
       
   202 		}
       
   203 
       
   204 	__ASSERT_DEBUG(iOutgoingMsg,
       
   205 		User::Panic(_L("ClientTa:ChkRecvResp !iOutMsg"), KErrNotFound));
       
   206 
       
   207 	TSglQueIter<CSIPHeaderBase> iterReq = iOutgoingMsg->Headers(from);
       
   208 	TSglQueIter<CSIPHeaderBase> iterResp = aResp.Headers(from);
       
   209 
       
   210     return CSIPMessageUtility::CompareTags(
       
   211 		static_cast<CSIPFromHeader&>(*iterReq),
       
   212 		static_cast<CSIPFromHeader&>(*iterResp)) &&
       
   213 		(aResp.HeaderCount(SIPStrings::StringF(SipStrConsts::EViaHeader)) == 1);
       
   214 	}
       
   215 
       
   216 // -----------------------------------------------------------------------------
       
   217 // CClientTransaction::RunIndependently
       
   218 // -----------------------------------------------------------------------------
       
   219 //
       
   220 void CClientTransaction::RunIndependently(TTransactionId aTransactionId,
       
   221 										  CDeleteMgr* aDeleteMgr,
       
   222 										  TBool aClearTransmitter)
       
   223 	{
       
   224 	__TEST_INVARIANT;
       
   225 	__ASSERT_DEBUG(!iDeleteMgr,
       
   226 		User::Panic(_L("ClientTa:RunIndependently iDM!=0"), KErrAlreadyExists));
       
   227     __SIP_ASSERT_RETURN(aDeleteMgr, KErrArgument);
       
   228 
       
   229 	iTransactionId = aTransactionId;
       
   230 	iDeleteMgr = aDeleteMgr;
       
   231 
       
   232 	if (aClearTransmitter)
       
   233 		{
       
   234 		iTransmitter->DetachCallback(this);
       
   235 		iTransmitter = NULL;
       
   236 		}
       
   237 
       
   238 	__TEST_INVARIANT;
       
   239 	}
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // CClientTransaction::CheckForTransportChange
       
   243 // -----------------------------------------------------------------------------
       
   244 //
       
   245 void CClientTransaction::CheckForTransportChange()
       
   246 	{
       
   247 	__TEST_INVARIANT;
       
   248 	__SIP_ASSERT_RETURN(iOutgoingMsg, KErrNotFound);
       
   249 
       
   250 	UpdateTransportProtocol(*iOutgoingMsg);
       
   251 
       
   252 	__TEST_INVARIANT;
       
   253 	}
       
   254 
       
   255 // -----------------------------------------------------------------------------
       
   256 // CClientTransaction::IcmpErrorL
       
   257 // Terminate with KErrSIPICMPFailure if transaction sends using UDP to the failed address
       
   258 // KErrSIPICMPFailure will be passed to observers like Profile Agent
       
   259 // -----------------------------------------------------------------------------
       
   260 //
       
   261 void CClientTransaction::IcmpErrorL(const TInetAddr& aAddress,
       
   262 								    CSipConnectionMgr::TICMPError /*aError*/)
       
   263 	{
       
   264 	__TEST_INVARIANT;
       
   265 
       
   266 	if (IsUnreliableTransportUsed() &&
       
   267 		CSIPMessageUtility::CompareTInetAddr(iRemoteAddr,
       
   268 											 TransportProtocol(),
       
   269 											 aAddress))
       
   270 		{
       
   271         TerminatedL(KErrSIPICMPFailure);
       
   272 		}
       
   273 
       
   274 	__TEST_INVARIANT;
       
   275 	}
       
   276 
       
   277 // -----------------------------------------------------------------------------
       
   278 // CClientTransaction::TerminatedL
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 void CClientTransaction::TerminatedL(TInt aReason)
       
   282 	{
       
   283 	__TEST_INVARIANT;
       
   284 	__SIP_INT_LOG1( "CClientTransaction::TerminatedL Error",
       
   285 					aReason )
       
   286 	if (!iTerminated)
       
   287 		{		
       
   288 		CTransaction::TerminatedL(aReason);
       
   289 
       
   290 		if (iDeleteMgr)
       
   291 			{
       
   292 			//Transaction is detached from UAC, and must remove itself from
       
   293 			//TransactionStore and use DeleteMgr to free itself.
       
   294 
       
   295 			if (iDeleteMgr->AddDeleteRequest(this) == KErrNone)
       
   296 				{
       
   297 				iTransactionStore.Remove(iTransactionId);
       
   298 				}
       
   299 			else
       
   300 				{
       
   301 				//Mark transaction to be deleted later on by MTransactionStore
       
   302 				iTransactionStore.UpdateTransactionId(iTransactionId,
       
   303 													  KEmptyTransactionId);
       
   304 				}
       
   305 			}
       
   306 		}
       
   307 
       
   308 	__TEST_INVARIANT;
       
   309 	}	
       
   310 
       
   311 // -----------------------------------------------------------------------------
       
   312 // CClientTransaction::__DbgTestInvariant
       
   313 // -----------------------------------------------------------------------------
       
   314 //
       
   315 
       
   316 void CClientTransaction::__DbgTestInvariant() const
       
   317 	{
       
   318 	if (iOutgoingMsg && !iOutgoingMsg->IsRequest())
       
   319 		{
       
   320 		User::Invariant();
       
   321 		}
       
   322 	}