realtimenetprots/sipfw/SIP/ConnectionMgr/src/CTcpResSender.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2004-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          : CTcpResSender.cpp
       
    15 // Part of       : ConnectionMgr
       
    16 // Version       : SIP/4.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "SipAssert.h"
       
    22 #include "CTcpResSender.h"
       
    23 #include "CSIPServerResolver.h"
       
    24 #include "CSipConnection.h"
       
    25 #include "COutgoingData.h"
       
    26 #include "sipuri.h"
       
    27 #include "sipviaheader.h"
       
    28 #include "siphostport.h"
       
    29 #include "CTransportBase.h"
       
    30 #include "MSIPResolvingResult.h"
       
    31 #include "sipstrings.h"
       
    32 #include "sipstrconsts.h"
       
    33 #include "TSIPTransportParams.h"
       
    34 #include "siperr.h"
       
    35 
       
    36 const TInt CTcpResponseSender::iSenderOffset =
       
    37 	_FOFF(CTcpResponseSender, iSenderLink);
       
    38 
       
    39 
       
    40 // -----------------------------------------------------------------------------
       
    41 // CTcpResponseSender::CTcpResponseSender
       
    42 // -----------------------------------------------------------------------------
       
    43 //
       
    44 CTcpResponseSender::CTcpResponseSender( const TSIPTransportParams& aParams,
       
    45                                         CSIPServerResolver& aHostResolver, 
       
    46 							 		    CSipConnection& aOwner ) :
       
    47     iTransportParams( aParams ),
       
    48     iHostResolver( aHostResolver ),
       
    49     iOwner( &aOwner ),
       
    50     iSending( EFalse ),
       
    51     iResolving( EFalse )
       
    52 	{
       
    53 	}
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 // CTcpResponseSender::~CTcpResponseSender
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 CTcpResponseSender::~CTcpResponseSender()
       
    60 	{
       
    61 	if ( iResolving && iData )
       
    62 		{
       
    63 		CompleteRequest( iData->Status(), KErrCouldNotConnect );
       
    64 		}
       
    65 	iHostResolver.Cancel( this );		    
       
    66 	iResultArray.ResetAndDestroy();
       
    67 	delete iData;
       
    68 	}
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CTcpResponseSender::ConnectionFailedL
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 void CTcpResponseSender::ConnectionFailedL()
       
    75 	{
       
    76 	// Safety check, although shouldn't ever exceed array bounds at this point
       
    77 	if ( IndexWithinBounds() )
       
    78 	    {
       
    79 	    iResultArray[ iCurrentIndex ]->SetFailed( ETrue );
       
    80 	    }
       
    81 	SendL();
       
    82 	}
       
    83 
       
    84 // -----------------------------------------------------------------------------
       
    85 // CTcpResponseSender::Connected
       
    86 // -----------------------------------------------------------------------------
       
    87 //
       
    88 void CTcpResponseSender::Connected( const TInetAddr& aAddr )	
       
    89 	{
       
    90 	if ( iSending )
       
    91 		{
       
    92 		if ( IndexWithinBounds() && 
       
    93 		     iResultArray[ iCurrentIndex ]->Address().CmpAddr( aAddr ) )
       
    94 			{
       
    95 			iOwner->RemoveTcpSender( this );
       
    96 			}
       
    97 		}
       
    98 	}
       
    99 
       
   100 // -----------------------------------------------------------------------------
       
   101 // CTcpResponseSender::IsInProgress
       
   102 // -----------------------------------------------------------------------------
       
   103 //
       
   104 TBool CTcpResponseSender::IsInProgress( COutgoingData& aData )
       
   105 	{
       
   106 	return iData && aData.Status() == iData->Status();
       
   107 	}
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // CTcpResponseSender::ResolveL
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 void CTcpResponseSender::ResolveL( COutgoingData& aData )
       
   114 	{
       
   115 	if ( !iResolving )
       
   116 		{
       
   117 		if ( aData.Message().HasHeader( 
       
   118 		    	SIPStrings::StringF( SipStrConsts::EViaHeader ) ) )
       
   119 			{
       
   120 			TSglQueIter< CSIPHeaderBase > iter = aData.Message().Headers( 
       
   121 				SIPStrings::StringF( SipStrConsts::EViaHeader ) );
       
   122 			CSIPHeaderBase* header = iter;
       
   123 			CSIPViaHeader* via = static_cast<CSIPViaHeader*>( header );
       
   124 			iHostResolver.GetByViaL( *via, iResultArray, this );
       
   125 			iResolving = ETrue;
       
   126 			}
       
   127 		}
       
   128 	}
       
   129 
       
   130 // -----------------------------------------------------------------------------
       
   131 // CTcpResponseSender::CancelSend
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 TBool CTcpResponseSender::CancelSend( TRequestStatus &aStatus )
       
   135 	{
       
   136 	if ( iResolving && iData && &aStatus == iData->Status() )
       
   137 		{
       
   138 		CompleteRequest( iData->Status(), KErrSIPTransportFailure );
       
   139 		iHostResolver.Cancel( this );
       
   140 		iResolving = EFalse;
       
   141 		return ETrue;
       
   142 		}
       
   143 	return EFalse;
       
   144 	}
       
   145 
       
   146 // -----------------------------------------------------------------------------
       
   147 // CTcpResponseSender::SetData
       
   148 // -----------------------------------------------------------------------------
       
   149 //    
       
   150 void CTcpResponseSender::SetData( COutgoingData* aData )
       
   151 	{
       
   152 	__SIP_ASSERT_RETURN( !iData, KErrAlreadyExists );
       
   153 	iData = aData;
       
   154 	}
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // CTcpResponseSender::CompletedL
       
   158 // -----------------------------------------------------------------------------
       
   159 //   
       
   160 void CTcpResponseSender::CompletedL()
       
   161     {
       
   162     iResolving = EFalse;
       
   163 	SendL();
       
   164     }
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 // CTcpResponseSender::ErrorOccured
       
   168 // -----------------------------------------------------------------------------
       
   169 //	
       
   170 void CTcpResponseSender::ErrorOccured( TInt /*aError*/ )
       
   171     {
       
   172     iResolving = EFalse;
       
   173 	if ( iData )
       
   174 		{
       
   175 		CompleteRequest( iData->Status(), KErrCouldNotConnect );
       
   176 		}
       
   177 	iOwner->RemoveTcpSender( this );
       
   178     }
       
   179     
       
   180 // -----------------------------------------------------------------------------
       
   181 // CTcpResponseSender::SendL
       
   182 // -----------------------------------------------------------------------------
       
   183 //
       
   184 void CTcpResponseSender::SendL()
       
   185 	{
       
   186 	__SIP_ASSERT_LEAVE( iData, KErrNotFound );
       
   187 
       
   188 	MSIPResolvingResult* result = FirstUnfailedResult();
       
   189 	if ( result )
       
   190 		{
       
   191 		CTransportBase* transport;
       
   192 		transport = iOwner->FindTransportL( iTransportParams,
       
   193 		                                    &iData->Message(),
       
   194 			                                result->Address() );	
       
   195 		if ( transport )
       
   196 			{
       
   197 			iSending = ETrue;
       
   198 			transport->Send( iTransportParams,
       
   199 			                 static_cast<CSIPResponse&>( iData->Message() ), 
       
   200 				             result->Address(), 
       
   201 						     *iData->Status() );
       
   202 			}
       
   203 		else
       
   204 			{
       
   205 			iOwner->CreateTcpTransportPointL( iTransportParams,
       
   206 			                                  result->Address() );
       
   207 			                                  
       
   208 			transport = iOwner->FindTransportL( iTransportParams,
       
   209 			                                    &iData->Message(), 
       
   210 				                                result->Address() );		
       
   211 			if ( transport )
       
   212 				{
       
   213 				iSending = ETrue;
       
   214 				transport->Send( iTransportParams,
       
   215 				                 static_cast<CSIPResponse&>( iData->Message() ), 
       
   216 					             result->Address(), 
       
   217 								 *iData->Status() );
       
   218 				}
       
   219 			else
       
   220 				{
       
   221 				CompleteRequest( iData->Status(), KErrCouldNotConnect );
       
   222 				iOwner->RemoveTcpSender( this );
       
   223 				}
       
   224 			}
       
   225 		}
       
   226 	else
       
   227 		{
       
   228 		// Sending to every resolved address failed, resolve more
       
   229 		ResolveL( *iData );
       
   230 		}
       
   231 	}
       
   232     
       
   233 // -----------------------------------------------------------------------------
       
   234 // CTcpResponseSender::CompleteRequest
       
   235 // -----------------------------------------------------------------------------
       
   236 //
       
   237 void CTcpResponseSender::CompleteRequest( TRequestStatus* aStatus, TInt aReason )
       
   238 	{
       
   239 	if ( aStatus != 0 && *aStatus == KRequestPending )
       
   240 		{
       
   241 		User::RequestComplete( aStatus, aReason );
       
   242 		}
       
   243 	}
       
   244 	
       
   245 // -----------------------------------------------------------------------------
       
   246 // CTcpResponseSender::FirstUnfailedResult
       
   247 // -----------------------------------------------------------------------------
       
   248 //
       
   249 MSIPResolvingResult* CTcpResponseSender::FirstUnfailedResult()
       
   250     {
       
   251     for ( TInt i = 0; i < iResultArray.Count(); i++ )
       
   252         {
       
   253         MSIPResolvingResult* result = iResultArray[ i ];
       
   254         if ( !result->Failed() )
       
   255             {
       
   256             iCurrentIndex = i;
       
   257             return result;
       
   258             }
       
   259         }
       
   260     iCurrentIndex = KErrNotFound;
       
   261     return 0;
       
   262     }
       
   263 
       
   264 // -----------------------------------------------------------------------------
       
   265 // CTcpResponseSender::IndexWithinBounds
       
   266 // -----------------------------------------------------------------------------
       
   267 //
       
   268 TBool CTcpResponseSender::IndexWithinBounds()
       
   269     {
       
   270     return ( iCurrentIndex >= 0 && iCurrentIndex < iResultArray.Count() );
       
   271     }