--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hti/HtiServicePlugins/HtiIpProxyServicePlugin/IPProxyEngine/Src/CIPProxyEngine.cpp Wed Oct 13 16:17:58 2010 +0300
@@ -0,0 +1,629 @@
+/*
+* Copyright (c) 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: Implementation of the main class for IPProxyEngine
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "CIPProxyEngine.h"
+#include "Ctcpportlistener.h"
+#include "CLocalTCPConnection.h"
+#include "Csocketrouter.h"
+#include "MIPProxyEngineObserver.h"
+#include "MHostConnection.h"
+#include "MAbstractConnection.h"
+
+#define DEBUG_FILENAME "IPProxyEngine.log"
+#include "DebugPrint.h"
+
+const TInt KPeerDisconnectDelay = 60000000; //60 seconds
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CleanupSocket RSocket pointer cleanup operation
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void CleanupSocket( TAny* aPtr )
+ {
+ RSocket* socket = ( RSocket* ) aPtr;
+ if ( socket )
+ {
+ socket->Close();
+ delete socket;
+ }
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::CIPProxyEngine
+// -----------------------------------------------------------------------------
+//
+CIPProxyEngine::CIPProxyEngine( MAbstractConnection* aConnection )
+ : CActive( EPriorityStandard ), iAbstractConnection( aConnection )
+ {
+ __ASSERT_DEBUG( iAbstractConnection, User::Invariant() );
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::ConstructL()
+ {
+ DEBUG_PRINT( DEBUG_STRING( "CSocketRouter::ConstructL()" ) );
+
+ User::LeaveIfError( iTimer.CreateLocal() );
+ User::LeaveIfError( iSocketServ.Connect() );
+
+ iHostConnection = iAbstractConnection->GetHostConnection();
+ __ASSERT_DEBUG( iHostConnection, User::Invariant() );
+ iHostConnection->SetObserver( this );
+
+ // Peer array. Granularity 10 suits fine.
+ iPeerListenerArray = new (ELeave) CArrayPtrFlat<CTCPPortListener> ( 10 );
+
+ // Local TCP connections array
+ iLocalConnArray = new (ELeave) CArrayPtrFlat<CLocalTCPConnection> ( 5 );
+
+ iSocketRouter = CSocketRouter::NewL( this );
+
+ CActiveScheduler::Add( this );
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::NewL
+// -----------------------------------------------------------------------------
+//
+CIPProxyEngine* CIPProxyEngine::NewL( MAbstractConnection* aConnection )
+ {
+ CIPProxyEngine* self = CIPProxyEngine::NewLC( aConnection );
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::NewLC
+// -----------------------------------------------------------------------------
+//
+CIPProxyEngine* CIPProxyEngine::NewLC( MAbstractConnection* aConnection )
+ {
+ CIPProxyEngine* self = new( ELeave ) CIPProxyEngine( aConnection );
+ CleanupStack::PushL( self );
+
+ self->ConstructL();
+ return self;
+ }
+
+
+// Destructor
+CIPProxyEngine::~CIPProxyEngine()
+ {
+ Cancel();
+ iTimer.Close();
+ delete iSocketRouter;
+
+ if ( iPeerListenerArray )
+ {
+ iPeerListenerArray->ResetAndDestroy();
+ delete iPeerListenerArray;
+ }
+ if ( iLocalConnArray )
+ {
+ iLocalConnArray->ResetAndDestroy();
+ delete iLocalConnArray;
+ }
+
+ iSocketServ.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::RunL
+// This is called when the timer expires
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::RunL()
+ {
+ DEBUG_PRINT( DEBUG_STRING( "CIPProxyEngine::RunL()" ) );
+ DEBUG_PRINT( DEBUG_STRING( " peer count = %d" ),
+ iSocketRouter->SocketCount() );
+
+ if ( iSocketRouter->SocketCount() == 0 )
+ {
+ iHostConnection->IssueDisconnect();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::DoCancel()
+ {
+ iTimer.Cancel();
+ DEBUG_PRINT( DEBUG_STRING( "Timeout timer cancelled" ) );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::SetObserver
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::SetObserver( MIPProxyEngineObserver* aObserver )
+ {
+ iObserver = aObserver;
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::AddPeerListeningPortL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::AddPeerListeningPortL( TInt aPort )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::AddPeerListeningPortL(%d)" ), aPort );
+
+ CTCPPortListener* newListener = CTCPPortListener::NewLC( aPort, this );
+ iPeerListenerArray->AppendL( newListener );
+ if ( iListening )
+ {
+ newListener->IssueListen();
+ }
+ CleanupStack::Pop( newListener );
+
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::AddPeerListeningPortL, Adding also UDP listener(%d)" ),
+ aPort );
+
+ // Adding also UDP listener for the port
+ iSocketRouter->AddUDPSocketL( aPort );
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::StartListening
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::StartListening()
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::StartListening()" ) );
+ TInt peerListenerArrayCount = iPeerListenerArray->Count();
+ for ( TInt i = 0; i < peerListenerArrayCount; i++ )
+ {
+ iPeerListenerArray->At( i )->IssueListen();
+ }
+ iListening = ETrue;
+
+ AssureConnectionL();
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::StopListening
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::StopListening()
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::StopListening()" ) );
+
+ TInt peerListenerArrayCount = iPeerListenerArray->Count();
+ for ( TInt i = 0; i < peerListenerArrayCount; i++ )
+ {
+ iPeerListenerArray->At( i )->Cancel();
+ }
+ iListening = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::DisconnectAllConnections
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::DisconnectAllConnections()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::ConnectionAcceptedL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::ConnectionAcceptedL( RSocket* aSocket )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::ConnectionAcceptedL()" ) );
+
+ Cancel(); //Possible timeout timer
+
+ CleanupStack::PushL( TCleanupItem( CleanupSocket, aSocket ) );
+ iSocketRouter->AddPeerSocketL( aSocket );
+ CleanupStack::Pop(); //aSocket
+
+ AssureConnectionL();
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::ErrorL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::ErrorL( TInt aErrorCode )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::ErrorL(%d)" ), aErrorCode );
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::ObserverLeaved
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::ObserverLeaved( TInt aLeaveCode )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::ObserverLeaved(%d)" ), aLeaveCode );
+ if ( iObserver )
+ {
+ iObserver->ObserverLeaved( aLeaveCode );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::ConnectionEstablishedL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::ConnectionEstablishedL()
+ {
+ // Connection to host established via bluetooth
+
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::ConnectionEstablishedL()" ) );
+
+ MSocket* socket = iAbstractConnection->GetSocket();
+ if ( socket )
+ {
+ iSocketRouter->SetHostSocketL( socket );
+ iSocketRouter->StartRouting();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::HostConnectionErrorL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::HostConnectionErrorL( TInt aErrorCode )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::HostConnectionErrorL(%d)" ), aErrorCode );
+ iHostConnection->IssueDisconnect();
+ iSocketRouter->RemoveAllPeers();
+ iSocketRouter->StopRouting();
+ iSocketRouter->ResetQueue();
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::HostConnectionObserverLeaved
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::HostConnectionObserverLeaved( TInt aLeaveCode )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::HostConnectionObserverLeaved(%d)" ), aLeaveCode );
+ if ( iObserver )
+ {
+ iObserver->ObserverLeaved( aLeaveCode );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::LocalTCPConnectionEstablishedL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::LocalTCPConnectionEstablishedL( TUint aPort )
+ {
+ // Connection to local host (via TCP connection) established.
+
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::LocalTCPConnectionEstablishedL(), port=%d" ), aPort );
+
+ // TCP connection that was initiated from the PC side, got connected
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::ConnectionEstablishedL() -\
+ Local conn. was connected, adding the socket to socket router" ) );
+
+ TInt connIndex = FindLocalTCPConn( aPort );
+ if ( connIndex >= 0 )
+ {
+ CLocalTCPConnection* conn = iLocalConnArray->At( connIndex );
+ iSocketRouter->AddPeerSocketL( conn->Socket() );
+ // Socket router took ownership of the socket
+ conn->SetSocketOwnership( EFalse );
+ // Connection was established,
+ conn->Cancel();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::LocalTCPConnectionErrorL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::LocalTCPConnectionErrorL( TInt aPort, TInt aErrorCode )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::LocalTCPConnectionErrorL(%d)" ), aErrorCode );
+
+ TInt connIndex = FindLocalTCPConn( aPort );
+ if ( connIndex >= 0 )
+ {
+ RSocket* localSocket = iLocalConnArray->At( connIndex )->Socket();
+ iSocketRouter->RemovePeerSocket( localSocket );
+ iLocalConnArray->Delete( connIndex );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::LocalTCPConnectionObserverLeaved
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::LocalTCPConnectionObserverLeaved( TInt aPort,
+ TInt aLeaveCode )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::HostConnectionObserverLeaved(%d), port%d" ),
+ aLeaveCode, aPort );
+ if ( iObserver )
+ {
+ iObserver->ObserverLeaved( aLeaveCode );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::SocketRouterErrorL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::SocketRouterErrorL(
+ const MSocket* /*aSocket*/, TInt aErrorCode )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::SocketRouterErrorL(%d)" ), aErrorCode );
+
+ if ( aErrorCode == -6305 ) //BT disconnected
+ {
+ iHostConnection->IssueDisconnect();
+ iSocketRouter->RemoveAllPeers();
+ iSocketRouter->StopRouting();
+ iSocketRouter->ResetQueue();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::ObserverLeaved
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::ObserverLeaved(
+ const MSocket* /*aSocket*/, TInt aLeaveCode )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::ObserverLeaved(%d)" ), aLeaveCode );
+ if ( iObserver )
+ {
+ iObserver->ObserverLeaved( aLeaveCode );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::PeerDisconnectedL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::PeerDisconnectedL( const MSocket* aSocket )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::PeerDisconnectedL(), localPort= %d. remotePort=%d" ),
+ aSocket->LocalPort(), aSocket->RemotePort() );
+
+ // Check if the socket was a local TCP connection socket
+ TInt indexOfConn = -1;
+ indexOfConn = FindLocalTCPConn( aSocket->RemotePort() );
+ if ( indexOfConn >= 0 )
+ {
+ // Notify PC side that the connection was disconnected
+ iSocketRouter->SendCloseTCPConnection( aSocket->RemotePort() );
+
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::PeerDisconnectedL(), Deleting local connection." ),
+ aSocket->LocalPort(), aSocket->RemotePort() );
+ iLocalConnArray->Delete( indexOfConn );
+ }
+
+ Cancel();
+ iTimer.After( iStatus, KPeerDisconnectDelay );
+ SetActive();
+ DEBUG_PRINT( DEBUG_STRING( "Timeout timer activated" ) );
+
+ if ( iSocketRouter->SocketCount() == 0 )
+ {
+ iSocketRouter->StopRouting();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::HostDisconnectedL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::HostDisconnectedL( const MSocket* /*aSocket*/ )
+ {
+ iHostConnection->IssueDisconnect();
+ if ( iSocketRouter->IsRouting() )
+ {
+ iSocketRouter->StopRouting();
+ }
+ iSocketRouter->ResetQueue();
+ iSocketRouter->RemoveAllPeers();
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::OpenLocalTCPConnectionL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::OpenLocalTCPConnectionL( TUint aPort )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::OpenLocalTCPConnectionL(), port=%d"), aPort );
+
+ CLocalTCPConnection* newConn =
+ CLocalTCPConnection::NewLC( this, aPort );
+
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::OpenLocalTCPConnectionL(), Issuing connection") );
+ iLocalConnArray->AppendL( newConn );
+ CleanupStack::Pop( newConn );
+
+ newConn->IssueConnectL();
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::OpenListeningTCPConnectionL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::OpenListeningTCPConnectionL( TUint aPort )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::OpenListeningTCPConnectionL(), port=%d"), aPort );
+
+ TInt count = iPeerListenerArray->Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iPeerListenerArray->At( i )->Port() == aPort )
+ {
+ // Port already listening
+ return;
+ }
+ }
+
+ // AddPeerListeningPortL will call IssueListen() only if iListening is set
+ // to ETrue
+ iListening = ETrue;
+ AddPeerListeningPortL( aPort );
+ AssureConnectionL();
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::CloseTCPConnection
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::CloseTCPConnection( TUint aPort )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::CloseTCPConnection(), port=%d"), aPort );
+
+ // Delete local TCP connections
+ TInt index = FindLocalTCPConn( aPort );
+ if ( index > -1 )
+ {
+ CLocalTCPConnection* conn = iLocalConnArray->At( index );
+ iLocalConnArray->Delete( index );
+ delete conn;
+
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::CloseTCPConnection(), conn deleted.") );
+ }
+
+ // stop listening on this port
+ TInt peerListenerArrayCount = iPeerListenerArray->Count();
+ for ( TInt i = 0; i < peerListenerArrayCount; i++ )
+ {
+ CTCPPortListener* listener = iPeerListenerArray->At( i );
+ if(listener->Port() == aPort)
+ {
+ listener->Cancel();
+ iPeerListenerArray->Delete(i);
+ delete listener;
+ break;
+ }
+ }
+
+ if(iPeerListenerArray->Count() == 0)
+ {
+ iListening = EFalse;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::CloseAllTCPConnections
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::CloseAllTCPConnections()
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::CloseAllTCPConnections()" ) );
+
+ iSocketRouter->ResetQueue();
+ iSocketRouter->RemoveAllPeers();
+
+ iLocalConnArray->ResetAndDestroy();
+
+ StopListening();
+
+ if ( iPeerListenerArray )
+ {
+ iPeerListenerArray->ResetAndDestroy();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::FindLocalTCPConn
+// -----------------------------------------------------------------------------
+//
+TInt CIPProxyEngine::FindLocalTCPConn( TUint aPort )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "CIPProxyEngine::FindLocalTCPConn(), port=%d"), aPort );
+ for ( TInt i = 0; i < iLocalConnArray->Count(); i++ )
+ {
+ if ( iLocalConnArray->At(i)->Port() == aPort )
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+// -----------------------------------------------------------------------------
+// CIPProxyEngine::AssureConnectionL
+// -----------------------------------------------------------------------------
+//
+void CIPProxyEngine::AssureConnectionL()
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "AssureConnectionL()" ) );
+ if ( iHostConnection->IsConnected() )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "AssureConnectionL, connected" ) );
+ if ( !iSocketRouter->IsRouting() )
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "AssureConnectionL, starting routing" ) );
+ iSocketRouter->StartRouting();
+ }
+ }
+ else
+ {
+ DEBUG_PRINT( DEBUG_STRING(
+ "AssureConnectionL, not connected, connecting" ) );
+ iHostConnection->IssueConnectL();
+ }
+ }
+// End of File