realtimenetprots/sipfw/SIP/ConnectionMgr/src/CReceiver.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/ConnectionMgr/src/CReceiver.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,239 @@
+// Copyright (c) 2006-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          : CReceiver.cpp
+// Part of       : ConnectionMgr
+// Version       : SIP/5.0
+//
+
+
+
+#include "CReceiver.h"
+#include "SipLogs.h"
+#include "CSipConnection.h"
+#include "CommonConsts.h"
+#include "MContext.h"
+#include "MSigCompController.h"
+#include "CSocketContainer.h"
+
+// -----------------------------------------------------------------------------
+// CReceiver::NewL
+// -----------------------------------------------------------------------------
+//
+CReceiver* CReceiver::NewL( MContext& aContext, TUint aIPAddrFamily )
+	{
+	CReceiver* self = NewLC( aContext, aIPAddrFamily );
+	CleanupStack::Pop( self );
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CReceiver::NewLC
+// -----------------------------------------------------------------------------
+//
+CReceiver* CReceiver::NewLC( MContext& aContext, TUint aIPAddrFamily )
+	{
+	CReceiver* self = new ( ELeave ) CReceiver( aContext, aIPAddrFamily );
+	CleanupStack::PushL( self );
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CReceiver::CReceiver
+// -----------------------------------------------------------------------------
+//
+CReceiver::CReceiver( MContext& aContext, TUint aIPAddrFamily ) : 
+    CActive( EPriorityStandard ), 
+    iContext( aContext ),
+    iIPAddrFamily( aIPAddrFamily ),
+    iState( EIdle ),
+    iReceivedMsgPtr( 0, 0, 0 )
+	{
+	CActiveScheduler::Add( this );
+	}
+
+// -----------------------------------------------------------------------------
+// CReceiver::~CReceiver
+// -----------------------------------------------------------------------------
+//
+CReceiver::~CReceiver()
+	{
+	Cancel();
+	delete iReceivedMsg;
+	}
+
+// -----------------------------------------------------------------------------
+// CReceiver::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CReceiver::DoCancel()
+	{
+	CSocketContainer* socketContainer = 
+	    iContext.SocketContainer( iIPAddrFamily );
+	if ( iState == EListening )
+	    {
+	    socketContainer->Socket().CancelIoctl();
+	    }
+	else
+        {
+        socketContainer->Socket().CancelRecv();
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CReceiver::Listen
+// -----------------------------------------------------------------------------
+//
+void CReceiver::Listen()
+	{
+	CSocketContainer* socketContainer = 
+	    iContext.SocketContainer( iIPAddrFamily );	
+	if ( socketContainer && !IsActive() )
+		{	
+		iState = EListening;
+		
+		iFlags() = KSockSelectRead | KSockSelectExcept;
+	    socketContainer->Socket().Ioctl( 
+	        KIOctlSelect, 
+	        iStatus, 
+	        &iFlags, 
+            KSOLSocket );	
+		SetActive();
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CReceiver::RunL
+// -----------------------------------------------------------------------------
+//
+void CReceiver::RunL()
+	{
+	switch ( iStatus.Int() )
+		{
+		case KErrNone:
+			{
+			if ( iState == EListening )
+			    {
+			    ReceivePendingL();
+			    }
+			else if ( iState == EReceiving )
+			    {
+    			__SIP_MESSAGE_LOG( "Connection Manager::ReceivedFromNetwork",
+    							   *iReceivedMsg )
+    			__SIP_DES8_LOG( "Received data via UDP", *iReceivedMsg )	
+    			// Give away ownership of the received message
+    			HBufC8* tmpReceivedMsg = iReceivedMsg;
+    			iReceivedMsg = 0; 
+    			
+    			Listen();
+    			ReceivedDataL( tmpReceivedMsg );
+			    }
+			else
+			    {
+			    // Required by PC-Lint
+			    }
+			break;
+			}
+		case KErrCancel:
+			break;
+		default:
+			{
+			__SIP_INT_LOG1( "CReceiver::RunL() status", iStatus.Int() )
+			iContext.Remove();
+			break;
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CReceiver::ReceivedDataL
+// -----------------------------------------------------------------------------
+//
+void CReceiver::ReceivedDataL( HBufC8* aData )
+	{
+	if ( iContext.SigCompHandler()->IsSupported() &&		
+		 iContext.SigCompHandler()->IsSigCompMsg( *aData ) )
+		{
+		__SIP_LOG( "IsSigComp complete == ETrue" )
+
+		CleanupStack::PushL( aData );
+		TUint bytesconsumed = 0;
+		CBufBase* decompressedmessage =				  
+			iContext.SigCompHandler()->DecompressL( *aData,
+													bytesconsumed,
+													EFalse );
+		CleanupStack::PopAndDestroy( aData );
+		CleanupStack::PushL( decompressedmessage );
+
+		HBufC8* receiveddata = HBufC8::NewL( decompressedmessage->Size() );
+		receiveddata->Des().Copy( decompressedmessage->Ptr( 0 ) );
+		CleanupStack::PopAndDestroy( decompressedmessage );
+
+		iContext.ReceivedDataL( receiveddata, iAddr, ETrue );
+		}
+	else
+		{
+		iContext.ReceivedDataL( aData, iAddr, EFalse );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CReceiver::ReceivePendingL
+// -----------------------------------------------------------------------------
+//	
+void CReceiver::ReceivePendingL()
+    {
+    __ASSERT_ALWAYS( !IsActive(), User::Leave( KErrInUse ) );
+    
+    CSocketContainer* socketContainer = 
+	    iContext.SocketContainer( iIPAddrFamily );
+    __ASSERT_ALWAYS( socketContainer, User::Leave( KErrNotFound ) );
+    
+    iState = EReceiving;
+			    
+	TInt bytesPending( 0 );
+	User::LeaveIfError( 
+	    socketContainer->Socket().GetOpt( 
+	        KSOReadBytesPending, 
+            KSOLSocket, 
+            bytesPending ) );
+
+    __SIP_INT_LOG1( "CReceiver::ReceivePendingL() bytes", bytesPending )
+
+	// Don't allow excessive buffer
+	if ( bytesPending > KMaxMessageLength )
+	    {
+	    bytesPending = KMaxMessageLength;
+	    }
+	    
+    delete iReceivedMsg;
+	iReceivedMsg = 0;
+	iReceivedMsg = HBufC8::NewL( bytesPending );
+	iReceivedMsgPtr.Set( iReceivedMsg->Des() );
+	socketContainer->Socket().RecvFrom( iReceivedMsgPtr, iAddr, 0, iStatus );     	
+	SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// CReceiver::RunError
+// -----------------------------------------------------------------------------
+//
+TInt CReceiver::RunError( TInt aError )
+	{
+	Listen();
+	if ( aError != KErrNoMemory )
+		{
+		return KErrNone;
+		}
+	return aError;
+	}