diff -r 7fdc9a71d314 -r 8ad140f3dd41 hti/HtiServicePlugins/HtiIpProxyServicePlugin/IPProxyEngine/Src/CIPProxyEngine.cpp --- /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 ( 10 ); + + // Local TCP connections array + iLocalConnArray = new (ELeave) CArrayPtrFlat ( 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