diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/ConnectionMgr/src/CSender.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/ConnectionMgr/src/CSender.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,336 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Name : CSender.cpp +// Part of : ConnectionMgr +// Version : SIP/4.0 +// + + + +#include "CSender.h" +#include "SipLogs.h" +#include "CSocketContainer.h" +#include "siperr.h" +#include "COwnerSettingsList.h" + +// ----------------------------------------------------------------------------- +// CSender::CSender +// ----------------------------------------------------------------------------- +// +CSender::CSender(MContext& aContext,COwnerSettingsList& aSettingsList) : + CActive(CActive::EPriorityStandard), + iContext(aContext), + iSettingsList(aSettingsList), + iList(COutgoingData::iOffset), + iListIter(iList), + iContinueSending(EFalse) + { + CActiveScheduler::Add(this); + } + +// ----------------------------------------------------------------------------- +// CSender::~CSender +// ----------------------------------------------------------------------------- +// +CSender::~CSender() + { + CancelAllRequests( KErrSIPTransportFailure ); + } + +// ----------------------------------------------------------------------------- +// CSender::SendL +// ----------------------------------------------------------------------------- +// +void CSender::SendL ( + const TSIPTransportParams& /*aTransportParams*/, + CSIPMessage& /*aMessage*/, + TRequestStatus& /*aStat*/) + { + __ASSERT_DEBUG(EFalse, + User::Panic(_L("CSender baseclass is called"), + KErrGeneral)); + } + +// ----------------------------------------------------------------------------- +// CSender::SendL +// ----------------------------------------------------------------------------- +// +void CSender::SendL (COutgoingData* /*aData*/) + { + __ASSERT_DEBUG(EFalse, + User::Panic(_L("CSender baseclass is called"), + KErrGeneral)); + } + +// ----------------------------------------------------------------------------- +// CSender::StoredData +// ----------------------------------------------------------------------------- +// +COutgoingData* CSender::StoredData() + { + return 0; + } + +// ----------------------------------------------------------------------------- +// CSender::Data +// ----------------------------------------------------------------------------- +// +COutgoingData* CSender::Data() + { + return 0; + } + +// ----------------------------------------------------------------------------- +// CSender::FindAndCancel +// ----------------------------------------------------------------------------- +// +TBool CSender::FindAndCancel(TRequestStatus& aStat) + { + COutgoingData* currentData = CurrentData(); + + if (currentData && &aStat == currentData->Status()) + { + iContext.SocketContainer().CancelSend(); + iContext.Sending( EFalse ); + RemoveCurrentData( KErrSIPTransportFailure ); + return ETrue; + } + + if (!iList.IsEmpty()) + { + iListIter.SetToFirst(); + for(COutgoingData* data = iListIter; data; data = iListIter++) + { + if(&aStat == data->Status()) + { + CompleteRequest(data->Status(), KErrSIPTransportFailure ); + iList.Remove(*data); + delete data; + return ETrue; + } + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CSender::CancelAllRequests +// ----------------------------------------------------------------------------- +// +void CSender::CancelAllRequests (TInt aReason) + { + Cancel(); + RemoveCurrentData(aReason); + if (!iList.IsEmpty()) + { + COutgoingData* data = 0; + iListIter.SetToFirst(); + while ((data = iListIter++) != 0) + { + CompleteRequest(data->Status(),aReason); + iList.Remove(*data); + delete data; + } + } + } + +// ----------------------------------------------------------------------------- +// CSender::CurrentData +// ----------------------------------------------------------------------------- +// +COutgoingData* CSender::CurrentData() + { + COutgoingData* data( NULL ); + if ( !iList.IsEmpty() ) + { + data = iList.First(); + } + return data; + } + +// ----------------------------------------------------------------------------- +// CSender::IpAddressType +// ----------------------------------------------------------------------------- +// +TUint CSender::IpAddrType( const TInetAddr& aAddr ) + { + // TInetAddr::Family returns sometimes KAfInet6 for an IPv4 address. + // The way to make sure the address is IPv4 is to use TInetAddr::Address. + // This is because a real IPv6 cannot be represented with a TUint. + TUint type( KAFUnspec ); + if ( aAddr.Address() ) + { + type = KAfInet; + } + else + { + type = KAfInet6; + } + return type; + } + +// ----------------------------------------------------------------------------- +// CSender::CleanCurrentDataOnLeave +// ----------------------------------------------------------------------------- +// +void CSender::CleanCurrentDataOnLeave( TAny* aSelf ) + { + CSender* self = reinterpret_cast< CSender* >( aSelf ); + COutgoingData* data = self->CurrentData(); + if ( data ) + { + self->iList.Remove( *data ); + self->iContinueSending = EFalse; + delete data; + } + } + +// ----------------------------------------------------------------------------- +// CSender::WriteToLog +// ----------------------------------------------------------------------------- +// +#if (defined(_DEBUG) && defined(USE_SIP_LOGS)) +void CSender::WriteToLog( const TDesC8& aMessage ) + { + if ( CurrentData() ) + { + __SIP_ADDR_LOG( "Outgoing data to address", CurrentData()->Address() ) + } + __SIP_DES8_LOG( "Outgoing data", aMessage ) + } +#else +void CSender::WriteToLog( const TDesC8& /*aMessage*/ ) + { + } +#endif + + +// ----------------------------------------------------------------------------- +// CSender::RunL +// ----------------------------------------------------------------------------- +// +void CSender::RunL() + { + TInt status = iStatus.Int(); + + __SIP_INT_LOG1( "CSender::RunL status:", status ) + + TBool terminated( EFalse ); + + switch ( status ) + { + case KErrNone: + { + COutgoingData* data = CurrentData(); + if ( data ) + { + data->Sent(); + + CSocketContainer* socketContainer = + iContext.SocketContainer( IpAddrType( data->Address() ) ); + if ( socketContainer ) + { + // Clear socket options after sending has completed. + // Do only if it completed successfully as it might be + // unsafe to attempt setting options after socket failure. + iSettingsList.ClearOpts( + data->TransportParams(), + socketContainer->Socket() ); + } + } + if ( !iContinueSending ) + { + RemoveCurrentData( KErrNone ); + } + break; + } + case KErrCancel: + { + break; + } + case KErrDisconnected: + { + terminated = iContext.DisconnectedL(); + break; + } + default: // Rest of the errors + { + terminated = iContext.StopL(); + if ( !terminated ) + { + iContext.ResetSocketL(); + iContext.ContinueL(); + } + break; + } + } + + if ( !terminated ) + { + SendNextL(); + } + } + +// ----------------------------------------------------------------------------- +// CSender::RunError +// ----------------------------------------------------------------------------- +// +TInt CSender::RunError(TInt aError) + { + if(aError != KErrNoMemory) + { + return KErrNone; + } + return aError; + } + +// ----------------------------------------------------------------------------- +// CSender::DoCancel +// ----------------------------------------------------------------------------- +// +void CSender::DoCancel() + { + iContext.SocketContainer().CancelSend(); + iContext.Sending( EFalse ); + RemoveCurrentData( KErrSIPTransportFailure ); + } + +// ----------------------------------------------------------------------------- +// CSender::RemoveCurrentData +// ----------------------------------------------------------------------------- +// +void CSender::RemoveCurrentData(TInt aReason) + { + COutgoingData* data = CurrentData(); + if ( data ) + { + iList.Remove( *data ); + iContinueSending = EFalse; + CompleteRequest(data->Status(),aReason); + delete data; + } + } + +// ----------------------------------------------------------------------------- +// CSender::CompleteRequest +// ----------------------------------------------------------------------------- +// +void CSender::CompleteRequest (TRequestStatus* aStatus, TInt aReason) + { + if (aStatus != 0 && *aStatus == KRequestPending) + { + User::RequestComplete(aStatus,aReason); + } + }