wlanutilities/wlansniffer/wlansnifferkeepalive/src/wsfkeepalive.cpp
branchRCL_3
changeset 24 63be7eb3fc78
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlanutilities/wlansniffer/wlansnifferkeepalive/src/wsfkeepalive.cpp	Tue Aug 31 16:18:40 2010 +0300
@@ -0,0 +1,365 @@
+/*
+* Copyright (c) 2010 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:
+* Main implementation of Wlan Sniffer Keepalive application.
+*/
+
+// System include files
+
+#include <rconnmon.h>
+
+// User include files
+
+#include "wsfkeepalivetimer.h"
+#include "wsfkeepalivecmm.h"
+#include "wsfkeepaliveconnmon.h"
+#include "wsfkeepaliveconnmondisc.h"
+#include "wsfkeepaliveesock.h"
+#include "wsfkeepalive.h"
+#include "OstTraceDefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "wsfkeepaliveTraces.h"
+#endif
+
+// External function prototypes
+
+// Local constants
+
+// We need to poll for client info every 5 seconds
+static const int KKeepalivePollInterval = 5000000;
+
+// We can close a connection after 5 minutes of inactivity
+static const int KKeepaliveInactivityInterval = 300;
+
+// UID of Wlan sniffer application
+static const TUid KWlanSnifferUid = { 0x10281CAA };
+
+// UID of Wlan login application
+static const TUid KWlanloginUid = { 0x2002E6D0 };
+
+// List of UIDs of clients not considered as "real"
+static const TUid KDiscardedClientUids[] = 
+    {
+        { 0x2002FF5F }, // Sniffer keepalive process, that is, us
+        KWlanSnifferUid, // Sniffer application (wlansniffer.exe)
+        KWlanloginUid, //   Wlan Login application (wlanlogin.exe)
+        { 0x101fD9C5 }  // DHCP server (dhcpserv.exe)
+    };
+
+// ======== LOCAL FUNCTIONS ========
+
+// ======== MEMBER FUNCTIONS ========
+
+CWsfKeepalive* CWsfKeepalive::NewL()
+    {
+    OstTraceFunctionEntry0( CWSFKEEPALIVE_NEWL_ENTRY );
+    
+    CWsfKeepalive* me = new ( ELeave ) CWsfKeepalive();
+    CleanupStack::PushL( me );
+    me->ConstructL();
+    CleanupStack::Pop( me );
+    
+    OstTraceFunctionExit0( CWSFKEEPALIVE_NEWL_EXIT );
+    return me;
+    }
+
+CWsfKeepalive::~CWsfKeepalive()
+    {
+    OstTraceFunctionEntry0( DUP1_CWSFKEEPALIVE_CWSFKEEPALIVE_ENTRY );
+
+    delete iEsock;
+    delete iConnMonDisc;
+    delete iCmMgr;
+    delete iConnMon;
+    delete iTimer;
+    
+    OstTraceFunctionExit0( DUP1_CWSFKEEPALIVE_CWSFKEEPALIVE_EXIT );
+    }
+
+void CWsfKeepalive::TimerExpired( TInt aError )
+    {
+    OstTraceFunctionEntry0( CWSFKEEPALIVE_TIMEREXPIRED_ENTRY );
+
+    TBool restartTimer = ETrue; // Should we restart timer or not?
+    if ( aError == KErrNone )
+        {
+        // Timer successfully completed, handle it
+        if ( NoRealClients( iConnectionId ) )
+            {
+            TTime now;
+            now.UniversalTime();
+            
+            // Check whether we are moving from EActiveWithClients to
+            // EActiveNoClients
+            if ( iState == EActiveWithClients )
+                {
+                OstTrace0(
+                    TRACE_NORMAL,
+                    CWSFKEEPALIVE_TIMEREXPIRED_RESET,
+                    "CWsfKeepalive::TimerExpired Keepalive time reset" );
+        
+                // Connection had clients, but doesn't anymore. Keepalive
+                // inactivity time starts now
+                iKeepaliveStart = now;
+                }
+            // Check whether keepalive time has been reached
+            else if ( iKeepaliveStart +
+                TTimeIntervalSeconds( KKeepaliveInactivityInterval ) <= now )
+                {
+                OstTrace0(
+                    TRACE_NORMAL,
+                    CWSFKEEPALIVE_TIMEREXPIRED_DONE,
+                    "CWsfKeepalive::TimerExpired Keepalive time expired" );
+                
+                // Keepalive time limit expired, connection should be stopped
+                iEsock->Disconnect();
+                iConnMonDisc->Disconnect( iConnectionId );
+                restartTimer = EFalse;
+                }
+            
+            // There are now no real clients for the connection
+            SetState( EActiveNoClients );
+            }
+        else
+            {
+            // One or more real clients are using the connection
+            SetState( EActiveWithClients );
+            }
+        }
+    else
+        {
+        // Timer not successful, probably because we stopped it
+        restartTimer = EFalse;
+        }
+
+    if ( restartTimer )
+        {
+        TTimeIntervalMicroSeconds32 interval( KKeepalivePollInterval );
+        iTimer->After( interval );
+        }
+    
+    OstTraceFunctionExit0( CWSFKEEPALIVE_TIMEREXPIRED_EXIT );
+    }
+
+void CWsfKeepalive::WlanConnectionOpenedL( TUint aConnectionId, TUint aIapId )
+    {
+    OstTraceFunctionEntry0( CWSFKEEPALIVE_WLANCONNECTIONOPENEDL_ENTRY );
+    
+    OstTraceExt2(
+        TRACE_NORMAL,
+        CWSFKEEPALIVE_WLANCONNECTIONOPENED,
+        "CWsfKeepalive::WlanConnectionOpened;aConnectionId=%u;aIapId=%u",
+        aConnectionId,
+        aIapId );
+
+    // We are only interested in connections opened by the Wlan Sniffer
+    if ( OpenedByWlanSniffer( aConnectionId ) )
+        {
+        // Start to monitor this connection, and add us as a user to the
+        // connection
+        iConnectionId = aConnectionId;
+        iIapId = aIapId;
+        iEsock->ConnectL( aIapId );
+
+        // Assume there are no real clients yet. Setup timer for polling
+        // when real clients might be added to the connection
+        SetState( EActiveNoClients );
+        iKeepaliveStart.UniversalTime();
+        
+        OstTrace0(
+            TRACE_NORMAL,
+            CWSFKEEPALIVE_WLANCONNECTIONOPENED_RESET,
+            "CWsfKeepalive::WlanConnectionOpened Keepalive time reset" );
+        
+        TTimeIntervalMicroSeconds32 interval( KKeepalivePollInterval );
+        iTimer->After( interval );
+        }
+    
+    OstTraceFunctionExit0( CWSFKEEPALIVE_WLANCONNECTIONOPENEDL_EXIT );
+    }
+
+void CWsfKeepalive::WlanConnectionClosed()
+    {
+    OstTraceFunctionEntry0( CWSFKEEPALIVE_WLANCONNECTIONCLOSED_ENTRY );
+
+    // No need to monitor anything anymore
+    SetState( EInactive );
+    iConnectionId = KInvalidConnectionId;
+    // Stop also the polling timer
+    iTimer->Stop();
+    
+    OstTrace1(
+        TRACE_NORMAL,
+        CWSFKEEPALIVE_WLANCONNECTIONCLOSED_IAPID,
+        "CWsfKeepalive::WlanConnectionClosed iapId=%d",
+        iIapId );
+    
+    // If connected to hotspot IAP, the IAP must be deleted
+    if ( iCmMgr->GetHotspotInfoL( iIapId ) )
+        {
+        OstTrace0(
+            TRACE_NORMAL,
+            CWSFKEEPALIVE_WLANCONNECTIONCLOSED_HOTSPOTDETECTED,
+            "CWsfKeepalive::WlanConnectionClosed Hotspot IAP detected" );
+
+        if ( !iCmMgr->DeleteHotspotIapL( iIapId ) )
+            {
+            OstTrace0(
+                TRACE_NORMAL,
+                CWSFKEEPALIVE_WLANCONNECTIONCLOSED_HOTSPOTDELETEFAILED,
+                "CWsfKeepalive::WlanConnectionClosed Hotspot delete failed" );
+            }
+        iIapId = 0;
+        }
+    
+    OstTraceFunctionExit0( CWSFKEEPALIVE_WLANCONNECTIONCLOSED_EXIT );
+    }
+
+// ---------------------------------------------------------------------------
+// Default constructor
+// ---------------------------------------------------------------------------
+//
+CWsfKeepalive::CWsfKeepalive() :
+    iConnectionId( KInvalidConnectionId ),
+    iState( EInactive ),
+    iIapId( 0 )
+    {
+    OstTraceFunctionEntry0( CWSFKEEPALIVE_CWSFKEEPALIVE_ENTRY );
+    OstTraceFunctionExit0( CWSFKEEPALIVE_CWSFKEEPALIVE_EXIT );
+    }
+
+// ---------------------------------------------------------------------------
+// Leaving constructor
+// ---------------------------------------------------------------------------
+//
+void CWsfKeepalive::ConstructL()
+    {
+    OstTraceFunctionEntry0( CWSFKEEPALIVE_CONSTRUCTL_ENTRY );
+    
+    iTimer = CWsfKeepaliveTimer::NewL( *this );
+    iConnMon = CWsfKeepaliveConnMon::NewL( *this );
+    iConnMonDisc = CWsfKeepaliveConnMonDisc::NewL();
+    iEsock = CWsfKeepaliveEsock::NewL();
+    iCmMgr = CWsfKeepaliveCmm::NewL();
+    
+    OstTraceFunctionExit0( CWSFKEEPALIVE_CONSTRUCTL_EXIT );
+    }
+ 
+// ---------------------------------------------------------------------------
+// Checks whether the given connection was opened by the Wlan Sniffer
+// application
+// ---------------------------------------------------------------------------
+//
+TBool CWsfKeepalive::OpenedByWlanSniffer( TUint aConnectionId )
+    {
+    OstTraceFunctionEntry0( CWSFKEEPALIVE_OPENEDBYWLANSNIFFER_ENTRY );
+    
+    TBool retVal = EFalse;
+
+    // Get all clients of this connection
+    TConnMonClientEnumBuf clientInfo;
+    iConnMon->GetClientInfo( clientInfo, aConnectionId );
+
+    // Check whether Wlan sniffer is one of the clients
+    for ( TInt i( 0 ); i < clientInfo().iCount; ++i )
+        {
+        if ( clientInfo().iUid[i] == KWlanSnifferUid )
+            {
+            // Match found, stop looking
+            retVal = ETrue;
+            break;
+            }
+        }
+    
+    OstTraceExt2(
+        TRACE_NORMAL,
+        CWSFKEEPALIVE_OPENEDBYWLANSNIFFER,
+        "CWsfKeepalive::OpenedByWlanSniffer;aConnectionId=%u;retVal=%u",
+        aConnectionId,
+        retVal );
+    
+    OstTraceFunctionExit0( CWSFKEEPALIVE_OPENEDBYWLANSNIFFER_EXIT );
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// Checks whether there are any real clients using the given connection
+// ---------------------------------------------------------------------------
+//
+TBool CWsfKeepalive::NoRealClients( TUint aConnectionId )
+    {
+    OstTraceFunctionEntry0( CWSFKEEPALIVE_NOREALCLIENTS_ENTRY );
+    
+    // Get all clients of this connection
+    TConnMonClientEnumBuf clientInfo;
+    iConnMon->GetClientInfo( clientInfo, aConnectionId );
+
+    // Get the client count
+    TInt clientCount = clientInfo().iCount;
+
+    TInt discardedClientCount = sizeof( KDiscardedClientUids ) / sizeof( TUid );
+    
+    // Decrease count by each non-real client we must discard
+    for ( TInt i( 0 ); i < clientInfo().iCount; ++i )
+        {
+        for ( TInt j( 0 ); j < discardedClientCount; ++j )
+            {
+            if ( clientInfo().iUid[i] == KDiscardedClientUids[j] )
+                {
+                OstTrace1(
+                    TRACE_NORMAL,
+                    CWSFKEEPALIVE_NOREALCLIENTS_DISCARD,
+                    "CWsfKeepalive::NoRealClients Client discarded;clientInfo().iUid[i].iUid=%x",
+                    clientInfo().iUid[i].iUid );
+                --clientCount;
+                break;
+                }
+            }
+        }
+
+    // If we reached zero, there were no real clients
+    TBool retVal = clientCount == 0 ? ETrue : EFalse;
+    OstTraceExt2(
+        TRACE_NORMAL,
+        CWSFKEEPALIVE_NOREALCLIENTS,
+        "CWsfKeepalive::NoRealClients;aConnectionId=%u;retVal=%u",
+        aConnectionId,
+        retVal );
+    
+    OstTraceFunctionExit0( CWSFKEEPALIVE_NOREALCLIENTS_EXIT );
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// Sets the given state and traces the transition, if state changed.
+// ---------------------------------------------------------------------------
+//
+void CWsfKeepalive::SetState( TUint aState )
+    {
+    OstTraceFunctionEntry0( CWSFKEEPALIVE_SETSTATE_ENTRY );
+
+#ifdef OST_TRACE_COMPILER_IN_USE
+    if ( aState != iState )
+        {
+        OstTrace1(
+            TRACE_NORMAL,
+            CWSFKEEPALIVE_SETSTATE,
+            "CWsfKeepalive::SetState;aState=%{State}",
+            aState );
+        }
+#endif
+    iState = aState;
+    
+    OstTraceFunctionExit0( CWSFKEEPALIVE_SETSTATE_EXIT );
+    }