diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/ConnectionMgr/src/CSenderUdp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/ConnectionMgr/src/CSenderUdp.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,217 @@ +// Copyright (c) 2007-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 : CSenderUdp.cpp +// Part of : ConnectionMgr +// Version : SIP/5.1 +// + + + +#include "CSenderUdp.h" +#include "CommonConsts.h" +#include "SipLogs.h" +#include "SipAssert.h" +#include "siperr.h" +#include "TSIPTransportParams.h" +#include "sipmessage.h" +#include "CSocketContainer.h" +#include "COwnerSettingsList.h" + +// ----------------------------------------------------------------------------- +// CSenderUdp::NewL +// ----------------------------------------------------------------------------- +// +CSenderUdp* CSenderUdp::NewL( + MContext& aContext, + COwnerSettingsList& aSettingsList ) + { + CSenderUdp* self = NewLC( aContext, aSettingsList ); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CSenderUdp::NewLC +// ----------------------------------------------------------------------------- +// +CSenderUdp* CSenderUdp::NewLC( + MContext& aContext, + COwnerSettingsList& aSettingsList ) + { + CSenderUdp* self = new ( ELeave ) CSenderUdp( aContext, aSettingsList ); + CleanupStack::PushL( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CSenderUdp::CSenderUdp +// ----------------------------------------------------------------------------- +// +CSenderUdp::CSenderUdp( MContext& aContext, COwnerSettingsList& aSettingsList ) : + CSender( aContext, aSettingsList ), + iPermissionToSend( ETrue ) + { + } + +// ----------------------------------------------------------------------------- +// CSenderUdp::~CSenderUdp +// ----------------------------------------------------------------------------- +// +CSenderUdp::~CSenderUdp() + { + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CSenderUdp::SendL +// ----------------------------------------------------------------------------- +// +TBool CSenderUdp::SendL( const TSIPTransportParams& aTransportParams, + CSIPMessage& aMessage, + const TInetAddr& aAddr, + TUint aOrigTransport, + TRequestStatus& aStat, + TBool /*aStore*/, + TBool aForceUDP ) + { + COutgoingData* data = + COutgoingData::NewL( aTransportParams, aMessage, aAddr, + aOrigTransport, aStat, *iContext.SigCompHandler(), + aForceUDP ); + + if ( !IsActive() && iPermissionToSend ) + { + iList.AddFirst( *data ); + + TCleanupItem cleanupItem( CleanCurrentDataOnLeave, this ); + CleanupStack::PushL( cleanupItem ); + + EncodeAndSendL( EFalse ); + + CleanupStack::Pop( 1 ); // cleanupItem + } + else + { + iList.AddLast( *data ); + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CSenderUdp::SendL +// ----------------------------------------------------------------------------- +// +void CSenderUdp::SendL( COutgoingData* aData ) + { + iList.AddLast( *aData ); + SendNextL(); + } + +// ----------------------------------------------------------------------------- +// CSenderUdp::SendNextL +// ----------------------------------------------------------------------------- +// +void CSenderUdp::SendNextL() + { + if ( !IsActive() ) + { + if ( iPermissionToSend && !iList.IsEmpty() ) + { + EncodeAndSendL( ETrue ); + } + else + { + iContext.Sending( EFalse ); + } + } + } + +// ----------------------------------------------------------------------------- +// CSenderUdp::SetSendPermission +// ----------------------------------------------------------------------------- +// +void CSenderUdp::SetSendPermission( TBool aPermissionToSend ) + { + iPermissionToSend = aPermissionToSend; + } + +// ----------------------------------------------------------------------------- +// CSenderUdp::EncodeAndSendL +// ----------------------------------------------------------------------------- +// +void CSenderUdp::EncodeAndSendL( TBool aRemoveFromList ) + { + COutgoingData* data = CurrentData(); + + __SIP_ASSERT_LEAVE( data, KErrNotFound ); + + TBool sendData = ETrue; + TPtr8 pointer = data->EncodeL( EFalse ); + TInt encodedLen = pointer.Length(); + + if ( encodedLen > KMaxMessageLength && data->ForceUDP() ) + { + // Message is too large to be sent with UDP + User::Leave( KErrTooBig ); + } + + if ( (encodedLen < KMaxUdpMessageSize || + !data->Message().IsRequest() || + data->ForceUDP() || + data->OrigTransport() == KProtocolInetUdp) && + !data->Compressed() ) + { + iOutgoingMessage.Set( pointer ); + } + else if ( data->Compressed() && encodedLen < KMaxUdpMessageSize ) + { + iOutgoingMessage.Set( pointer ); + } + else + { + data->Sent(); + if ( aRemoveFromList ) + { + iList.Remove( *data ); + } + CleanupStack::PushL( data ); + iContext.ReRouteL( KProtocolInetTcp, data ); + CleanupStack::Pop( data ); + sendData = EFalse; + } + + if ( sendData ) + { + CSocketContainer* socketContainer( + iContext.SocketContainer( IpAddrType( data->Address() ) ) ); + __ASSERT_ALWAYS( socketContainer, User::Leave( KErrNotFound ) ); + __SIP_MESSAGE_LOG( "Connection Manager::SendToNetwork via UDP", + iOutgoingMessage ) + WriteToLog( iOutgoingMessage ); + + // Set socket options before sending, options will be cleared after + // send has completed. + iSettingsList.SetOpts( + data->TransportParams(), socketContainer->Socket() ); + + iContext.Sending( ETrue ); + socketContainer->Socket().SendTo( + iOutgoingMessage, + data->Address(), + 0, + iStatus ); + SetActive(); + } + }