realtimenetprots/sipfw/SIP/ConnectionMgr/src/CSender.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          : CSender.cpp
       
    15 // Part of       : ConnectionMgr
       
    16 // Version       : SIP/4.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "CSender.h"
       
    22 #include "SipLogs.h"
       
    23 #include "CSocketContainer.h"
       
    24 #include "siperr.h"
       
    25 #include "COwnerSettingsList.h"
       
    26 
       
    27 // -----------------------------------------------------------------------------
       
    28 // CSender::CSender
       
    29 // -----------------------------------------------------------------------------
       
    30 //
       
    31 CSender::CSender(MContext& aContext,COwnerSettingsList& aSettingsList) :
       
    32     CActive(CActive::EPriorityStandard),
       
    33     iContext(aContext), 
       
    34     iSettingsList(aSettingsList),
       
    35     iList(COutgoingData::iOffset),
       
    36     iListIter(iList),
       
    37     iContinueSending(EFalse)
       
    38 	{
       
    39 	CActiveScheduler::Add(this);
       
    40 	}
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CSender::~CSender
       
    44 // -----------------------------------------------------------------------------
       
    45 //
       
    46 CSender::~CSender() 
       
    47 	{
       
    48 	CancelAllRequests( KErrSIPTransportFailure );
       
    49 	}
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CSender::SendL
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 void CSender::SendL (
       
    56     const TSIPTransportParams& /*aTransportParams*/, 
       
    57     CSIPMessage& /*aMessage*/, 
       
    58     TRequestStatus& /*aStat*/)
       
    59 	{
       
    60 	__ASSERT_DEBUG(EFalse,
       
    61 	User::Panic(_L("CSender baseclass is called"),
       
    62 	KErrGeneral));
       
    63 	}
       
    64 
       
    65 // -----------------------------------------------------------------------------
       
    66 // CSender::SendL
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 void CSender::SendL (COutgoingData* /*aData*/)
       
    70 	{
       
    71 	__ASSERT_DEBUG(EFalse,
       
    72 	User::Panic(_L("CSender baseclass is called"),
       
    73 	KErrGeneral));
       
    74 	}
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 // CSender::StoredData
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 COutgoingData* CSender::StoredData()
       
    81 	{
       
    82 	return 0;
       
    83 	}
       
    84 
       
    85 // -----------------------------------------------------------------------------
       
    86 // CSender::Data
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 COutgoingData* CSender::Data()
       
    90 	{
       
    91 	return 0;
       
    92 	}
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // CSender::FindAndCancel
       
    96 // -----------------------------------------------------------------------------
       
    97 //
       
    98 TBool CSender::FindAndCancel(TRequestStatus& aStat)
       
    99 	{
       
   100 	COutgoingData* currentData = CurrentData();
       
   101 	
       
   102 	if (currentData && &aStat == currentData->Status())
       
   103 		{
       
   104 		iContext.SocketContainer().CancelSend();
       
   105         iContext.Sending( EFalse );
       
   106         RemoveCurrentData( KErrSIPTransportFailure );
       
   107         return ETrue;
       
   108 		}	
       
   109 	
       
   110 	if (!iList.IsEmpty())
       
   111 		{
       
   112 		iListIter.SetToFirst();
       
   113 		for(COutgoingData* data = iListIter; data; data = iListIter++)
       
   114 			{
       
   115 			if(&aStat == data->Status())
       
   116 				{
       
   117 				CompleteRequest(data->Status(), KErrSIPTransportFailure );
       
   118 				iList.Remove(*data);
       
   119 				delete data;
       
   120 				return ETrue;
       
   121 				}
       
   122 			}
       
   123 		}
       
   124 
       
   125 	return EFalse;		
       
   126 	}
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 // CSender::CancelAllRequests
       
   130 // -----------------------------------------------------------------------------
       
   131 //
       
   132 void CSender::CancelAllRequests (TInt aReason)
       
   133 	{
       
   134 	Cancel();
       
   135 	RemoveCurrentData(aReason);
       
   136 	if (!iList.IsEmpty())
       
   137 		{
       
   138 		COutgoingData* data = 0;
       
   139 		iListIter.SetToFirst();
       
   140 		while ((data = iListIter++) != 0)
       
   141 			{
       
   142 			CompleteRequest(data->Status(),aReason);
       
   143 			iList.Remove(*data);
       
   144 			delete data;
       
   145 			}
       
   146 		}
       
   147 	}
       
   148 
       
   149 // -----------------------------------------------------------------------------
       
   150 // CSender::CurrentData
       
   151 // -----------------------------------------------------------------------------
       
   152 //
       
   153 COutgoingData* CSender::CurrentData()
       
   154     {
       
   155     COutgoingData* data( NULL );
       
   156     if ( !iList.IsEmpty() )
       
   157         {
       
   158         data = iList.First();
       
   159         }
       
   160     return data;
       
   161     }
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CSender::IpAddressType
       
   165 // -----------------------------------------------------------------------------
       
   166 //
       
   167 TUint CSender::IpAddrType( const TInetAddr& aAddr )
       
   168     {
       
   169     // TInetAddr::Family returns sometimes KAfInet6 for an IPv4 address.
       
   170     // The way to make sure the address is IPv4 is to use TInetAddr::Address.
       
   171     // This is because a real IPv6 cannot be represented with a TUint.
       
   172     TUint type( KAFUnspec );
       
   173     if ( aAddr.Address() )
       
   174         {
       
   175         type = KAfInet;
       
   176         }
       
   177     else
       
   178         {
       
   179         type = KAfInet6;
       
   180         }
       
   181     return type;
       
   182     }
       
   183 
       
   184 // -----------------------------------------------------------------------------
       
   185 // CSender::CleanCurrentDataOnLeave
       
   186 // -----------------------------------------------------------------------------
       
   187 //
       
   188 void CSender::CleanCurrentDataOnLeave( TAny* aSelf )
       
   189     {
       
   190     CSender* self = reinterpret_cast< CSender* >( aSelf );
       
   191     COutgoingData* data = self->CurrentData();
       
   192 	if ( data )
       
   193 		{
       
   194 		self->iList.Remove( *data );
       
   195 		self->iContinueSending = EFalse;
       
   196 		delete data;
       
   197 		}
       
   198 	}
       
   199 
       
   200 // -----------------------------------------------------------------------------
       
   201 // CSender::WriteToLog
       
   202 // -----------------------------------------------------------------------------
       
   203 //
       
   204 #if (defined(_DEBUG) && defined(USE_SIP_LOGS))
       
   205 void CSender::WriteToLog( const TDesC8& aMessage )
       
   206 	{
       
   207 	if ( CurrentData() )
       
   208 	    {
       
   209 	    __SIP_ADDR_LOG( "Outgoing data to address", CurrentData()->Address() )
       
   210 	    }
       
   211 	__SIP_DES8_LOG( "Outgoing data", aMessage )
       
   212 	}
       
   213 #else
       
   214 void CSender::WriteToLog( const TDesC8& /*aMessage*/ )
       
   215 	{
       
   216 	}
       
   217 #endif
       
   218 
       
   219 
       
   220 // -----------------------------------------------------------------------------
       
   221 // CSender::RunL
       
   222 // -----------------------------------------------------------------------------
       
   223 //
       
   224 void CSender::RunL()
       
   225 	{
       
   226 	TInt status = iStatus.Int();
       
   227 	
       
   228 	__SIP_INT_LOG1( "CSender::RunL status:", status )
       
   229 	
       
   230 	TBool terminated( EFalse );
       
   231 
       
   232     switch ( status )
       
   233         {
       
   234         case KErrNone:
       
   235             {
       
   236             COutgoingData* data = CurrentData();
       
   237            	if ( data )
       
   238     			{
       
   239     			data->Sent();
       
   240     			
       
   241     			CSocketContainer* socketContainer =
       
   242     			    iContext.SocketContainer( IpAddrType( data->Address() ) );
       
   243     			if ( socketContainer )
       
   244     			    {
       
   245         			// Clear socket options after sending has completed.
       
   246         			// Do only if it completed successfully as it might be 
       
   247         			// unsafe to attempt setting options after socket failure.
       
   248         			iSettingsList.ClearOpts( 
       
   249         			    data->TransportParams(),
       
   250         	            socketContainer->Socket() );
       
   251     			    }
       
   252     			}
       
   253     		if ( !iContinueSending )
       
   254     			{
       
   255     			RemoveCurrentData( KErrNone );
       
   256     			}
       
   257             break;
       
   258             }
       
   259         case KErrCancel:
       
   260             {
       
   261             break;
       
   262             }
       
   263         case KErrDisconnected:
       
   264             {
       
   265             terminated = iContext.DisconnectedL();
       
   266             break;
       
   267             }
       
   268         default: // Rest of the errors
       
   269             {
       
   270             terminated = iContext.StopL();
       
   271             if ( !terminated )
       
   272                 {
       
   273                 iContext.ResetSocketL();
       
   274 			    iContext.ContinueL();
       
   275                 }
       
   276             break;
       
   277             }
       
   278         }
       
   279         
       
   280     if ( !terminated )
       
   281         {
       
   282         SendNextL();
       
   283         }
       
   284 	}
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CSender::RunError
       
   288 // -----------------------------------------------------------------------------
       
   289 //
       
   290 TInt CSender::RunError(TInt aError)
       
   291 	{
       
   292 	if(aError != KErrNoMemory)
       
   293 		{
       
   294 		return KErrNone;
       
   295 		}
       
   296 	return aError;
       
   297 	}
       
   298 
       
   299 // -----------------------------------------------------------------------------
       
   300 // CSender::DoCancel
       
   301 // -----------------------------------------------------------------------------
       
   302 //
       
   303 void CSender::DoCancel()
       
   304 	{
       
   305 	iContext.SocketContainer().CancelSend();
       
   306 	iContext.Sending( EFalse );
       
   307 	RemoveCurrentData( KErrSIPTransportFailure );
       
   308 	}
       
   309 
       
   310 // -----------------------------------------------------------------------------
       
   311 // CSender::RemoveCurrentData
       
   312 // -----------------------------------------------------------------------------
       
   313 //
       
   314 void CSender::RemoveCurrentData(TInt aReason)
       
   315 	{
       
   316 	COutgoingData* data = CurrentData();
       
   317 	if ( data )
       
   318 		{
       
   319 		iList.Remove( *data );
       
   320 		iContinueSending = EFalse;
       
   321 		CompleteRequest(data->Status(),aReason);
       
   322 		delete data;
       
   323 		}
       
   324 	}
       
   325 
       
   326 // -----------------------------------------------------------------------------
       
   327 // CSender::CompleteRequest
       
   328 // -----------------------------------------------------------------------------
       
   329 //
       
   330 void CSender::CompleteRequest (TRequestStatus* aStatus, TInt aReason)
       
   331 	{
       
   332 	if (aStatus != 0 && *aStatus == KRequestPending)
       
   333 		{
       
   334 		User::RequestComplete(aStatus,aReason);
       
   335 		}
       
   336 	}