hti/HtiServicePlugins/HtiIpProxyServicePlugin/IPProxyEngine/Src/CIPProxyEngine.cpp
branchRCL_3
changeset 59 8ad140f3dd41
--- /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