realtimenetprots/sipfw/SIP/ConnectionMgr/src/CSenderTcp.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2007-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          : CSenderTcp.cpp
       
    15 // Part of       : ConnectionMgr
       
    16 // Version       : SIP/5.1 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "SipAssert.h"
       
    22 #include "CSenderTcp.h"
       
    23 #include "MContext.h"
       
    24 #include "SipLogs.h"
       
    25 #include "sipmessage.h"
       
    26 #include "CSocketContainer.h"
       
    27 #include "CommonConsts.h"
       
    28 #include "COwnerSettingsList.h"
       
    29 
       
    30 // -----------------------------------------------------------------------------
       
    31 // CSenderTcp::NewL
       
    32 // -----------------------------------------------------------------------------
       
    33 //
       
    34 CSenderTcp* CSenderTcp::NewL(
       
    35     MContext& aContext, 
       
    36     COwnerSettingsList& aSettingsList)
       
    37 	{
       
    38 	CSenderTcp* self = NewLC(aContext, aSettingsList);
       
    39 	CleanupStack::Pop();
       
    40 	return self;
       
    41 	}
       
    42 
       
    43 // -----------------------------------------------------------------------------
       
    44 // CSenderTcp::NewLC
       
    45 // -----------------------------------------------------------------------------
       
    46 //
       
    47 CSenderTcp* CSenderTcp::NewLC(
       
    48     MContext& aContext,
       
    49     COwnerSettingsList& aSettingsList)
       
    50 	{
       
    51 	CSenderTcp* self = new (ELeave) CSenderTcp(aContext, aSettingsList);
       
    52 	CleanupStack::PushL(self);
       
    53 	return self;
       
    54 	}
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CSenderTcp::CSenderTcp
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 CSenderTcp::CSenderTcp(MContext& aContext, COwnerSettingsList& aSettingsList) : 
       
    61     CSender(aContext, aSettingsList)
       
    62 	{	
       
    63 	}
       
    64 	
       
    65 // -----------------------------------------------------------------------------
       
    66 // CSenderTcp::~CSenderTcp
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 CSenderTcp::~CSenderTcp()
       
    70 	{
       
    71 	Cancel();
       
    72 	}
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CSenderTcp::SendL
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 TBool CSenderTcp::SendL(const TSIPTransportParams& aTransportParams,
       
    79                         CSIPMessage& aMessage,
       
    80 					    const TInetAddr& aAddr,
       
    81 					    TUint aOrigTransport,
       
    82 					    TRequestStatus& aStat,
       
    83 					    TBool aStore,
       
    84 					    TBool /*aForceUDP*/)
       
    85 	{
       
    86 	if(!aStore)
       
    87 		{
       
    88 		if(!IsActive())
       
    89 			{
       
    90 			if(aMessage.Content().Length() > 0)
       
    91 				{
       
    92 				iContinueSending = ETrue;
       
    93 				}
       
    94 			
       
    95 			COutgoingData* data = 
       
    96 			    COutgoingData::NewL( aTransportParams, aMessage, aAddr, 
       
    97 			                         aOrigTransport, aStat, 
       
    98 			                         *iContext.SigCompHandler() );		
       
    99 
       
   100 	        iList.AddFirst( *data );		
       
   101 		
       
   102             TCleanupItem cleanupItem( CleanCurrentDataOnLeave, this );
       
   103             CleanupStack::PushL( cleanupItem );
       
   104 										
       
   105 			EncodeAndSendL(aAddr);
       
   106 			
       
   107 			CleanupStack::Pop( 1 ); // cleanupItem
       
   108 			
       
   109 			return EFalse;
       
   110 			}
       
   111 		}
       
   112 
       
   113 	return HandleFirstSendL( aTransportParams,
       
   114 		                     aMessage, 
       
   115 		                     aAddr, 
       
   116 		                     aOrigTransport, 
       
   117 		                     aStat,
       
   118 		                     aStore );
       
   119 	}
       
   120 
       
   121 // -----------------------------------------------------------------------------
       
   122 // CSenderTcp::SendL
       
   123 // -----------------------------------------------------------------------------
       
   124 //
       
   125 void CSenderTcp::SendL(const TSIPTransportParams& aTransportParams,
       
   126                        CSIPMessage& aMessage, 
       
   127                        TRequestStatus& aStat)
       
   128 	{
       
   129 	if (!IsActive())
       
   130 		{
       
   131 		if(aMessage.Content().Length() > 0)
       
   132 			{
       
   133 			iContinueSending = ETrue;
       
   134 			}
       
   135 		
       
   136 		COutgoingData* data = 	
       
   137             COutgoingData::NewL( aTransportParams, aMessage, aStat, 
       
   138                                  *iContext.SigCompHandler() );
       
   139 
       
   140         iList.AddFirst( *data );		
       
   141 		
       
   142         TCleanupItem cleanupItem( CleanCurrentDataOnLeave, this );
       
   143         CleanupStack::PushL( cleanupItem );
       
   144 
       
   145 		TInetAddr address;
       
   146 		iContext.SocketContainer().RemoteName( address );
       
   147 		
       
   148 		EncodeAndSendL( address );
       
   149 		
       
   150 		CleanupStack::Pop( 1 ); // cleanupItem
       
   151 		}
       
   152 	else
       
   153 		{
       
   154     	COutgoingData* data = COutgoingData::NewL( aTransportParams, 
       
   155     	                                           aMessage, aStat,
       
   156     	                                           *iContext.SigCompHandler() );
       
   157 	    iList.AddLast( *data );
       
   158 		}
       
   159 	}
       
   160 
       
   161 // -----------------------------------------------------------------------------
       
   162 // CSenderTcp::SendNextL
       
   163 // -----------------------------------------------------------------------------
       
   164 //
       
   165 void CSenderTcp::SendNextL()
       
   166 	{
       
   167 	COutgoingData* data = CurrentData();
       
   168 	
       
   169 	if ( !IsActive() )
       
   170 		{
       
   171 		if ( iContinueSending && data )
       
   172 			{
       
   173 			DoSend( data->Message().Content() );
       
   174 			iContinueSending = EFalse;
       
   175 			}
       
   176 		else if ( data )
       
   177 			{
       
   178 			if ( data->Message().Content().Length() > 0 )
       
   179 				{
       
   180 				iContinueSending = ETrue;
       
   181 				}
       
   182 			TInetAddr address;
       
   183 			iContext.SocketContainer().RemoteName( address );
       
   184             EncodeAndSendL( address );
       
   185 			}
       
   186 		else
       
   187 			{
       
   188 			iContext.Sending( EFalse );
       
   189 			}
       
   190 		}
       
   191 	}
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CSenderTcp::EncodeAndSendL
       
   195 // -----------------------------------------------------------------------------
       
   196 //
       
   197 void CSenderTcp::EncodeAndSendL( const TInetAddr& aAddr )
       
   198 	{
       
   199 	COutgoingData* data = CurrentData();
       
   200 	
       
   201 	__SIP_ASSERT_LEAVE( data, KErrNotFound );
       
   202 	
       
   203 	data->SetAddress( aAddr );
       
   204 			
       
   205     TPtr8 ptrOutgoing = data->EncodeL( ETrue );
       
   206     
       
   207     if ( data->OrigTransport() == KProtocolInetUdp &&
       
   208          data->Compressed() &&
       
   209          ptrOutgoing.Length() < KMaxUdpMessageSize )
       
   210 	    {
       
   211 	    // If transport was originally UDP and compression decreased size
       
   212 	    // of the message to be under MTU, UDP can be used.
       
   213 	    data->Sent();
       
   214 		iList.Remove( *data );
       
   215 		iContext.Sending( EFalse );
       
   216 		CleanupStack::PushL( data );
       
   217 		iContext.ReRouteL( KProtocolInetUdp, data );
       
   218 		CleanupStack::Pop( data );
       
   219 		SendNextL();
       
   220 		}
       
   221     else
       
   222         {
       
   223     	iOutgoingMessage.Set( ptrOutgoing );
       
   224     	if ( data->Compressed() )
       
   225     		{
       
   226     		iContinueSending = EFalse;
       
   227     		}
       
   228     	
       
   229     	__SIP_MESSAGE_LOG( "Connection Manager::SendToNetwork via TCP", 
       
   230     	                   iOutgoingMessage )
       
   231     	WriteToLog( iOutgoingMessage );
       
   232     	
       
   233     	DoSend( iOutgoingMessage );
       
   234         }
       
   235 	}
       
   236 
       
   237 // -----------------------------------------------------------------------------
       
   238 // CSenderTcp::HandleFirstSendL
       
   239 // -----------------------------------------------------------------------------
       
   240 //	
       
   241 TBool CSenderTcp::HandleFirstSendL( 
       
   242     const TSIPTransportParams& aTransportParams,
       
   243     CSIPMessage& aMessage, 
       
   244     const TInetAddr& aAddr, 
       
   245 	TUint aOrigTransport, 
       
   246 	TRequestStatus& aStat,
       
   247 	TBool aStore )
       
   248     {
       
   249     COutgoingData* data = COutgoingData::NewLC( aTransportParams,
       
   250 	                                            aMessage, 
       
   251 	                                            aAddr, 
       
   252 	                                            aOrigTransport,
       
   253 		                                        aStat, 
       
   254 											    *iContext.SigCompHandler() );
       
   255 	
       
   256 	TBool isFirstSend( iList.IsEmpty() && aStore );
       
   257 	
       
   258 	if ( aOrigTransport == KProtocolInetUdp && isFirstSend )
       
   259 	    {
       
   260 	    // Have to check immediately whether compression decreases size
       
   261 	    // so that UDP could be used.
       
   262 	    
       
   263 	    TPtr8 encoded = data->EncodeL( ETrue );
       
   264 	    
       
   265 	    if ( encoded.Length() < KMaxUdpMessageSize && data->Compressed() )
       
   266 	        {
       
   267 	        data->Sent();
       
   268     		iContext.ReRouteL( KProtocolInetUdp, data );
       
   269     		CleanupStack::Pop( data );
       
   270     		return EFalse;
       
   271 	        }
       
   272 	    }
       
   273 
       
   274     CleanupStack::Pop( data );
       
   275 	iList.AddLast( *data );
       
   276 	
       
   277 	return isFirstSend;
       
   278     }
       
   279 	
       
   280 // -----------------------------------------------------------------------------
       
   281 // CSenderTcp::StoredData
       
   282 // -----------------------------------------------------------------------------
       
   283 //
       
   284 COutgoingData* CSenderTcp::StoredData()
       
   285 	{
       
   286 	if (!iList.IsEmpty())
       
   287 		{
       
   288 		COutgoingData* listItem = 0;
       
   289 		iListIter.SetToFirst();
       
   290 		while ((listItem = iListIter++) != 0)
       
   291 			{
       
   292 			iList.Remove(*listItem);
       
   293             return listItem;
       
   294 			}
       
   295 		}
       
   296 	return 0;
       
   297 	}
       
   298 
       
   299 // -----------------------------------------------------------------------------
       
   300 // CSenderTcp::Data
       
   301 // -----------------------------------------------------------------------------
       
   302 //
       
   303 COutgoingData* CSenderTcp::Data()
       
   304 	{
       
   305 	if (!iList.IsEmpty())
       
   306 		{
       
   307 		COutgoingData* listItem = 0;
       
   308 		iListIter.SetToFirst();
       
   309 		while ((listItem = iListIter++) != 0)
       
   310 			{
       
   311 			iList.Remove(*listItem);
       
   312 			return listItem;
       
   313 			}
       
   314 		}
       
   315 	return 0;
       
   316 	}
       
   317 
       
   318 // -----------------------------------------------------------------------------
       
   319 // CSenderTcp::DoSend
       
   320 // -----------------------------------------------------------------------------
       
   321 //
       
   322 void CSenderTcp::DoSend( const TDesC8& aData )
       
   323     {
       
   324     COutgoingData* data = CurrentData();
       
   325     
       
   326     __SIP_ASSERT_RETURN( !IsActive() && data, KErrInUse );
       
   327     
       
   328     // Set socket options before sending, options will be cleared after
       
   329     // send has completed.
       
   330     iSettingsList.SetOpts( data->TransportParams(),
       
   331     	                   iContext.SocketContainer().Socket() );
       
   332     	                       
       
   333 	iContext.Sending( ETrue );
       
   334 	iContext.SocketContainer().Send( aData, 0, iStatus );
       
   335 			
       
   336 	SetActive();
       
   337     }
       
   338