--- /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);
+ }
+ }