connectionmonitoring/connmon/connectionmonitor/src/ConnMonIAP.cpp
changeset 0 5a93021fdf25
child 8 2e6c4614c58e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/connectionmonitoring/connmon/connectionmonitor/src/ConnMonIAP.cpp	Thu Dec 17 08:55:21 2009 +0200
@@ -0,0 +1,5031 @@
+/*
+* Copyright (c) 2002-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:  Core functionality for ConnMon.
+*
+*/
+
+#include <mmtsy_names.h>
+#include <featmgr.h>
+#include <rmmcustomapi.h>
+#include <utf.h>
+#include <es_sock_partner.h>
+
+#include "ConnMonServ.h"
+#include "ConnMonSess.h"
+#include "CEventQueue.h"
+#include "CCsdFax.h"
+#include "CPsdFax.h"
+#include "ConnMonIAP.h"
+#include "ConnMonNoti.h"
+#include "CDataVolume.h"
+#include "connmondtmnoti.h"
+#include "connmontelnoti.h"
+#include "ConnMonBearerNotifier.h"
+#include "log.h"
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TConnInfo::TConnInfo
+// -----------------------------------------------------------------------------
+//
+TConnInfo::TConnInfo(
+        TInt aIapId,
+        TInt aNetId,
+        TUint aConnectionId,
+        TInt aBearer,
+        TBearerInfo aBearerInfo )
+        :
+        iIapId( aIapId ),
+        iNetId( aNetId ),
+        iConnectionId( aConnectionId ),
+        iBearer( aBearer ),
+        iConnAttach( 0 ),
+        iProgressNotifier( 0 ),
+        iDLDataNotifier( 0 ),
+        iULDataNotifier( 0 ),
+        iDataVolumeAO( 0 ),
+        iConnDownNotifier( 0 ),
+        iActivityNotifier( 0 ),
+        iActivity( 0 ),
+        iBearerInfo( aBearerInfo ),
+        iBearerNotifier( 0 )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// TConnInfo::Reset
+// -----------------------------------------------------------------------------
+//
+void TConnInfo::Reset()
+    {
+    // Only call this function to initialize a newly created TConnInfo-object.
+    // (There is no cleanup)
+    iIapId            = 0;
+    iNetId            = 0;
+    iConnectionId     = 0;
+    iBearer           = EBearerUnknown;
+    iBearerInfo.iBearer = EBearerInfoUnknown;
+    iBearerInfo.iInternal = ETrue;
+    iProgressNotifier = 0;
+    iDLDataNotifier   = 0;
+    iULDataNotifier   = 0;
+    iDataVolumeAO     = 0;
+    iConnAttach       = 0;
+    iConnDownNotifier = 0;
+    iActivityNotifier = 0;
+    iActivity         = 0;
+    iBearerNotifier   = 0;
+    }
+
+// -----------------------------------------------------------------------------
+// TConnInfo::Compare
+// Compares two TConnInfo items (by connection id).
+// -----------------------------------------------------------------------------
+//
+TInt TConnInfo::Compare( const TConnInfo& aFirst, const TConnInfo& aSecond )
+    {
+    if ( aFirst.iConnectionId < aSecond.iConnectionId )
+        {
+        return -1;
+        }
+
+    if ( aFirst.iConnectionId > aSecond.iConnectionId )
+        {
+        return 1;
+        }
+    return 0;
+    }
+
+// -----------------------------------------------------------------------------
+// TConnInfo::MatchId
+// Finds TConnInfo item matching by connection Id.
+// -----------------------------------------------------------------------------
+//
+TBool TConnInfo::MatchId( const TConnInfo& aFirst, const TConnInfo& aSecond )
+    {
+    if ( aFirst.iConnectionId == aSecond.iConnectionId )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// TConnInfo::MatchIap
+// Finds TConnInfo item matching by iap id and net id.
+// -----------------------------------------------------------------------------
+//
+TBool TConnInfo::MatchIap( const TConnInfo& aFirst, const TConnInfo& aSecond )
+    {
+    // Only internal bearers can be matched by IapId and NetId
+    if ( ( aFirst.iIapId == aSecond.iIapId ) && ( aFirst.iNetId == aSecond.iNetId ) &&
+         ( aFirst.iBearer < EBearerExternalCSD ) && ( aSecond.iBearer < EBearerExternalCSD ) &&
+         ( aFirst.iBearerInfo.iInternal ) && ( aSecond.iBearerInfo.iInternal ) )
+        {
+        return ETrue;
+        }
+
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// TConnInfo::MatchBearer
+// Finds TConnInfo item matching by bearer.
+// -----------------------------------------------------------------------------
+//
+TBool TConnInfo::MatchBearer( const TConnInfo& aFirst, const TConnInfo& aSecond )
+    {
+    // External CSD bearers (there is no event availabe for bearer change)
+    if ( ( aFirst.iBearer == EBearerExternalCSD || aFirst.iBearer == EBearerExternalHSCSD ||
+           aFirst.iBearer == EBearerExternalWcdmaCSD )
+         &&
+         ( aSecond.iBearer == EBearerExternalCSD || aSecond.iBearer == EBearerExternalHSCSD ||
+           aSecond.iBearer == EBearerExternalWcdmaCSD ) )
+        {
+        return ETrue;
+        }
+
+    // External PSD bearers (there is not always an event availabe for bearer change)
+    else if ( ( aFirst.iBearer == EBearerExternalGPRS     ||
+                aFirst.iBearer == EBearerExternalEdgeGPRS ||
+                aFirst.iBearer == EBearerExternalWCDMA    ||
+                aFirst.iBearer == EBearerExternalCDMA2000 ||
+                ( !aFirst.iBearerInfo.iInternal &&
+                  ( aFirst.iBearerInfo.iBearer == EBearerInfoHSDPA ||
+                    aFirst.iBearerInfo.iBearer == EBearerInfoHSUPA ||
+                    aFirst.iBearerInfo.iBearer == EBearerInfoHSxPA ) ) )
+              &&
+              ( aSecond.iBearer == EBearerExternalGPRS     ||
+                aSecond.iBearer == EBearerExternalEdgeGPRS ||
+                aSecond.iBearer == EBearerExternalWCDMA    ||
+                aSecond.iBearer == EBearerExternalCDMA2000 ||
+                ( !aSecond.iBearerInfo.iInternal &&
+                  ( aSecond.iBearerInfo.iBearer == EBearerInfoHSDPA ||
+                    aSecond.iBearerInfo.iBearer == EBearerInfoHSUPA ||
+                    aSecond.iBearerInfo.iBearer == EBearerInfoHSxPA ) ) ) )
+
+        {
+        return ETrue;
+        }
+
+    // Other bearers
+    else if ( aFirst.iBearer == aSecond.iBearer &&
+            aFirst.iBearerInfo.iBearer == aSecond.iBearerInfo.iBearer )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::CConnMonIAP
+// -----------------------------------------------------------------------------
+//
+CConnMonIAP::CConnMonIAP( CConnMonServer* aServer )
+        :
+        iServer( aServer ),
+        iEndUserNetIds( KNullDesC8 )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CConnMonIAP::ConstructL()
+    {
+    LOGENTRFN("CConnMonIAP::ConstructL()")
+    TInt err( KErrNone );
+
+    // Connect to socket server and use system global pool (-1) for message slots.
+    User::LeaveIfError( iSocketServer.Connect( static_cast<TUint>( -1 ) ) );
+    LOGIT("(01/11) Loaded OK: ESock")
+
+    // Open RConnection. This object is not attached to any connection
+    User::LeaveIfError( iConnection.Open( iSocketServer ) );
+    LOGIT("(02/11) Opened OK: RConnection")
+
+    // Connect to ETel server
+    TBuf<KCommsDbSvrMaxColumnNameLength> tsyName;
+    tsyName.Copy( KMmTsyModuleName );
+
+    // The RTelServer::Connect() might not always work with the first trial,
+    // because of a coding error related to using semaphores in the method.
+    for ( TInt a = 0; a < KPhoneRetryCount; a++ )
+        {
+        err = iTelServer.Connect();
+        if ( KErrNone == err )
+            {
+            break;
+            }
+        User::After( KPhoneRetryTimeout );
+        LOGIT("RTelServer::Connect() failed, trying again.")
+        }
+    User::LeaveIfError( err );
+    LOGIT("(03/11) Loaded OK: ETel")
+
+    // Initialize FeatureManager
+    FeatureManager::InitializeLibL();
+    LOGIT("(04/11) Loaded OK: FeatureManager")
+
+    // Try to load tsy
+    err = iTelServer.LoadPhoneModule( tsyName );
+    if ( KErrNone == err )
+        {
+        LOGIT("(05/11) Loaded OK: TSY")
+        iTSYLoaded = 1;
+
+        // Phone info can be retrieved with value 0 if there is only one phone
+        RTelServer::TPhoneInfo info;
+        User::LeaveIfError( iTelServer.GetPhoneInfo( 0, info ) );
+        LOGIT("(06/11) Loaded OK: Phone info")
+
+        User::LeaveIfError( iMobilePhone.Open( iTelServer, info.iName ) );
+        LOGIT("(07/11) Opened OK: RMobilePhone")
+
+        // Open packet service
+        err = iPacketService.Open( iMobilePhone );
+        if ( KErrNone == err )
+            {
+            LOGIT("(08/11) Loaded OK: Packet service")
+            iPacketServLoaded = 1;
+
+            // CDMA network does not support external connections. PSD Fax handler module
+            // should not be created when in CDMA network. The code below works OK as long
+            // as there is no phone that supports both CDMA and GSM at the same time.
+            if ( !FeatureManager::FeatureSupported( KFeatureIdProtocolCdma ) )
+                {
+                // Create PSD Fax handler module
+                iPsdFax = new( ELeave ) CPsdFax(
+                        iServer,
+                        &iTelServer,
+                        &iMobilePhone,
+                        &iPacketService );
+                iPsdFax->ConstructL();
+                LOGIT("(09/11) Loaded OK: PSD module")
+                }
+            else
+                {
+                LOGIT("(09/11) Nosupport: PSD module not loaded, no PSD support in CDMA networks.")
+                }
+            }
+        else
+            {
+            LOGIT1("(08/11) Loaderror: Packet service failed with code <%d>", err)
+            }
+
+        // CDMA network does not support external connections. CSD Fax handler module
+        // should not be created when in CDMA network. The code below works OK as long
+        // as there is no phone that supports both CDMA and GSM at the same time.
+        if ( !FeatureManager::FeatureSupported( KFeatureIdProtocolCdma ) )
+            {
+            // Create CSD Fax handler module
+            iCsdFax = new( ELeave ) CCsdFax( iServer, &iTelServer, &iMobilePhone );
+            iCsdFax->ConstructL();
+            LOGIT("(10/11) Loaded OK: CSD module")
+            }
+        else
+            {
+            LOGIT("(10/11) Nosupport: CSD module not loaded, no CSD support in CDMA networks")
+            }
+        }
+    else
+        {
+        LOGIT1("(05/11) Loaderror: TSY failed with code <%d>", err)
+        }
+
+    // Open WLAN Management service
+    if ( FeatureManager::FeatureSupported( KFeatureIdProtocolWlan ) )
+        {
+        TRAPD( leaveCode, iWlanSupport = CWlanSupport::NewL( iServer ) );
+        if ( KErrNone != leaveCode )
+            {
+            LOGIT1("(11/11) Loaderror: WLAN module failed with code <%d>", leaveCode)
+            }
+        else
+            {
+            LOGIT("(11/11) Loaded OK: WLAN module")
+            }
+        }
+    else
+        {
+        LOGIT("(11/11) Nosupport: WLAN module not loaded, no WLAN support detected")
+        }
+
+    LOGEXITFN("CConnMonIAP::ConstructL()")
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::~CConnMonIAP
+// -----------------------------------------------------------------------------
+//
+// Destructor
+CConnMonIAP::~CConnMonIAP()
+    {
+    LOGENTRFN("CConnMonIAP::~CConnMonIAP()")
+    // Delele dial up modules.
+    delete iCsdFax;
+    iCsdFax = NULL;
+
+    delete iPsdFax;
+    iPsdFax = NULL;
+
+    // Delete global notifications. This must be called before
+    // services are closed or destroyed below.
+    DeleteNotifications();
+
+    // Delete connection up/down notification.
+    if ( iConnUpDownNotifier != 0 )
+        {
+        iConnUpDownNotifier->Cancel();
+        delete iConnUpDownNotifier;
+        }
+
+    // Close all attached connections
+    TInt count = iConnInfos.Count();
+
+    for ( TInt i = 0; i < count; i++ )
+        {
+        if ( iConnInfos[i].iConnAttach != 0 )
+            {
+            iConnInfos[i].iConnAttach->Close();
+            delete iConnInfos[i].iConnAttach;
+            }
+        }
+
+    // Note. all sessions have closed by now.
+    // There is no need to delete connection parameters
+    // because session destructors have already done that.
+    iConnInfos.Close();
+
+    // Close "global" ESOCK objects
+    iConnection.Close();
+    iSocketServer.Close();
+
+    // Close "global" ETEL objects
+    if ( iPacketServLoaded == 1 )
+        {
+        iPacketService.Close();
+        }
+
+    iMobilePhone.Close();
+    iTelServer.Close();
+
+    // Unload FeatureManager
+    FeatureManager::UnInitializeLib();
+
+    // Destroy WLAN service
+    delete iWlanSupport;
+    iWlanSupport = NULL;
+
+    // Reset global pointers
+    iServer                        = NULL;
+    iPsdNetwStatusNotifier         = NULL;
+    iNetwRegistrationNotifier      = NULL;
+    iEdgeNotifier                  = NULL;
+    iWcdmaNotifier                 = NULL;
+    iModeNotifier                  = NULL;
+    iGSMSignalNotifier             = NULL;
+    iGSMBearerAvailabilityNotifier = NULL;
+
+    // Clean up all ECom sessions
+    // More info about it: TSW EGUO-64LD36
+    REComSession::FinalClose();
+    LOGEXITFN("CConnMonIAP::~CConnMonIAP()")
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::EnumerateConnections
+// Enumerates active connections using RConnection API.
+// Refreshes iConnInfos array (server view) with the latest information.
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::EnumerateConnections( TUint& aCount )
+    {
+    // Server must be 'blocked' while updating the connection table.
+    TConnectionInfoBuf connInfoBuf;
+    TBearerInfo bearerInfo;
+    TConnInfo connInfo( 0, 0, 0, 0, bearerInfo );
+    TInt err( KErrNone );
+
+    aCount = 0;
+    RArray<TConnInfo> tempArray;
+
+    // Get existing external (fax) CSD connections
+    // These can't be enumerated from ETEL at the moment
+    if ( iCsdFax )
+        {
+        // In practise there can be only ONE fax connection of this type
+        connInfo.Reset();
+        connInfo.iBearer = EBearerExternalCSD; // This will match any ext-CSD
+        connInfo.iBearerInfo.iBearer = EBearerInfoCSD;
+        connInfo.iBearerInfo.iInternal = EFalse;
+
+        TInt index = iConnInfos.Find( connInfo, TConnInfo::MatchBearer );
+        if ( ( KErrNotFound != index ) && iCsdFax->IsValid() )
+            {
+            // Add to temp array
+            tempArray.Append( iConnInfos[index] );
+            aCount++;
+            }
+        else if ( !iConnUpDownNotifier )
+            {
+            // Try to find out about external CSD connections
+            // that were alive before CM server started.
+            // The code below will be executed only when
+            // this method is called for the first time.
+            err = iCsdFax->FindCall();
+            if ( KErrNone == err )
+                {
+                iCsdFax->GetBearer( connInfo.iBearer, connInfo.iBearerInfo );
+                connInfo.iConnectionId = NewConnectionId(); // New unique Id
+                iCsdFax->SetConnectionId( connInfo.iConnectionId );
+                tempArray.Append( connInfo );
+                aCount++;
+                }
+            }
+        }
+
+    // Get existing external (fax) PSD connections
+    // These connections can't be enumerated from ETEL at the moment
+    // Only notification of a new connection is available from ETEL.
+    if ( iPsdFax )
+        {
+        connInfo.Reset();
+        connInfo.iBearer = EBearerExternalGPRS; // This will match any ext-PSD
+        connInfo.iBearerInfo.iBearer = EBearerInfoGPRS;
+        connInfo.iBearerInfo.iInternal = EFalse;
+
+        // Check all external PSD connections
+        for ( TUint index = 0; index < iConnInfos.Count(); index++ )
+            {
+            // Check that connection bearer is external PSD
+            if ( iConnInfos[index].iBearer == EBearerExternalGPRS       ||
+                 iConnInfos[index].iBearer == EBearerExternalEdgeGPRS   ||
+                 iConnInfos[index].iBearer == EBearerExternalWCDMA      ||
+                 iConnInfos[index].iBearer == EBearerExternalCDMA2000   ||
+                 ( !iConnInfos[index].iBearerInfo.iInternal &&
+                   ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA ||
+                     iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA ||
+                     iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) )
+                {
+                // Check if connection is still valid
+                if ( iPsdFax->IsValid( iConnInfos[index].iConnectionId ) )
+                    {
+                    // Add to temp array
+                    tempArray.Append( iConnInfos[index] );
+                    aCount++;
+                    }
+                }
+            }
+
+        if ( !iConnUpDownNotifier )
+            {
+            for( TUint index = 0; index < KMaxPsdConnectionCount; index++ )
+                {
+                // Try to find out about external PSD connections
+                // that were alive before CM server started.
+                // The code below will be executed only when
+                // this method is called for the first time.
+                TBuf<KMaxName> tempName( KExternalName );
+
+                // Add connection number to string if index is > 1
+                if ( index > 0 )
+                    {
+                    tempName.AppendNum( index+1 );
+                    }
+
+                // Try to open connection context
+                err = iPsdFax->OpenContext( index, tempName );
+                if ( KErrNone == err )
+                    {
+                    iPsdFax->GetBearer( connInfo.iBearer, connInfo.iBearerInfo );
+                    connInfo.iConnectionId = NewConnectionId(); // New unique Id
+                    err = iPsdFax->SetConnectionId( index, connInfo.iConnectionId );
+                    if ( KErrNone == err )
+                        {
+                        tempArray.Append( connInfo );
+                        aCount++;
+                        }
+                    }
+                }
+            }
+        }
+
+    const TUint initialCount = iConnInfos.Count();
+    __ASSERT_DEBUG( ( aCount == static_cast<TUint>( tempArray.Count() ) ),
+            PanicServer( EIapArrayError ) );
+
+    TUint k( 0 );
+    // Remove resources owned by obsolete connections
+    for ( k = 0; k < initialCount; k++ )
+        {
+        TInt index( KErrNotFound );
+
+        if ( iConnInfos[k].iBearer < EBearerExternalCSD )
+            {
+            index = tempArray.Find( iConnInfos[k], TConnInfo::MatchIap ); // Internal
+            }
+        else
+            {
+            index = tempArray.Find( iConnInfos[k], TConnInfo::MatchBearer ); // External
+            }
+
+        if ( KErrNotFound == index )
+            {
+            TBool deleteSent( ETrue );
+
+            if ( iConnInfos[k].iConnDownNotifier != 0 )
+                {
+                deleteSent = iConnInfos[k].iConnDownNotifier->DeleteSent();
+                }
+
+            TInt connStatus( 0 );
+            TInt ret = GetConnectionStatus( k, connStatus );
+
+            if ( ( ( KErrNone != ret ) || ( connStatus == 0 ) ) && deleteSent )
+                {
+                LOGIT3("Removing old connection, index %d, id %d, bearer %d",
+                        k, iConnInfos[k].iConnectionId, iConnInfos[k].iBearer)
+                iServer->RemoveConnSettingsFromSessions( iConnInfos[k].iConnectionId );
+                DeleteConnNotifications( k );
+
+                // Close attached connection
+                if ( iConnInfos[k].iConnAttach != 0 )
+                    {
+                    iConnInfos[k].iConnAttach->Close();
+                    delete iConnInfos[k].iConnAttach;
+                    }
+                }
+            else
+                {
+                // Add connection to temp array because connection status is valid.
+                tempArray.Append( iConnInfos[k] );
+                aCount++;
+                }
+            }
+        }
+
+    // Replace old iConnInfos array with tempArray
+    // Reserve enough room
+    for ( TUint i = initialCount; i < aCount; i++ )
+        {
+        TInt error = iConnInfos.Append( tempArray[0] );
+        if ( error )
+            {
+            // Rollback reserved entries
+            for ( TUint j = i; j > initialCount; j-- )
+                {
+                iConnInfos.Remove( j-1 );
+                }
+            tempArray.Reset();
+            tempArray.Close();
+            return error;
+            }
+        }
+
+    // Safe from leaves from here. Copy over new contents
+    iConnInfos.Reset();
+    for ( k = 0; k < aCount; k++ )
+        {
+        iConnInfos.Append( tempArray[k] );
+        }
+
+    // Print connection info array to log
+    #ifdef _DEBUG
+    LOGIT("EnumerateConnections: Connection info array:")
+    for ( TInt m = 0; m < iConnInfos.Count(); m++ )
+        {
+        LOGIT4("    id %d, bearer %d, iapId %d, netId %d", iConnInfos[m].iConnectionId,
+                iConnInfos[m].iBearer, iConnInfos[m].iIapId, iConnInfos[m].iNetId)
+        }
+    #endif // _DEBUG
+
+    tempArray.Reset();
+    tempArray.Close();
+
+    err = KErrNone;
+    // Start connection up/down notifier if not already running
+    if ( !iConnUpDownNotifier )
+        {
+        // Leave left out intentionally, check for NULL instead
+        iConnUpDownNotifier = new CConnUpDownNotifier( iServer ); // No (ELeave)
+        if ( !iConnUpDownNotifier )
+            {
+            err = KErrNoMemory;
+            }
+        else
+            {
+            iConnUpDownNotifier->Construct();
+            }
+        }
+    if ( KErrNone == err )
+        {
+        if ( !iConnUpDownNotifier->IsActive() )
+            {
+            iConnUpDownNotifier->Receive(); // (re)start listening
+            }
+        // Add event watchers for the new connections. Old connections already have
+        // notifications on and AddConnNotificationsL() will only restart the event
+        // watchers if they have stopped (because of an error situation).
+        if ( iCountListeners > 0 )
+            {
+            TRAP( err,
+                    {
+                    for ( k = 0; k < aCount; k++ )
+                        {
+                        AddConnNotificationsL( k );
+                        }
+                    } );
+            }
+        }
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::EnumerateConnectionsL
+// Enumerates active connections using RConnection API.
+// Refreshes iConnInfos array (server view) with the latest information.
+// Fills aEnumInfo array (client view) with the newly enumerated connection ids.
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::EnumerateConnectionsL( TUint& aCount, CArrayFixFlat<TUint>& aEnumInfo )
+    {
+    LOGENTRFN("CConnMonIAP::EnumerateConnectionsL()")
+    TInt err( KErrNone );
+
+    err = EnumerateConnections( aCount );
+    if ( KErrNone == err )
+        {
+        // Fill in table (connection ids) owned by the session
+        // Client needs this table when querying connection info index by index.
+        aEnumInfo.Reset();
+
+        if ( aCount > 0 )
+            {
+            for ( TUint k = 0; k < aCount; k++ )
+                {
+                // Sometimes there is a delay after the DELETE event has arrived and
+                // before the closed connection is removed from Esock. Hide these closing
+                // connections from clients.
+                TBool deleteSent( EFalse );
+
+                if ( iConnInfos[k].iConnDownNotifier != 0 )
+                    {
+                    deleteSent = iConnInfos[k].iConnDownNotifier->DeleteSent();
+                    }
+
+                if ( !deleteSent )
+                    {
+                    aEnumInfo.AppendL( iConnInfos[k].iConnectionId );
+                    }
+                }
+            aCount = aEnumInfo.Count();
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::EnumerateConnectionsL()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::ConnectionExists
+// Checks if given connection id is valid
+// -----------------------------------------------------------------------------
+//
+TBool CConnMonIAP::ConnectionExists( const TUint& aConnectionId )
+    {
+    LOGENTRFN("CConnMonIAP::ConnectionExists()")
+    TBool res( EFalse );
+
+    if ( aConnectionId == 0 || aConnectionId >= KMaxConnectionId )
+        {
+        res = EFalse;
+        }
+    else
+        {
+        TInt index = Index( aConnectionId );
+        if ( index < 0 )
+            {
+            res = EFalse;
+            }
+        else
+            {
+            res = ETrue;
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::ConnectionExists()", res)
+    return res;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetConnectionInfo
+// Returns the number of subconnections in aSubConnectionCount
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetConnectionInfo(
+        const TUint& aConnectionId,
+        TUint& aSubConnectionCount )
+    {
+    LOGENTRFN("CConnMonIAP::GetConnectionInfo()")
+    TInt err( KErrNone );
+
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+    if ( index < 0  )
+        {
+        err = KErrNotFound;
+        }
+    else
+        {
+        // Get the number of subconnections
+        if ( iConnInfos[index].iBearer < EBearerExternalCSD )
+            {
+            // Internal connections
+            aSubConnectionCount = 1;
+            err = iConnInfos[index].iConnAttach->EnumerateSubConnections(
+                    aSubConnectionCount );
+            if ( KErrNotReady == err )
+                {
+                err = KErrNone;
+                }
+            }
+        else
+            {
+            // External connections
+            aSubConnectionCount = 1;
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetConnectionInfo()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetIntAttributeL
+// Returns the integer attribute in aValue
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetIntAttributeL( const RMessage2& aMessage, TInt& aValue )
+    {
+    LOGENTRFN("CConnMonIAP::GetIntAttributeL()")
+    TInt ret( KErrNone );
+    TUint connectionId( aMessage.Int0() );
+    TUint attribute( aMessage.Int2() );
+
+    LOGIT2("SERVER: CConnMonIAP::GetIntAttributeL(): connId %d, attribute %d", connectionId, attribute)
+
+    if ( KBearerInfo == attribute )
+        {
+        LOGIT("SERVER: CConnMonIAP::GetIntAttributeL(): KBearerInfo")
+        TBearerInfo bearerInfo;
+        ret = GetBearerInfo( connectionId, bearerInfo );
+        if ( KErrNone == ret )
+            {
+            aValue = bearerInfo.iBearer;
+            }
+        return ret;
+        }
+
+    if ( KWlanScanCacheLifetime == attribute )
+        {
+        // Check WLAN support for the given id
+        ret = WlanSupportCheck( connectionId );
+        if ( KErrNone == ret )
+            {
+            ret = iWlanSupport->GetIntAttributeL( aMessage, aValue );
+            }
+        return ret;
+        }
+
+    // Handle requests that use a bearer specific connection IDs
+    if ( ( connectionId == EBearerIdGPRS || connectionId == EBearerIdWCDMA ) &&
+         ( attribute == KNetworkStatus ) )
+        {
+        return ( GetPsdNetworkStatus( aValue ) );
+        }
+    else if ( ( connectionId == EBearerIdGPRS || connectionId == EBearerIdWCDMA ||
+                connectionId == EBearerIdCSD || connectionId == EBearerIdGSM ||
+                connectionId == EBearerIdWcdmaCSD )
+                && ( attribute == KNetworkRegistration ) )
+        {
+        return ( GetNetworkRegistration( aValue ) );
+        }
+    else if ( ( connectionId == EBearerIdGPRS || connectionId == EBearerIdWCDMA ||
+                connectionId == EBearerIdCSD || connectionId == EBearerIdGSM ||
+                connectionId == EBearerIdWcdmaCSD )
+                && ( attribute == KNetworkRegistration_v2 ) )
+        {
+        return ( GetNetworkRegistration_v2( aValue ) );
+        }
+    else if ( ( connectionId == EBearerIdGPRS || connectionId == EBearerIdWCDMA ||
+                connectionId == EBearerIdCSD || connectionId == EBearerIdGSM ||
+                connectionId == EBearerIdWcdmaCSD )
+                && ( attribute == KSignalStrength ) )
+        {
+        return ( GetGSMSignalStrength( aValue ) );
+        }
+    else if ( connectionId == EBearerIdWLAN && attribute == KSignalStrength )
+        {
+        if ( iWlanSupport )
+            {
+            ret = iWlanSupport->GetSignalStrengthL( aMessage, aValue );
+            }
+        else
+            {
+            ret = KErrNotSupported;
+            }
+        return ret;
+        }
+    else if ( ( connectionId == EBearerIdGPRS ) && ( attribute == KBearer ) )
+        {
+        // Check which is the bearer of the GPRS cell.
+        if ( IsEdgeCell() )
+            {
+            aValue = EBearerEdgeGPRS;
+            }
+        else
+            {
+            aValue = EBearerGPRS;
+            }
+        return KErrNone;
+        }
+
+    // Find connection matching the given Id
+    TInt index = Index( connectionId );
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    LOGIT1("SERVER: CConnMonIAP::GetIntAttributeL(): index %d", index)
+
+    // Find out bearer if not already set.
+    if ( iConnInfos[index].iBearer == EBearerUnknown )
+        {
+        ret = GetBearer(
+                connectionId,
+                iConnInfos[index].iBearer,
+                iConnInfos[index].iBearerInfo );
+
+        if ( ret != KErrNone )
+            {
+            LOGIT1("SERVER: CConnMonIAP::GetIntAttributeL(): Error getting bearer info for connection <%d>", ret)
+            return ret;
+            }
+        LOGIT1("SERVER: CConnMonIAP::GetIntAttributeL(): bearer was unknown, now %d", iConnInfos[index].iBearer)
+        }
+
+    switch ( attribute )
+        {
+        case KBearer:
+            {
+            // BEARER
+            LOGIT1("SERVER: CConnMonIAP::GetIntAttributeL(): case KBearer, bearer %d", iConnInfos[index].iBearer)
+            // Bearer is never unknown for the external connections
+            // but sometimes it is not valid (e.g. CSD/HSCSD) until
+            // connection reaches certain status.
+            if ( ( iConnInfos[index].iBearer == EBearerExternalCSD ) ||
+                 ( iConnInfos[index].iBearer == EBearerExternalHSCSD ) ||
+                 ( iConnInfos[index].iBearer == EBearerExternalWcdmaCSD ) )
+                {
+                if ( iCsdFax )
+                    {
+                    iCsdFax->GetBearer( iConnInfos[index].iBearer, iConnInfos[index].iBearerInfo );
+                    }
+                }
+            else if ( ( iConnInfos[index].iBearer == EBearerExternalGPRS ) ||
+                      ( iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ) ||
+                      ( iConnInfos[index].iBearer == EBearerExternalWCDMA ) )
+                {
+                if ( iPsdFax )
+                    {
+                    iPsdFax->GetBearer( iConnInfos[index].iBearer, iConnInfos[index].iBearerInfo );
+                    }
+                }
+            else if ( iConnInfos[index].iBearer < EBearerExternalCSD )
+                {
+                // CSD/HSCSD info could change after the first query
+                // also GPRS/EdgeGPRS/WCDMA info can change
+                TInt bearer( EBearerUnknown );
+                TBearerInfo bearerInfo;
+
+                ret = GetBearer( connectionId, bearer, bearerInfo );
+                if ( iConnInfos[index].iBearer != bearer )
+                    {
+                    LOGIT4("Bearer changed: id %d, iapId %d, old bearer %d, new bearer %d",
+                            iConnInfos[index].iConnectionId, iConnInfos[index].iIapId,
+                            iConnInfos[index].iBearer, bearer)
+                    }
+
+                if ( ( bearer != EBearerUnknown && bearerInfo.iBearer != EBearerInfoUnknown )
+                     && ( ret == KErrNone ) )
+                    {
+                    iConnInfos[index].iBearer = bearer;
+                    iConnInfos[index].iBearerInfo = bearerInfo;
+                    }
+                }
+            aValue = iConnInfos[index].iBearer;
+            }
+            break;
+
+        case KNetworkStatus:
+            {
+            // NETWORK STATUS
+            if ( iConnInfos[index].iBearer == EBearerGPRS ||
+                 iConnInfos[index].iBearer == EBearerEdgeGPRS ||
+                 iConnInfos[index].iBearer == EBearerWCDMA ||
+                 iConnInfos[index].iBearer == EBearerCDMA2000 ||
+                 iConnInfos[index].iBearer == EBearerExternalGPRS ||
+                 iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ||
+                 iConnInfos[index].iBearer == EBearerExternalWCDMA ||
+                 iConnInfos[index].iBearer == EBearerExternalCDMA2000 )
+                {
+                // psd
+                ret = GetPsdNetworkStatus( aValue );
+                }
+            else if ( iConnInfos[index].iBearer == EBearerUnknown )
+                {
+                 // GetBearer() : iMobilePhone.GetCurrentMode()
+                 // is not always working for PSD when starting the first
+                 // connection. So this must be some PSD...
+                ret = GetPsdNetworkStatus( aValue );
+                }
+            else
+                {
+                // Others not supported at the moment
+                aValue = EConnMonStatusNotAvailable;
+                ret = KErrNone;
+                }
+            }
+            break;
+
+        case KConnectionStatus:
+            {
+            // CONNECTION STATUS
+            if ( iConnInfos[index].iBearer < EBearerExternalCSD )
+                {
+                // Internal connections
+                ret = GetConnectionStatus( index, aValue );
+                }
+            else if ( iConnInfos[index].iBearer == EBearerExternalCSD ||
+                      iConnInfos[index].iBearer == EBearerExternalHSCSD ||
+                      iConnInfos[index].iBearer == EBearerExternalWcdmaCSD )
+                {
+                // External csd
+                if ( iCsdFax )
+                    {
+                    ret = iCsdFax->GetStatus( aValue );
+                    }
+                else
+                    {
+                    ret = KErrNotFound;
+                    }
+                }
+            else
+                {
+                // External psd
+                if ( iPsdFax )
+                    {
+                    ret = iPsdFax->GetStatus( connectionId, aValue );
+                    }
+                else
+                    {
+                    ret = KErrNotFound;
+                    }
+                }
+            }
+            break;
+
+        case KProtocolType:
+            {
+            // PROTOCOL TYPE
+            if ( iConnInfos[index].iBearer == EBearerGPRS ||
+                 iConnInfos[index].iBearer == EBearerEdgeGPRS ||
+                 iConnInfos[index].iBearer == EBearerWCDMA )
+                {
+                ret = GetProtocolTypeL( connectionId, aValue );
+                }
+            else if ( iConnInfos[index].iBearer == EBearerExternalGPRS ||
+                      iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ||
+                      iConnInfos[index].iBearer == EBearerExternalWCDMA )
+                {
+                if ( iPsdFax )
+                    {
+                    ret = iPsdFax->GetProtocolType( connectionId, aValue );
+                    }
+                else
+                    {
+                    ret = KErrNotFound;
+                    }
+                }
+            else
+                {
+                aValue = EProtocolTypeUnknown;
+                }
+            }
+            break;
+
+        case KNetworkRegistration:
+            {
+            // NETWORK REGISTRATION STATUS
+            if ( iConnInfos[index].iBearer == EBearerGPRS ||
+                 iConnInfos[index].iBearer == EBearerEdgeGPRS ||
+                 iConnInfos[index].iBearer == EBearerWCDMA ||
+                 iConnInfos[index].iBearer == EBearerCSD ||
+                 iConnInfos[index].iBearer == EBearerHSCSD ||
+                 iConnInfos[index].iBearer == EBearerWcdmaCSD ||
+                 iConnInfos[index].iBearer == EBearerExternalGPRS ||
+                 iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ||
+                 iConnInfos[index].iBearer == EBearerExternalWCDMA ||
+                 iConnInfos[index].iBearer == EBearerExternalCSD ||
+                 iConnInfos[index].iBearer == EBearerExternalHSCSD ||
+                 iConnInfos[index].iBearer == EBearerExternalWcdmaCSD )
+                {
+                ret = GetNetworkRegistration( aValue );
+                }
+            else
+                {
+                aValue = ENetworkRegistrationNotAvailable;
+                ret = KErrNone;
+                }
+            }
+            break;
+        case KNetworkRegistration_v2:
+            {
+            // NETWORK REGISTRATION STATUS
+            if ( iConnInfos[index].iBearer == EBearerGPRS ||
+                 iConnInfos[index].iBearer == EBearerEdgeGPRS ||
+                 iConnInfos[index].iBearer == EBearerWCDMA ||
+                 iConnInfos[index].iBearer == EBearerCSD ||
+                 iConnInfos[index].iBearer == EBearerHSCSD ||
+                 iConnInfos[index].iBearer == EBearerWcdmaCSD ||
+                 iConnInfos[index].iBearer == EBearerExternalGPRS ||
+                 iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ||
+                 iConnInfos[index].iBearer == EBearerExternalWCDMA ||
+                 iConnInfos[index].iBearer == EBearerExternalCSD ||
+                 iConnInfos[index].iBearer == EBearerExternalHSCSD ||
+                 iConnInfos[index].iBearer == EBearerExternalWcdmaCSD )
+                {
+                ret = GetNetworkRegistration_v2( aValue );
+                }
+            else
+                {
+                aValue = ENetworkRegistrationNotAvailable;
+                ret = KErrNone;
+                }
+            }
+            break;
+        case KSignalStrength:
+            {
+            // SIGNAL STRENGTH
+            ret = KErrNotSupported;
+            if ( iConnInfos[index].iBearer == EBearerGPRS ||
+                 iConnInfos[index].iBearer == EBearerEdgeGPRS ||
+                 iConnInfos[index].iBearer == EBearerWCDMA ||
+                 iConnInfos[index].iBearer == EBearerCSD ||
+                 iConnInfos[index].iBearer == EBearerHSCSD ||
+                 iConnInfos[index].iBearer == EBearerWcdmaCSD ||
+                 iConnInfos[index].iBearer == EBearerExternalGPRS ||
+                 iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ||
+                 iConnInfos[index].iBearer == EBearerExternalWCDMA ||
+                 iConnInfos[index].iBearer == EBearerExternalCSD ||
+                 iConnInfos[index].iBearer == EBearerExternalHSCSD ||
+                 iConnInfos[index].iBearer == EBearerExternalWcdmaCSD )
+                {
+                ret = GetGSMSignalStrength( aValue );
+                }
+            else if ( iConnInfos[index].iBearer == EBearerWLAN )
+                {
+                if ( iWlanSupport )
+                    {
+                    ret = iWlanSupport->GetSignalStrengthL( aMessage, aValue );
+                    }
+                }
+            }
+            break;
+
+        case KNetworkMode:
+            // NETWORK MODE
+            ret = KErrNotSupported;
+            if ( iConnInfos[index].iBearer == EBearerWLAN )
+                {
+                if ( iWlanSupport )
+                    {
+                    ret = iWlanSupport->GetConnectionMode( aValue );
+                    }
+                }
+            break;
+
+        case KSecurityMode:
+            // SECURITY MODE
+            ret = KErrNotSupported;
+            if ( iConnInfos[index].iBearer == EBearerWLAN )
+                {
+                if ( iWlanSupport )
+                    {
+                    ret = iWlanSupport->GetConnectionSecurity( aValue );
+                    }
+                }
+            break;
+
+        case KTrafficClass:
+            ret = KErrNotSupported;
+            break;
+        case KDeliveryOrder:
+            ret = KErrNotSupported;
+            break;
+        case KErroneousSDUDelivery:
+            ret = KErrNotSupported;
+            break;
+        case KResidualBitErrorRatio:
+            ret = KErrNotSupported;
+            break;
+        case KSDUErrorRatio:
+            ret = KErrNotSupported;
+            break;
+        default:
+            ret = KErrArgument;
+            break;
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetIntAttributeL()", ret)
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetBearerInfo
+// Returns the integer attribute in aValue
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetBearerInfo( const TUint aConnectionId, TBearerInfo& aBearerInfo )
+    {
+    LOGENTRFN("CConnMonIAP::GetBearerInfo()")
+    TInt err( KErrNone );
+
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+    if ( index < 0  )
+        {
+        err = KErrNotFound;
+        }
+    else
+        {
+        // Find out bearer if not already set. This can be only with internal
+        // connections.
+        if ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoUnknown )
+            {
+            LOGIT("GetBearerInfo: EBearerInfoUnknown")
+            err = GetBearer(
+                    aConnectionId,
+                    iConnInfos[index].iBearer,
+                    iConnInfos[index].iBearerInfo );
+            }
+        if ( KErrNone == err )
+            {
+            // Bearer is never unknown for the external connections but
+            // sometimes it is not valid (e.g. CSD/HSCSD) until connection
+            // reaches certain status.
+            if ( !iConnInfos[index].iBearerInfo.iInternal &&
+                    ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoCSD ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSCSD ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoWcdmaCSD ) )
+                {
+                if ( iCsdFax )
+                    {
+                    LOGIT("GetBearerInfo: case iCsdFax")
+                    err = iCsdFax->GetBearer(
+                            iConnInfos[index].iBearer,
+                            iConnInfos[index].iBearerInfo );
+                    }
+                }
+            else if ( !iConnInfos[index].iBearerInfo.iInternal &&
+                    ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoGPRS ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoEdgeGPRS ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoWCDMA ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) )
+                {
+                if ( iPsdFax )
+                    {
+                    LOGIT("GetBearerInfo: case iPsdFax")
+                    err = iPsdFax->GetBearer(
+                            iConnInfos[index].iBearer,
+                            iConnInfos[index].iBearerInfo );
+                    }
+                }
+            else if ( iConnInfos[index].iBearerInfo.iInternal &&
+                    ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoCSD ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSCSD ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoGPRS ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoEdgeGPRS ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoWCDMA ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA ||
+                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) )
+                {
+                // CSD/HSCSD info could change after the first query also
+                // GPRS/EdgeGPRS/WCDMA info can change.
+                TInt bearer( EBearerUnknown );
+                TBearerInfo bearerInfo;
+
+                LOGIT("GetBearerInfo: GetBearer() 2nd query")
+                err = GetBearer( aConnectionId, bearer, bearerInfo );
+                if ( ( KErrNone == err ) && ( bearerInfo.iBearer != EBearerInfoUnknown ) )
+                    {
+                    iConnInfos[index].iBearer = bearer;
+                    iConnInfos[index].iBearerInfo = bearerInfo;
+                    }
+                }
+            }
+        if ( KErrNone == err )
+            {
+            aBearerInfo.iBearer = iConnInfos[index].iBearerInfo.iBearer;
+            aBearerInfo.iInternal = iConnInfos[index].iBearerInfo.iInternal;
+            LOGIT2("GetBearerInfo: result: bearer %d, internal %d", aBearerInfo.iBearer, aBearerInfo.iInternal)
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetBearerInfo()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetUintAttributeL
+// Returns the unsigned integer attribute in aValue
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetUintAttributeL( const RMessage2& aMessage, TUint& aValue )
+    {
+    LOGENTRFN("CConnMonIAP::GetUintAttributeL()")
+    TInt err( KErrNone );
+    TUint connectionId( aMessage.Int0() );
+    TUint attribute( aMessage.Int2() );
+
+    LOGIT2("SERVER: CConnMonIAP::GetUintAttributeL: connId %d, attribute %d", connectionId, attribute)
+
+    // Find connection matching the given ID
+    TInt index = Index( connectionId );
+    if ( index < 0 )
+        {
+        LOGEXITFN1("CConnMonIAP::GetUintAttributeL()", KErrNotFound)
+        return KErrNotFound;
+        }
+
+    switch ( attribute )
+        {
+        case KIAPId:
+            {
+            err = KErrNotSupported;
+            if ( iConnInfos[index].iBearer < EBearerExternalCSD &&
+                    iConnInfos[index].iBearerInfo.iInternal )
+                {
+                err = KErrNone;
+                aValue = iConnInfos[index].iIapId;
+                LOGIT1("GetUintAttributeL: iap id %d", aValue)
+                }
+            }
+            break;
+
+        case KNetworkIdentifier:
+            {
+            err = KErrNotSupported;
+            if ( iConnInfos[index].iBearer < EBearerExternalCSD &&
+                    iConnInfos[index].iBearerInfo.iInternal )
+                {
+                err = KErrNone;
+                aValue = iConnInfos[index].iNetId;
+                LOGIT1("GetUintAttributeL: net id %d", aValue)
+                }
+            }
+            break;
+
+        case KDownlinkData:
+        case KUplinkData:
+            {
+            if ( iConnInfos[index].iBearer < EBearerExternalCSD &&
+                    iConnInfos[index].iBearerInfo.iInternal )
+                {
+                // INTERNAL
+                // Query data volumes asyncronously
+                if ( !iConnInfos[index].iDataVolumeAO )
+                    {
+                    // Create an active object and add it to scheduler
+                    iConnInfos[index].iDataVolumeAO = new( ELeave ) CDataVolume(
+                            iServer,
+                            iConnInfos[index].iConnAttach,
+                            iConnInfos[index].iConnectionId );
+
+                    iConnInfos[index].iDataVolumeAO->Construct();
+                    }
+                if ( !iConnInfos[index].iDataVolumeAO->IsActive() )
+                    {
+                    iConnInfos[index].iDataVolumeAO->Receive(); // start a new request
+                    }
+                // Don't complete this request yet
+                err = KRequestPending;
+                }
+
+            else if ( iConnInfos[index].iBearer == EBearerExternalGPRS     ||
+                      iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ||
+                      iConnInfos[index].iBearer == EBearerExternalWCDMA    ||
+                      iConnInfos[index].iBearer == EBearerExternalCDMA2000 ||
+                      ( !iConnInfos[index].iBearerInfo.iInternal &&
+                        ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA ||
+                          iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA ||
+                          iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) )
+                {
+                // EXTERNAL PSD
+                if ( iPsdFax )
+                    {
+                    TUint down( 0 );
+                    TUint up( 0 );
+                    err = iPsdFax->GetDataVolumes( connectionId, down, up );
+                    if ( KErrNone == err )
+                        {
+                        if ( attribute == KDownlinkData )
+                            {
+                            aValue = down;
+                            }
+                        else
+                            {
+                            aValue = up;
+                            }
+                        }
+                    }
+                else
+                    {
+                    err = KErrNotFound;
+                    }
+                }
+
+            else
+                {
+                // EXTERNAL CSD
+                err = KErrNotSupported;
+                }
+            }
+            break;
+
+        case KTransmitPower:
+            {
+            err = KErrNotSupported;
+            if ( iConnInfos[index].iBearer == EBearerWLAN && iWlanSupport )
+                {
+                err = iWlanSupport->GetTransmitPower( aValue );
+                LOGIT1("GetUintAttributeL: transmit power %d", aValue)
+                }
+            }
+            break;
+
+        case KMaximumBitrateDownlink:
+        case KMaximumBitrateUplink:
+        case KMaximumSDUSize:
+        case KTransferDelay:
+        case KGuaranteedBitrateDownlink:
+        case KGuaranteedBitrateUplink:
+        case KTrafficHandlingPriority:
+            err = KErrNotSupported;
+            break;
+
+        default:
+            err = KErrArgument;
+            break;
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetUintAttributeL()", err)
+    return err;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetBoolAttributeL
+// Returns the TBool attribute in aValue
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetBoolAttributeL( const RMessage2& aMessage, TBool& aValue )
+    {
+    LOGENTRFN("CConnMonIAP::GetBoolAttributeL()")
+    TInt err( KErrNone );
+    TUint connectionId( aMessage.Int0() );
+    TUint attribute( aMessage.Int2() );
+
+    switch ( attribute )
+        {
+        case KConnectionActive:
+            {
+            // Find connection matching the given ID
+            TInt index = Index( connectionId );
+            if ( index < 0  )
+                {
+                LOGIT("GetBoolAttributeL: connection id not found")
+                err = KErrNotFound;
+                break;
+                }
+            if ( iConnInfos[index].iBearer < EBearerExternalCSD &&
+                    iConnInfos[index].iBearerInfo.iInternal )
+                {
+                TInt connectionStatus( 0 );
+                GetConnectionStatus( index, connectionStatus );
+                LOGIT1("GetBoolAttributeL: connection status %d", connectionStatus)
+
+                if ( connectionStatus != KLinkLayerOpen )
+                    {
+                    aValue = EFalse;
+                    break;
+                    }
+                if ( ( iCountListeners > 0 ) && ( iConnInfos[index].iActivityNotifier != 0 ) )
+                    {
+                    if ( iConnInfos[index].iActivityNotifier->IsActive() )
+                        {
+                        // Notifications are ON and are updating the activity info.
+                        // Return the info immediately from internal table
+                        if ( iConnInfos[index].iActivity == 0 )
+                            {
+                            aValue = EFalse;
+                            }
+                        else
+                            {
+                            aValue = ETrue;
+                            }
+                        }
+                    else
+                        {
+                        GetActivityOneShotL( index );
+                        err = KRequestPending;
+                        }
+                    }
+                else
+                    {
+                    // Notifications are OFF
+                    GetActivityOneShotL( index );
+                    err = KRequestPending;
+                    }
+                }
+            else
+                {
+                err = KErrNotSupported;
+                }
+            }
+            break;
+
+        case KBearerAvailability:
+            {
+            TUint bearer( EBearerIdAll );
+            err = BearerIdForBearerAvailability( connectionId, bearer );
+            if ( KErrNone == err )
+                {
+                if ( bearer == EBearerIdWLAN )
+                    {
+                    if ( iWlanSupport )
+                        {
+                        err = iWlanSupport->GetBearerAvailabilityL( aMessage, aValue );
+                        }
+                    else
+                        {
+                        err = KErrNotSupported;
+                        }
+                    }
+                else
+                    {
+                    TBool byCell( EFalse );
+                    TBool byPhone( EFalse );
+                    err = GetBearerSupportInfo( bearer, byCell, byPhone );
+                    if ( byCell && byPhone )
+                        {
+                        aValue = ETrue;
+                        }
+                    else
+                        {
+                        aValue = EFalse;
+                        }
+                    }
+                }
+            }
+            break;
+
+        case KPacketDataAvailability:
+            {
+            if ( connectionId != EBearerIdGPRS && connectionId != EBearerIdWCDMA )
+                {
+                err = KErrNotSupported;
+                }
+            else
+                {
+                // When not in dual mode and call is active, gprs and wcdma bearers are unavailable
+                // Note that even the WCDMA can be unavailable, if the phone doesn't support DTM
+                if ( iTelephonyNotifier && iDualTransferModeNotifier &&
+                        iTelephonyNotifier->IsCallActive() &&
+                        !iDualTransferModeNotifier->IsInDualMode() )
+                    {
+                    LOGIT("SERVER: Packet data UNAVAILABLE (2G&3G), no DTM and call is active")
+                    aValue = EFalse;
+                    }
+                // If DTM status says available, lets check the availability of the bearer.
+                // This is done because the DTM status remains as it was if the psd link is broken.
+                // So there might be a situation where the notifier says we are in dual mode even
+                // though the whole bearer is unavailable
+                else
+                    {
+                    TBool byPhone( EFalse );
+                    TBool byCell( EFalse );
+                    err = GetBearerSupportInfo( connectionId, byCell, byPhone );
+                    LOGIT4("Bearer support: bearer %d, byCell %d, byPhone %d, err <%d>", connectionId, byCell, byPhone, err)
+                    aValue = ETrue;
+                    if ( KErrNone == err )
+                        {
+                        if ( byCell && byPhone )
+                            {
+                            LOGIT("SERVER: Packet data AVAILABLE, DTM or no call is active")
+                            }
+                        else
+                            {
+                            LOGIT("SERVER: Packet data UNAVAILABLE, no bearer")
+                            aValue = EFalse;
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+
+        default:
+            // Unknown attribute
+            err = KErrArgument;
+            break;
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetBoolAttributeL()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetStringAttribute
+// Returns the TDes attribute in aValue
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetStringAttribute( const RMessage2& aMessage, TDes& aValue )
+    {
+    LOGENTRFN("CConnMonIAP::GetStringAttribute()")
+    TInt err( KErrNone );
+    TUint connectionId( aMessage.Int0() );
+    TUint attribute( aMessage.Int2() );
+
+    // Find connection matching the given ID
+    TInt index = Index( connectionId );
+    if ( index < 0  )
+        {
+        LOGEXITFN1("CConnMonIAP::GetStringAttribute()", KErrNotFound)
+        return KErrNotFound;
+        }
+
+    // Find out bearer if not already set
+    if ( iConnInfos[index].iBearer == EBearerUnknown )
+        {
+        err = GetBearer( connectionId, iConnInfos[index].iBearer, iConnInfos[index].iBearerInfo );
+        if ( KErrNone != err )
+            {
+            LOGEXITFN1("CConnMonIAP::GetStringAttribute()", err)
+            return err;
+            }
+        }
+
+    switch ( attribute )
+        {
+        case KIAPName:
+            {
+            // From RConnection
+            if ( iConnInfos[index].iBearer >= EBearerExternalCSD &&
+                    !iConnInfos[index].iBearerInfo.iInternal )
+                {
+                err = KErrNotSupported;
+                }
+            else
+                {
+                TBuf<KCommsDbSvrMaxFieldLength> settingName;
+                settingName.Copy( TPtrC( IAP ) );
+                settingName.Append( TChar( '\\' ) );
+                settingName.Append( TPtrC( COMMDB_NAME ) );
+                // IAP name max. length in commsdat should be 50
+                err = iConnInfos[index].iConnAttach->GetDesSetting( TPtrC( settingName ), aValue );
+                }
+            }
+            break;
+
+        case KAccessPointName:
+            {
+            if ( iConnInfos[index].iBearer < EBearerExternalCSD )
+                {
+                err = GetAccessPointName( iConnInfos[index].iConnectionId, aValue );
+                }
+            else if ( iConnInfos[index].iBearer == EBearerExternalGPRS ||
+                    iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ||
+                    iConnInfos[index].iBearer == EBearerExternalWCDMA ||
+                    ( !iConnInfos[index].iBearerInfo.iInternal &&
+                            ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA ||
+                                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA ||
+                                    iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) )
+                {
+                if ( iPsdFax )
+                    {
+                    err = iPsdFax->GetApn( connectionId, aValue );
+                    }
+                else
+                    {
+                    err = KErrNotFound;
+                    }
+                }
+            else
+                {
+                err = KErrNotSupported;
+                }
+            }
+            break;
+
+        case KTelNumber:
+            {
+            if ( iConnInfos[index].iBearer < EBearerExternalCSD )
+                {
+                err = GetTelNumber( iConnInfos[index].iConnectionId, aValue );
+                }
+            else if ( iConnInfos[index].iBearer == EBearerExternalCSD ||
+                    iConnInfos[index].iBearer == EBearerExternalHSCSD ||
+                    iConnInfos[index].iBearer == EBearerExternalWcdmaCSD )
+                {
+                if ( iCsdFax )
+                    {
+                    err = iCsdFax->GetTelNumber( aValue );
+                    }
+                else
+                    {
+                    err = KErrNotFound;
+                    }
+                }
+            else
+                {
+                err = KErrNotSupported;
+                }
+            }
+            break;
+
+        case KNetworkName:
+            {
+            err = KErrNotSupported;
+            if ( iConnInfos[index].iBearer == EBearerWLAN )
+                {
+                if ( iWlanSupport )
+                    {
+                    // Max SSID length is 32
+                    err = iWlanSupport->GetConnectionSsid( aValue );
+                    }
+                }
+            }
+            break;
+
+        default:
+            err = KErrArgument;
+            break;
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetStringAttribute()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetUids
+// RConnection::EnumerateConnections() must be called to get the right
+// RConnection index for the connection (iConnInfos can't be trusted because
+// connections are added by events, too).
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetUids(
+        const TUint aConnectionId,
+        TConnMonClientEnum& aClientEnum )
+    {
+    TInt                     err( KErrNone );
+    TConnEnumArgBuf          enumArgBuf;
+    TConnGetClientInfoArgBuf clientInfoBuf;
+    TUint                    count( 0 );
+    TConnectionInfoBuf       connInfoBuf;
+    TUint                    j;
+
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    // Uids are not available for external connections
+    if ( iConnInfos[index].iBearer >= EBearerExternalCSD &&
+         !iConnInfos[index].iBearerInfo.iInternal )
+        {
+        return KErrNotSupported;
+        }
+
+    // Get RConnection index for the connection
+    err = iConnection.EnumerateConnections( count );
+
+    if ( err != KErrNone )
+        {
+        return( err );
+        }
+
+    for ( j = 1; j <= count; j++ )
+        {
+        err = iConnection.GetConnectionInfo( j, connInfoBuf );
+
+        if ( err != KErrNone )
+            {
+            return( err );
+            }
+
+        if ( ( iConnInfos[index].iIapId == connInfoBuf().iIapId ) &&
+                ( iConnInfos[index].iNetId == connInfoBuf().iNetId ) )
+            {
+            break;
+            }
+        }
+
+    // If connection does not exist anymore
+    if ( j > count )
+        {
+        return KErrNotFound;
+        }
+
+    enumArgBuf().iIndex = j;
+
+    // Get the number of clients
+    err = iConnection.Control( KCOLConnection, KCoEnumerateConnectionClients, enumArgBuf );
+
+    if ( err != KErrNone )
+        {
+        return err;
+        }
+
+    aClientEnum.iCount = enumArgBuf().iCount;
+
+    // Count connection monitor OUT of the number of clients
+    if ( aClientEnum.iCount > 0 )
+        {
+        --aClientEnum.iCount;
+        }
+
+    // Get client uids one by one
+    // Note. in WINS uids are zero.
+    TInt k( 0 );
+
+    for ( TUint i = 1; i <= enumArgBuf().iCount; i++ )
+        {
+        clientInfoBuf().iIndex = i;
+
+        err = iConnection.Control( KCOLConnection, KCoGetConnectionClientInfo, clientInfoBuf );
+
+        if ( err != KErrNone )
+            {
+            return err;
+            }
+
+        // Exclude Connection Monitor UID
+        if ( ( clientInfoBuf().iClientInfo.iUid.iUid != KConnMonDllUid.iUid ) &&
+             ( clientInfoBuf().iClientInfo.iUid.iUid != KGenericDllUid.iUid ) &&
+             ( clientInfoBuf().iClientInfo.iUid.iUid != KConnMonServerUid.iUid ) &&
+             ( clientInfoBuf().iClientInfo.iUid.iUid != 0 ) )
+            {
+            TInt m( 0 );
+
+            // Look for duplicates
+            for ( m = 0; m < k; m++ )
+                {
+                if ( aClientEnum.iUid[m].iUid == clientInfoBuf().iClientInfo.iUid.iUid )
+                    {
+                    break;
+                    }
+                }
+
+            if ( m == k )
+                {
+                // This is a new unique ID
+                aClientEnum.iUid[k].iUid = clientInfoBuf().iClientInfo.iUid.iUid;
+                k++;
+                }
+            else
+                {
+                // Duplicate
+                --aClientEnum.iCount;
+                }
+            }
+        }
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::SetUintAttribute
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::SetUintAttribute(
+        const RMessage2& /*aMessage*/,
+        const TUint /*aValue*/ )
+    {
+    return KErrNotSupported;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::SetBoolAttributeL
+// Used for stopping the connections.
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::SetBoolAttribute( const RMessage2& aMessage )
+    {
+    LOGENTRFN("CConnMonIAP::SetBoolAttribute()")
+    TInt err( KErrNone );
+    TUint attribute( aMessage.Int2() );
+    TBool value( aMessage.Int3() );
+
+    switch ( attribute )
+        {
+        case KConnectionStop:
+            if ( value )
+                {
+                // Find connection matching the given Id
+                TInt index = Index( aMessage.Int0() );
+                if ( index < 0  )
+                    {
+                    err = KErrNotFound;
+                    }
+                else
+                    {
+                    err = StopConnection( index );
+                    if ( KErrCouldNotConnect == err )
+                        {
+                        err = KErrNotFound;
+                        }
+                    }
+                }
+            break;
+
+        case KConnectionStopAll:
+            if ( value )
+                {
+                TUint i( 0 );
+                TUint count( 0 );
+                TUint newCount( 0 );
+
+                // Refresh array
+                err = EnumerateConnections( count );
+                LOGIT2("SetBoolAttribute: KConnectionStopAll: Enumerated all connections, count %d <%d>", count, err)
+                if ( KErrNone == err )
+                    {
+                    while ( count > 0 && i < count )
+                        {
+                        // Stop (and remove if up/down event watcher is dead) the connection
+                        err = StopConnection( i );
+                        if ( KErrNone != err )
+                            {
+                            LOGIT2("SetBoolAttribute: KConnectionStopAll: Error stopping connection %d <%d>", i, err)
+                            return err;
+                            }
+                        newCount = iConnInfos.Count();
+                        if ( count > newCount )
+                            {
+                            count = newCount; // Connection has been removed
+                            }
+                        else
+                            {
+                            i++; // Cconnection has not been removed, increment index to next connection
+                            }
+                        }
+                    }
+                }
+            break;
+
+        default:
+            err = KErrArgument;
+            break;
+        }
+
+    LOGEXITFN1("CConnMonIAP::SetBoolAttribute()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::SetStringAttributeL
+//
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::SetStringAttributeL(
+        const RMessage2& /*aMessage*/,
+        const TDes& /*aValue*/ )
+    {
+    return KErrNotSupported;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::ListenL
+// Starts event watchers.
+// -----------------------------------------------------------------------------
+//
+void CConnMonIAP::ListenL()
+    {
+    LOGIT(".")
+    LOGENTRFN("CConnMonIAP::ListenL()")
+    iCountListeners++;
+
+    // GLOBAL notifiers
+
+    // Connection Up/Down events
+    if ( iConnUpDownNotifier == 0 )
+        {
+        iConnUpDownNotifier = new( ELeave ) CConnUpDownNotifier( iServer );
+        iConnUpDownNotifier->Construct();
+        }
+    if ( !iConnUpDownNotifier->IsActive() )
+        {
+        iConnUpDownNotifier->Receive(); // (re)start listening
+        }
+
+    if ( iTSYLoaded && iPacketServLoaded )
+        {
+        // PSD network status events
+        if ( iPsdNetwStatusNotifier == 0 )
+            {
+            iPsdNetwStatusNotifier = CNetwStatusNotifier::NewL( iServer );
+            }
+        if ( !iPsdNetwStatusNotifier->IsActive() )
+            {
+            iPsdNetwStatusNotifier->Receive(); // (re)start listening
+            }
+
+        // GPRS bearer availability changed events
+        if ( iGSMBearerAvailabilityNotifier == 0 )
+            {
+            iGSMBearerAvailabilityNotifier = CBearerAvailabilityNotifier::NewL( iServer );
+            }
+        if ( !iGSMBearerAvailabilityNotifier->IsActive() )
+            {
+            iGSMBearerAvailabilityNotifier->Receive(); // (re)start listening
+            }
+        }
+
+    if ( iTSYLoaded )
+        {
+        // Mode change events
+        if ( iModeNotifier == 0 )
+            {
+            iModeNotifier = CModeNotifier::NewL( iServer, iMobilePhone );
+            }
+        if ( !iModeNotifier->IsActive() )
+            {
+            iModeNotifier->Receive(); // (re)start listening
+            }
+
+        // Network registration status events
+        if ( iNetwRegistrationNotifier == 0 )
+            {
+            iNetwRegistrationNotifier = CNetwRegistrationNotifier::NewL( iServer, iMobilePhone );
+            }
+        if ( !iNetwRegistrationNotifier->IsActive() )
+            {
+            iNetwRegistrationNotifier->Receive(); // (re)start listening
+            }
+
+        // Bearer change (GPRS/Edge GPRS) status events
+        if ( FeatureManager::FeatureSupported( KFeatureIdEdgeKnowledge ) )
+            {
+            if ( iEdgeNotifier == 0 )
+                {
+                iEdgeNotifier = new( ELeave ) CBearerNotifier( iServer, iMobilePhone );
+                TRAPD( ret, iEdgeNotifier->ConstructL() );
+                if ( ret != KErrNone )
+                    {
+                    // Construction (=opening ETel CustomAPI) failed
+                    delete iEdgeNotifier;
+                    iEdgeNotifier = 0;
+                    }
+                }
+            if ( iEdgeNotifier != 0 )
+                {
+                if ( !iEdgeNotifier->IsActive() )
+                    {
+                    iEdgeNotifier->Receive(); // (re)start listening
+                    }
+                }
+            }
+
+        if ( !iWcdmaNotifier )
+            {
+            iWcdmaNotifier = CWcdmaBearerNotifier::NewL( iServer, iTelServer );
+            if ( iWcdmaNotifier )
+                {
+                iWcdmaNotifier->Receive();
+                }
+            }
+
+        if (  FeatureManager::FeatureSupported( KFeatureIdConnMonExtension ) )
+            {
+            // GSM signal strength change events
+            if ( iGSMSignalNotifier == 0 )
+                {
+                iGSMSignalNotifier = CGsmSignalNotifier::NewL( iServer, iMobilePhone );
+                }
+            if ( !iGSMSignalNotifier->IsActive() )
+                {
+                iGSMSignalNotifier->Receive(); // (re)start listening
+                }
+            }
+        }
+
+    if ( !iTelephonyNotifier )
+        {
+        iTelephonyNotifier = CConnMonTelNotifier::NewL( *this, &iMobilePhone );
+        iTelephonyNotifier->Receive();
+        }
+
+    if ( !iDualTransferModeNotifier && iPacketServLoaded )
+        {
+        iDualTransferModeNotifier = CConnMonDtmNotifier::NewL( iPacketService, *this );
+        iDualTransferModeNotifier->Receive();
+        }
+
+    if ( iWlanSupport )
+        {
+        iWlanSupport->EnableEventsToClients();
+        }
+
+    // Notifiers owned by the connections
+    // (connection status, data volumes, connection activity, subconnection up/down)
+    TInt count = iConnInfos.Count();
+
+    for ( TInt i = 0; i < count; i++ )
+        {
+        AddConnNotificationsL( i );
+        }
+    LOGEXITFN("CConnMonIAP::ListenL()")
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::CancelListen
+// Stops and deletes event watchers.
+// -----------------------------------------------------------------------------
+//
+void CConnMonIAP::CancelListen()
+    {
+    iCountListeners--;
+    LOGIT1("CancelListen() remaining listeners: %d", iCountListeners)
+
+    if ( iCountListeners == 0 )
+        {
+        DeleteNotifications();
+        }
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::AddConnectionL
+// Adds a new connection to the iConnInfos array. Starts event watchers for the
+// connection if there are clients that want events.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::AddConnectionL( TConnInfo& aConnection )
+    {
+    TInt err( KErrNone );
+    TInt index( KErrNotFound );
+    TUint8 internal( 0 );
+
+    if ( aConnection.iBearer < EBearerExternalCSD )
+        {
+        internal = 1;
+        }
+
+    if ( internal )
+        {
+        index = iConnInfos.Find( aConnection, TConnInfo::MatchIap );
+        }
+    /*
+    else
+        {
+        index = iConnInfos.Find( aConnection, TConnInfo::MatchBearer );
+        }
+    */
+
+    if ( KErrNotFound != index )
+        {
+        LOGIT("AddConnectionL: New connection occured with same IAP id, remove old")
+        // To remove the connection we have to complete the
+        // connection by sending the notifications needed by clients.
+        CompleteConnectionClosing( index );
+        }
+
+    // Add to connection table
+    aConnection.iConnectionId = NewConnectionId();
+
+    if ( internal )
+        {
+        err = OpenAndAttachTo( aConnection );
+        if ( err != KErrNone )
+            {
+            LOGIT1("AddConnectionL: ERROR attach failed <%d>", err)
+            return err;
+            }
+        }
+
+    err = iConnInfos.Append( aConnection );
+
+    if ( ( KErrNone == err ) && internal )
+        {
+        index = iConnInfos.Find( aConnection, TConnInfo::MatchIap );
+        if ( ( index != KErrNotFound ) && ( iCountListeners > 0 ) )
+            {
+            TRAPD( ret, AddConnNotificationsL( index ) );
+            if ( ret != KErrNone )
+                {
+                // Close attached connection
+                if ( iConnInfos[ index ].iConnAttach != 0 )
+                    {
+                    iConnInfos[ index ].iConnAttach->Close();
+                    delete iConnInfos[ index ].iConnAttach;
+                    }
+
+                // Remove
+                iConnInfos.Remove( index );
+
+                // Leave
+                User::Leave( ret );
+                }
+            }
+        }
+
+    // Print connection info array to log
+    #ifdef _DEBUG
+    LOGIT("AddConnectionL: Connection info array:")
+    for ( TInt m = 0; m < iConnInfos.Count(); m++ )
+        {
+        LOGIT4("  id %d, bearer %d, iapId %d, netId %d", iConnInfos[m].iConnectionId,
+                iConnInfos[m].iBearer, iConnInfos[m].iIapId, iConnInfos[m].iNetId)
+        }
+    #endif // _DEBUG
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::CompleteConnectionClosing
+// -----------------------------------------------------------------------------------
+//
+void CConnMonIAP::CompleteConnectionClosing( TInt& aIndex )
+    {
+    LOGENTRFN("CConnMonIAP::CompleteConnectionClosing()")
+
+    if ( iConnInfos[aIndex].iBearerNotifier->Listening() )
+        {
+        iConnInfos[aIndex].iBearerNotifier->CancelListen();
+        }
+
+    if ( iConnInfos[aIndex].iProgressNotifier->IsActive() )
+        {
+        // Progress notification request is still active --> Cancel it
+        iConnInfos[aIndex].iProgressNotifier->Cancel();
+        }
+    // Send KLinkLayerClosed event
+    LOGIT("CompleteConnectionClosing: ProgressNotifier->SendClosedEvent()")
+    iConnInfos[aIndex].iProgressNotifier->SendClosedEvent();
+
+    if ( iConnInfos[aIndex].iConnDownNotifier->IsActive() )
+        {
+        // Allinterface notification request is still active --> Cancel it
+        iConnInfos[aIndex].iConnDownNotifier->Cancel();
+        }
+
+    if ( !iConnInfos[aIndex].iConnDownNotifier->DeleteSent() )
+        {
+        // After SetInterfaceClosed() call SendDeletedEvent() removes
+        // the connection
+        iConnInfos[aIndex].iConnDownNotifier->SetInterfaceClosed();
+        iConnInfos[aIndex].iConnDownNotifier->SendDeletedEvent();
+        }
+    else
+        {
+        // Delete has already been sent (shouldn't be possible) so
+        // connection has to be removed
+        LOGIT("CompleteConnectionClosing: Delete already sent, removing connection")
+        RemoveConnection( iConnInfos[aIndex] );
+        }
+
+    LOGEXITFN("CConnMonIAP::CompleteConnectionClosing()")
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::RemoveConnection
+// Removes connection settings from sessions, stops and deletes event watchers and
+// removes the connection info from the iConnInfos array.
+// Connection is deleted by an event (or by calling RConnection::Stop()).
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::RemoveConnection( TConnInfo& aConnection )
+    {
+    LOGENTRFN("CConnMonIAP::RemoveConnection()")
+
+    TInt index( KErrNotFound );
+    // Check if bearer is external CSD
+    if ( aConnection.iBearer == EBearerExternalCSD ||
+            aConnection.iBearer == EBearerExternalHSCSD ||
+            aConnection.iBearer == EBearerExternalWcdmaCSD )
+        {
+        index = iConnInfos.Find( aConnection, TConnInfo::MatchBearer );
+        }
+    else if ( aConnection.iConnectionId > 0 )
+        {
+        index = iConnInfos.Find( aConnection, TConnInfo::MatchId );
+        }
+    else
+        {
+        index = iConnInfos.Find( aConnection, TConnInfo::MatchIap );
+        }
+
+    TInt err( KErrNotFound );
+    if ( index >= 0 )
+        {
+        // Set connection id for passing it back to the caller (client event)
+        aConnection.iConnectionId = iConnInfos[index].iConnectionId;
+
+        // Remove threshold settings from the client tables
+        iServer->RemoveConnSettingsFromSessions( aConnection.iConnectionId );
+
+        // Stop notifications (data volume, connection status, etc.)
+        DeleteConnNotifications( index );
+
+        // Close attached connection
+        if ( iConnInfos[index].iConnAttach != 0 )
+            {
+            iConnInfos[index].iConnAttach->Close();
+            delete iConnInfos[index].iConnAttach;
+            iConnInfos[index].iConnAttach = NULL;
+            }
+
+        iConnInfos.Remove( index );
+        err = KErrNone;
+        }
+
+    // Print connection info array to log
+    #ifdef _DEBUG
+    LOGIT("RemoveConnection: Connection info array:")
+    for ( TInt m = 0; m < iConnInfos.Count(); m++ )
+        {
+        LOGIT4("  id %d, bearer %d, iapId %d, netId %d", iConnInfos[m].iConnectionId,
+                iConnInfos[m].iBearer, iConnInfos[m].iIapId, iConnInfos[m].iNetId)
+        }
+    #endif // _DEBUG
+
+    LOGEXITFN1("CConnMonIAP::RemoveConnection()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::CalculateNetworkStatus
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::CalculateNetworkStatus( const RPacketService::TStatus& aPacketStatus ) const
+    {
+    switch ( aPacketStatus )
+        {
+        case ( RPacketService::EStatusUnattached ):
+            return EConnMonStatusUnattached;
+
+        case ( RPacketService::EStatusAttached ):
+            return EConnMonStatusAttached;
+
+        case ( RPacketService::EStatusActive ):
+            return EConnMonStatusActive;
+
+        case ( RPacketService::EStatusSuspended ):
+            return EConnMonStatusSuspended;
+
+        default:
+            break;
+        }
+    return aPacketStatus;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::CalculateNetworkRegistration
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::CalculateNetworkRegistration(
+        const RMobilePhone::TMobilePhoneRegistrationStatus&
+        aRegistration ) const
+    {
+    switch ( aRegistration )
+        {
+        case ( RMobilePhone::ERegistrationUnknown ):
+            return ENetworkRegistrationUnknown;
+
+        case ( RMobilePhone::ENotRegisteredNoService ):
+            return ENetworkRegistrationNoService;
+
+        case ( RMobilePhone::ENotRegisteredEmergencyOnly ):
+            return ENetworkRegistrationEmergencyOnly;
+
+        case ( RMobilePhone::ENotRegisteredSearching ):
+            return ENetworkRegistrationSearching;
+
+        case ( RMobilePhone::ERegisteredBusy ):
+            return ENetworkRegistrationBusy;
+
+        case ( RMobilePhone::ERegisteredOnHomeNetwork ):
+            return ENetworkRegistrationHomeNetwork;
+
+        case ( RMobilePhone::ERegistrationDenied ):
+            return ENetworkRegistrationDenied;
+
+        case ( RMobilePhone::ERegisteredRoaming ):
+            return ENetworkRegistrationRoaming;
+
+        default:
+            break;
+        }
+    return aRegistration;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::CalculateNetworkRegistration_v2
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::CalculateNetworkRegistration_v2(
+        const RMobilePhone::TMobilePhoneRegistrationStatus&
+        aRegistration ) const
+    {
+    switch ( aRegistration )
+        {
+        case ( RMobilePhone::ERegistrationUnknown ):
+            return ENetworkRegistrationExtUnknown;
+
+        case ( RMobilePhone::ENotRegisteredNoService ):
+            return ENetworkRegistrationExtNoService;
+
+        case ( RMobilePhone::ENotRegisteredEmergencyOnly ):
+            return ENetworkRegistrationExtEmergencyOnly;
+
+        case ( RMobilePhone::ENotRegisteredSearching ):
+            return ENetworkRegistrationExtSearching;
+
+        case ( RMobilePhone::ERegisteredBusy ):
+            return ENetworkRegistrationExtBusy;
+
+        case ( RMobilePhone::ERegisteredOnHomeNetwork ):
+            return ENetworkRegistrationExtHomeNetwork;
+
+        case ( RMobilePhone::ERegistrationDenied ):
+            return ENetworkRegistrationExtDenied;
+
+        case ( RMobilePhone::ERegisteredRoaming ):
+            {
+            RMobilePhone::TMobilePhoneNetworkInfoV1 network;
+            RMobilePhone::TMobilePhoneNetworkInfoV1Pckg networkPckg( network );
+
+            RMobilePhone::TMobilePhoneNetworkInfoV1 homeNetwork;
+            RMobilePhone::TMobilePhoneNetworkInfoV1Pckg homeNetworkPckg( homeNetwork );
+
+            TRequestStatus status( KErrNone );
+
+            iMobilePhone.GetCurrentNetwork(status, networkPckg);
+            User::WaitForRequest( status );
+
+            if(status.Int() == KErrNone)
+                {
+                iMobilePhone.GetHomeNetwork(status, homeNetworkPckg);
+                User::WaitForRequest( status );
+
+                if(network.iCountryCode.Compare(homeNetwork.iCountryCode) == 0)
+                    {
+                    return ENetworkRegistrationExtRoamingNational;
+                    }
+                else
+                    {
+                    return ENetworkRegistrationExtRoamingInternational;
+                    }
+                }
+          }
+
+        default:
+            break;
+        }
+    return aRegistration;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::IsEdgeCell
+// -----------------------------------------------------------------------------
+//
+TBool CConnMonIAP::IsEdgeCell()
+    {
+    LOGENTRFN("CConnMonIAP::IsEdgeCell()")
+    TBool edgeStatus( EFalse );
+
+    LOGTIMINGSTART("CConnMonIAP::IsEdgeCell")
+
+    if ( FeatureManager::FeatureSupported( KFeatureIdEdgeKnowledge ) )
+        {
+        RMmCustomAPI customApi;
+        RMmCustomAPI::TGprsInformation gprsInfo;
+        RMmCustomAPI::TGprsInformationPckg gprsInfoPckg( gprsInfo );
+        TRequestStatus status( KErrNone );
+
+        TInt ret = customApi.Open( iMobilePhone );
+
+        if ( KErrNone == ret )
+            {
+            customApi.GetEGprsInfo( status, gprsInfoPckg );
+            User::WaitForRequest( status );
+
+            customApi.Close();
+
+            if ( KErrNone == status.Int() )
+                {
+                if ( gprsInfoPckg().iGprsInfo == RMmCustomAPI::EEdgeGprs )
+                    {
+                    edgeStatus = ETrue;
+                    }
+                }
+            else
+                {
+                LOGIT1("IsEdgeCell: Error, RMmCustomAPI.GetEGprsInfo() <%d>", status.Int())
+                }
+            }
+        else
+            {
+            LOGIT1("IsEdgeCell: Error, RMmCustomAPI.Open() <%d>", ret)
+            }
+        }
+    else
+        {
+        LOGIT("IsEdgeCell: KFeatureIdEdgeKnowledge not supported")
+        }
+    LOGTIMINGEND("CConnMonIAP::IsEdgeCell")
+
+    LOGEXITFN1("CConnMonIAP::IsEdgeCell()", (TInt)edgeStatus)
+    return edgeStatus;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::IsHsdpaCell
+// -----------------------------------------------------------------------------
+//
+TBool CConnMonIAP::IsHsdpaCell()
+    {
+    LOGENTRFN("CConnMonIAP::IsHsdpaCell()")
+
+    RPacketService::TDynamicCapsFlags dynamicCaps( 0 );
+    TBool hsdpaStatus( EFalse );
+
+    LOGTIMINGSTART("CConnMonIAP::IsHsdpaCell")
+
+    TInt ret = iPacketService.GetDynamicCaps( dynamicCaps );
+    if ( dynamicCaps & RPacketService::KCapsHSDPA )
+        {
+        hsdpaStatus = ETrue;
+        }
+    LOGTIMINGEND("CConnMonIAP::IsHsdpaCell")
+    LOGIT2("IsHsdpaCell: Dynamic caps 0x%06X <%d>", dynamicCaps, ret)
+
+    LOGEXITFN1("CConnMonIAP::IsHsdpaCell()", (TInt)hsdpaStatus)
+    return hsdpaStatus;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::HsxpaStatus
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::HsxpaStatus()
+    {
+    LOGENTRFN("CConnMonIAP::HsxpaStatus()")
+
+    RPacketService::TDynamicCapsFlags dynamicCaps( 0 );
+    TInt hspaState( EBearerInfoWCDMA );
+
+    LOGTIMINGSTART("CConnMonIAP::HsxpaStatus")
+
+    TInt ret = iPacketService.GetDynamicCaps( dynamicCaps );
+    if ( dynamicCaps & RPacketService::KCapsHSDPA )
+        {
+        if ( dynamicCaps & RPacketService::KCapsHSUPA )
+            {
+            hspaState = EBearerInfoHSxPA;
+            }
+        else
+            {
+            hspaState = EBearerInfoHSDPA;
+            }
+        }
+    else
+        {
+        if ( dynamicCaps & RPacketService::KCapsHSUPA )
+            {
+            hspaState = EBearerInfoHSUPA;
+            }
+        else
+            {
+            hspaState = EBearerInfoWCDMA;
+            }
+        }
+    LOGTIMINGEND("CConnMonIAP::HsxpaStatus")
+    LOGIT2("HsxpaStatus: Dynamic caps 0x%06X <%d>", dynamicCaps, ret)
+
+    LOGEXITFN1("CConnMonIAP::HsxpaStatus()", hspaState)
+    return hspaState;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetStartTime
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetStartTime( const TUint& aConnectionId, TTime& aTime )
+    {
+    TInt err( KErrNone );
+
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    if ( iConnInfos[index].iBearer < EBearerExternalCSD
+         && iConnInfos[index].iBearerInfo.iBearer <= EBearerInfoHSxPA )
+        {
+        // INTERNAL CONNECTIONS
+        TUint subConnectionCount( 0 );
+
+        // Find the start time of the earliest subconnection
+        err = iConnInfos[index].iConnAttach->EnumerateSubConnections( subConnectionCount );
+
+        if ( KErrNone != err )
+            {
+            return err;
+            }
+
+        LOGIT1("GetStartTime: Sub connection count %d", subConnectionCount)
+        for ( TUint i = 1; i <= subConnectionCount; i++ )
+            {
+            TSubConnectionInfo subInfo;
+            TPckg<TSubConnectionInfo> pckgSubInfo( subInfo );
+
+            err = iConnInfos[index].iConnAttach->GetSubConnectionInfo( i, pckgSubInfo );
+
+            if ( KErrNone != err )
+                {
+                LOGIT2("GetStartTime: Error getting conn.info for index %d, <%d>", i, err)
+                return err;
+                }
+
+            if ( i == 1 )
+                {
+                aTime = pckgSubInfo().iTimeStarted;
+                }
+            else if ( aTime > pckgSubInfo().iTimeStarted )
+                {
+                aTime = pckgSubInfo().iTimeStarted;
+                }
+            }
+        }
+    else if ( iConnInfos[index].iBearer == EBearerExternalGPRS     ||
+              iConnInfos[index].iBearer == EBearerExternalEdgeGPRS ||
+              iConnInfos[index].iBearer == EBearerExternalWCDMA    ||
+              iConnInfos[index].iBearer == EBearerExternalCDMA2000 ||
+              ( !iConnInfos[index].iBearerInfo.iInternal &&
+                ( iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSDPA ||
+                  iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSUPA ||
+                  iConnInfos[index].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) )
+        {
+        // EXTERNAL PSD
+        if ( iPsdFax )
+            {
+            err = iPsdFax->GetStartTime( aConnectionId, aTime );
+
+            if ( KErrNone != err )
+                {
+                return err;
+                }
+            }
+        else
+            {
+            return KErrNotFound;
+            }
+        }
+    else if ( iConnInfos[index].iBearer == EBearerExternalCSD   ||
+              iConnInfos[index].iBearer == EBearerExternalHSCSD ||
+              iConnInfos[index].iBearer == EBearerExternalWcdmaCSD )
+        {
+        // EXTERNAL CSD
+        if ( iCsdFax )
+            {
+            err = iCsdFax->GetStartTime( aTime );
+
+            if ( KErrNone != err )
+                {
+                return err;
+                }
+            }
+        else
+            {
+            err = KErrNotFound;
+            }
+        }
+    else
+        {
+        return KErrNotSupported;
+        }
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetBearer
+// Gets the bearer setting for the internal connections.
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetBearer(
+        const TUint& aConnectionId,
+        TInt& aBearer,
+        TBearerInfo& aBearerInfo )
+    {
+    TInt err( KErrNone );
+    TUint32 bearerType( EBearerUnknown );
+    TBuf<KCommsDbSvrMaxFieldLength> settingName;
+    TBuf<KCommsDbSvrMaxFieldLength> settingValue;
+
+    LOGENTRFN("CConnMonIAP::GetBearer()")
+
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+    if ( index < 0 )
+        {
+        LOGEXITFN1("CConnMonIAP::GetBearer()", KErrNotFound)
+        return KErrNotFound;
+        }
+
+    if ( iConnInfos[index].iConnAttach == 0 )
+        {
+        LOGIT("GetBearer: error, iConnAttach was NULL")
+        LOGEXITFN1("CConnMonIAP::GetBearer()", KErrArgument)
+        return KErrArgument;
+        }
+
+    // Find out BEARER TYPE
+    settingName.Copy( TPtrC( IAP ) );
+    settingName.Append( TChar( '\\' ) );
+    settingName.Append( TPtrC( IAP_BEARER_TYPE ) );
+
+    err = iConnInfos[index].iConnAttach->GetDesSetting( TPtrC( settingName ), settingValue );
+    if ( KErrNone != err )
+        {
+        LOGIT1("GetBearer: ERROR getting IAP bearer type <%d>", err)
+        LOGEXITFN1("CConnMonIAP::GetBearer()", err)
+        return err;
+        }
+
+    if ( settingValue == TPtrC( VIRTUAL_BEARER ) )
+        {
+        aBearer = EBearerVirtual;
+        aBearerInfo.iBearer = EBearerInfoVirtual;
+        aBearerInfo.iInternal = ETrue;
+        }
+
+    // Find out SERVICE TYPE
+    settingName.Copy( TPtrC( IAP ) );
+    settingName.Append( TChar( '\\' ) );
+    settingName.Append( TPtrC( IAP_SERVICE_TYPE ) );
+
+    err = iConnInfos[index].iConnAttach->GetDesSetting( TPtrC( settingName ), settingValue );
+    if ( KErrNone != err )
+        {
+        LOGIT1("GetBearer: ERROR getting IAP service type <%d>", err)
+        LOGEXITFN1("CConnMonIAP::GetBearer()", err)
+        return err;
+        }
+
+    // Is this virtual bearer + VPN service
+    if ( ( aBearer == EBearerVirtual ) && ( settingValue == TPtrC( VPN_SERVICE ) ) )
+        {
+        aBearer = EBearerVirtualVPN;
+        aBearerInfo.iBearer = EBearerInfoVirtualVPN;
+        aBearerInfo.iInternal = ETrue;
+        }
+
+    // Return if bearer has been solved
+    if ( aBearer != EBearerUnknown )
+        {
+        LOGEXITFN1("CConnMonIAP::GetBearer()", KErrNone)
+        return KErrNone;
+        }
+
+    // Study service type if bearer is still unknown
+    if ( settingValue == TPtrC( DIAL_OUT_ISP ) || settingValue == TPtrC( DIAL_IN_ISP ) )
+        {
+        LOGIT("GetBearer: type is dial_x_isp")
+        settingName.Copy( settingValue );
+        settingName.Append( TChar( '\\' ) );
+        settingName.Append( TPtrC( ISP_BEARER_TYPE ) );
+
+        err = iConnInfos[index].iConnAttach->GetIntSetting( TPtrC( settingName ), bearerType );
+
+        if ( KErrNone != err )
+            {
+            return err;
+            }
+
+        if ( bearerType == EBearerTypeCSD )
+            {
+            aBearer = EBearerCSD;
+            aBearerInfo.iBearer = EBearerInfoCSD;
+            aBearerInfo.iInternal = ETrue;
+            }
+        else
+            {
+            // EBearerTypeHSCSD
+            aBearer = EBearerHSCSD;
+            aBearerInfo.iBearer = EBearerInfoHSCSD;
+            aBearerInfo.iInternal = ETrue;
+            }
+
+        if ( iTSYLoaded )
+            {
+            RMobilePhone::TMobilePhoneNetworkMode mode;
+
+            err = iMobilePhone.GetCurrentMode( mode );
+
+            if ( ( KErrNone == err ) && ( mode == RMobilePhone::ENetworkModeWcdma ) )
+                {
+                aBearer = EBearerWcdmaCSD;
+                aBearerInfo.iBearer = EBearerInfoWcdmaCSD;
+                aBearerInfo.iInternal = ETrue;
+                }
+            }
+
+        if ( aBearer == EBearerHSCSD || aBearer == EBearerCSD )
+            {
+            // If TsyName == PHONETSY try to find out the real life situation (CSD/HSCSD) from ETel
+            // For point-to-point connections TSY is NOT PHONETSY.
+            settingName.Copy( TPtrC( IAP ) );
+            settingName.Append( TChar( '\\' ) );
+            settingName.Append( TPtrC( IAP_BEARER_TYPE ) );
+
+            err = iConnInfos[index].iConnAttach->GetDesSetting(
+                    TPtrC( settingName ),
+                    settingValue );
+
+            if ( ( KErrNone == err ) && ( settingValue == TPtrC( MODEM_BEARER ) ) )
+                {
+                settingName.Copy( TPtrC( MODEM_BEARER ) );
+                settingName.Append( TChar( '\\' ) );
+                settingName.Append( TPtrC( MODEM_TSY_NAME ) );
+
+                err = iConnInfos[index].iConnAttach->GetDesSetting(
+                        TPtrC( settingName ),
+                        settingValue );
+
+                TBuf<KConnMonSmallBufferLen> tmp( KMmTsyModuleName );
+                tmp.UpperCase();
+
+                if ( ( KErrNone == err ) && ( settingValue == tmp ) )
+                    {
+                    // TSY is PHONETSY
+                    TBuf<KConnMonSmallBufferLen> number;
+
+                    err = GetTelNumber( aConnectionId, number );
+
+                    if ( KErrNone == err )
+                        {
+                        GetBearerFromETel( number, aBearer, aBearerInfo );
+                        }
+                    }
+                }
+            }
+        }
+    else if ( settingValue == TPtrC( OUTGOING_WCDMA ) ||
+              settingValue == TPtrC( INCOMING_WCDMA ) )
+        {
+        LOGIT("GetBearer: type is wcdma")
+        if ( iTSYLoaded )
+            {
+            RMobilePhone::TMobilePhoneNetworkMode mode;
+            err = iMobilePhone.GetCurrentMode( mode );
+            LOGIT2("GetBearer: phone mode %d <%d>", (TInt)mode, err)
+            if ( ( KErrNone != err ) ||
+                 ( mode == RMobilePhone::ENetworkModeUnknown ) ||
+                 ( mode == RMobilePhone::ENetworkModeUnregistered ) )
+                {
+                // MODE is UNKNOWN
+                LOGIT2("GetBearer: mode is unknown %d <%d>", mode, err)
+                if ( FeatureManager::FeatureSupported( KFeatureIdProtocolGsm ) )
+                    {
+                    // KFeatureIdProtocolGsm means that phone supports only GSM
+                    if ( IsEdgeCell() )
+                        {
+                        aBearer = EBearerEdgeGPRS;
+                        aBearerInfo.iBearer = EBearerInfoEdgeGPRS;
+                        }
+                    else
+                        {
+                        aBearer = EBearerGPRS;
+                        aBearerInfo.iBearer = EBearerInfoGPRS;
+                        }
+                    aBearerInfo.iInternal = ETrue;
+                    }
+                else
+                    {
+                    LOGIT("GetBearer: KFeatureIdProtocolGsm not supported")
+                    }
+                }
+            else
+                {
+                // MODE is KNOWN
+                if ( mode == RMobilePhone::ENetworkModeWcdma )
+                    {
+                    aBearer = EBearerWCDMA;
+                    aBearerInfo.iBearer = HsxpaStatus();
+                    aBearerInfo.iInternal = ETrue;
+                    }
+                else if ( mode == RMobilePhone::ENetworkModeGsm )
+                    {
+                    if ( IsEdgeCell() )
+                        {
+                        aBearer = EBearerEdgeGPRS;
+                        aBearerInfo.iBearer = EBearerInfoEdgeGPRS;
+                        }
+                    else
+                        {
+                        aBearer = EBearerGPRS;
+                        aBearerInfo.iBearer = EBearerInfoGPRS;
+                        }
+                    aBearerInfo.iInternal = ETrue;
+                    }
+                else
+                    {
+                    LOGIT1("GetBearer: error, mode was unexpected %d", mode)
+                    }
+                }
+            }
+        }
+
+    else if ( settingValue == TPtrC( LAN_SERVICE ) )
+        {
+        LOGIT("GetBearer: type is (w)lan")
+        aBearer = EBearerLAN;
+        aBearerInfo.iBearer = EBearerInfoLAN;
+        aBearerInfo.iInternal = ETrue;
+
+        settingName.FillZ();
+        settingValue.FillZ();
+        settingName.Copy( TPtrC( LAN_BEARER ) );
+        settingName.Append( TChar( '\\' ) );
+        settingName.Append( TPtrC( COMMDB_NAME ) );
+
+        err = iConnInfos[index].iConnAttach->GetDesSetting( TPtrC( settingName ), settingValue );
+
+        if ( KErrNone != err )
+            {
+            return err;
+            }
+
+        if ( settingValue == TPtrC( KWlanBearerRecordName ) )
+            {
+            aBearer = EBearerWLAN;
+            aBearerInfo.iBearer = EBearerInfoWLAN;
+            }
+        }
+    LOGIT2("GetBearer: bearer %d, bearerInfo %d", aBearer, aBearerInfo.iBearer)
+    LOGEXITFN1("CConnMonIAP::GetBearer()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::UpdateActivity
+// Updates connection activity information.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::UpdateActivity( const TUint& aConnectionId, const TUint& aActivity )
+    {
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    if ( aActivity == 0 )
+        {
+        iConnInfos[index].iActivity = 0;
+        }
+    else
+        {
+        iConnInfos[index].iActivity = 1;
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::GetDeleteNotifyStatus
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetDeleteNotifyStatus( TConnInfo& aConnection, TBool& aSent )
+    {
+    TInt index( KErrNotFound );
+
+    if ( aConnection.iBearer >= EBearerExternalCSD )
+        {
+        return KErrNotSupported;
+        }
+
+    index = iConnInfos.Find( aConnection, TConnInfo::MatchIap );
+
+    if ( index < 0 )
+        {
+        return KErrNotFound;
+        }
+
+    aConnection.iConnectionId = iConnInfos[index].iConnectionId;
+    aConnection.iBearer = iConnInfos[index].iBearer;
+
+    TInt connectionStatus( 0 );
+    GetConnectionStatus( index, connectionStatus );
+
+    if ( ( iConnInfos[index].iConnDownNotifier != 0 ) &&
+         ( iConnInfos[index].iProgressNotifier != 0 ) )
+        {
+        if ( !iConnInfos[index].iConnDownNotifier->DeleteSent() &&
+             !iConnInfos[index].iConnDownNotifier->IsActive() &&
+             ( !iConnInfos[index].iProgressNotifier->IsActive() ||
+               ( connectionStatus != KLinkLayerOpen ) ) )
+            {
+            aSent = EFalse;
+            }
+        else
+            {
+            aSent = ETrue;
+            }
+        }
+    else
+        {
+        aSent = EFalse;
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::GetActivityNotifier
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetActivityNotifier(
+        const TUint& aConnectionId,
+        CActivityNotifier** aActivityNotifier )
+    {
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    if ( aActivityNotifier == 0 )
+        {
+        return KErrUnknown;
+        }
+
+    *aActivityNotifier = iConnInfos[ index ].iActivityNotifier;
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::GetProgressNotifier
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetProgressNotifier(
+        const TUint& aConnectionId,
+        CProgressNotifier** aProgressNotifier )
+    {
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    if ( aProgressNotifier == 0 )
+        {
+        return KErrUnknown;
+        }
+
+    *aProgressNotifier = iConnInfos[index].iProgressNotifier;
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::GetSubConnUpDownNotifier
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetSubConnUpDownNotifier(
+        const TUint& aConnectionId,
+        CSubConnUpDownNotifier** aSubConnUpDownNotifier )
+    {
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    if ( aSubConnUpDownNotifier == 0 )
+        {
+        return KErrUnknown;
+        }
+
+    *aSubConnUpDownNotifier = iConnInfos[index].iConnDownNotifier;
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::WakeUpNotifications
+// Wakes up sleeping CONNECTION SPECIFIC event watchers that depend on a threshold.
+// (data volume, activity).
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::WakeUpNotifications( const TUint& aConnectionId )
+    {
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    if ( ( iConnInfos[index].iBearer < EBearerExternalCSD ) &&  ( iCountListeners > 0 ) )
+        {
+        // INTERNAL CONNECTIONS
+        TInt connectionStatus( 0 );
+        GetConnectionStatus( index, connectionStatus );
+
+        if ( ( connectionStatus == KLinkLayerOpen ) || ( connectionStatus == KPsdSuspended ) )
+            {
+            // -------------------------
+            // Amount of Downlink data
+            // -------------------------
+            if ( iConnInfos[index].iDLDataNotifier != 0 )
+                {
+                if ( !iConnInfos[index].iDLDataNotifier->IsActive() )
+                    {
+                    iConnInfos[index].iDLDataNotifier->Receive(); // (re)start listening
+                    }
+                }
+
+            // -------------------------
+            // Amount of Uplink data
+            // -------------------------
+            if ( iConnInfos[index].iULDataNotifier != 0 )
+                {
+                if ( !iConnInfos[index].iULDataNotifier->IsActive() )
+                    {
+                    iConnInfos[index].iULDataNotifier->Receive(); // (re)start listening
+                    }
+                }
+
+            // ----------------------
+            // Connection Activity
+            // ----------------------
+            if ( iConnInfos[index].iActivityNotifier != 0 )
+                {
+                if ( !iConnInfos[index].iActivityNotifier->IsActive() )
+                    {
+                    iConnInfos[index].iActivityNotifier->Receive( iConnInfos[index].iActivity );
+                    }
+                }
+
+            if ( iConnInfos[index].iBearerNotifier )
+                {
+                if ( !iConnInfos[index].iBearerNotifier->Listening() )
+                    {
+                    iConnInfos[index].iBearerNotifier->Listen();
+                    }
+                }
+            }
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::WakeUpNotifications
+// Wakes up GENERAL sleeping event watchers that depend on a threshold.
+// (signal strength, bearer availability).
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::WakeUpNotifications()
+    {
+    if ( iGSMSignalNotifier != 0 )
+        {
+        if ( !iGSMSignalNotifier->IsActive() )
+            {
+            iGSMSignalNotifier->Receive(); // (re)start listening
+            }
+        }
+
+    if ( iGSMBearerAvailabilityNotifier != 0 )
+        {
+        if ( !iGSMBearerAvailabilityNotifier->IsActive() )
+            {
+            iGSMBearerAvailabilityNotifier->Receive(); // (re)start listening
+            }
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::LaunchActivityNotifierL
+// Launches the activity notifier for the given connection id.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::LaunchActivityNotifierL( const TUint& aConnectionId )
+    {
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    GetActivityOneShotL( index );
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::LaunchDataNotifiers
+// Launches the data notifiers (uplink & downlink) for the given connection id.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::LaunchDataNotifiers( const TUint& aConnectionId )
+    {
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    if ( iConnInfos[index].iDLDataNotifier != 0 )
+        {
+        if ( !iConnInfos[index].iDLDataNotifier->IsActive() )
+            {
+            iConnInfos[index].iDLDataNotifier->Receive();
+            }
+        }
+
+    if ( iConnInfos[index].iULDataNotifier != 0 )
+        {
+        if ( !iConnInfos[index].iULDataNotifier->IsActive() )
+            {
+            iConnInfos[index].iULDataNotifier->Receive();
+            }
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::LaunchDataNotifiers
+// Launches the data notifiers (uplink & downlink) for the given connection id.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::LaunchBearerNotifier( const TUint& aConnectionId )
+    {
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    if ( iConnInfos[index].iBearerNotifier )
+        {
+        if ( !iConnInfos[index].iBearerNotifier->Listening() )
+            {
+            iConnInfos[index].iBearerNotifier->Listen();
+            }
+        }
+
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::AppendActiveConnections
+// -----------------------------------------------------------------------------
+//
+void CConnMonIAP::GetActiveConnectionsIds( const TUint& aBearerId, RArray<TUint>& aIdArray )
+    {
+    //LOGENTRFN("CConnMonIAP::GetActiveConnectionsIds()")
+
+    const TInt count = iConnInfos.Count();
+    for ( TInt i = 0; i < count; i++ )
+        {
+        // Bearer might still be uninitialized
+        if ( iConnInfos[i].iBearer == EBearerUnknown )
+            {
+            LOGIT1("GetActiveConnectionsIds: bearer unknown for conn.id %d",
+                    iConnInfos[i].iConnectionId)
+            TInt err = GetBearer(
+                    iConnInfos[i].iConnectionId,
+                    iConnInfos[i].iBearer,
+                    iConnInfos[i].iBearerInfo );
+
+            if ( KErrNone != err )
+                {
+                // Skip because bearer is unknown. This connection has not yet fully started.
+                continue;
+                }
+            }
+        switch ( iConnInfos[i].iBearer )
+            {
+            case EBearerGPRS:
+            case EBearerEdgeGPRS:
+            case EBearerWCDMA:
+                {
+                if ( aBearerId == EBearerIdGPRS )
+                    {
+                    aIdArray.Append( iConnInfos[i].iIapId );
+                    }
+                }
+                break;
+            case EBearerWLAN:
+                {
+                if ( aBearerId == EBearerIdWLAN )
+                    {
+                    TInt connectionStatus( 0 );
+                    GetConnectionStatus( i, connectionStatus );
+                    if ( connectionStatus == KLinkLayerOpen )
+                        {
+                        aIdArray.Append( iConnInfos[i].iIapId );
+                        }
+                    }
+                }
+                break;
+            case EBearerCSD:
+            case EBearerHSCSD:
+            case EBearerWcdmaCSD:
+                {
+                if ( aBearerId == EBearerIdCSD )
+                    {
+                    aIdArray.Append( iConnInfos[i].iIapId );
+                    }
+                }
+                break;
+            case EBearerLAN:
+                {
+                if ( aBearerId == EBearerIdLAN )
+                    {
+                    aIdArray.Append( iConnInfos[i].iIapId );
+                    }
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    //LOGEXITFN("CConnMonIAP::GetActiveConnectionsIds()")
+    }
+
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetBearerSupportInfo
+// Checks whether the current cell and the phone support a bearer (GPRS or CSD).
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetBearerSupportInfo(
+        const TUint aConnectionId,
+        TBool& aByCell,
+        TBool& aByPhone ) const
+    {
+    LOGENTRFN("CConnMonIAP::GetBearerSupportInfo()")
+    TInt err( KErrNone );
+
+    aByCell = EFalse;
+    aByPhone = EFalse;
+
+    if ( !iTSYLoaded  )
+        {
+        LOGIT("GetBearerSupportInfo: ERROR, TSY not loaded")
+        LOGEXITFN1("CConnMonIAP::GetBearerSupportInfo()", err)
+        return err;
+        }
+
+    RPacketService::TDynamicCapsFlags capsDynamic( 0 );
+    if ( iPacketServLoaded )
+        {
+        err = iPacketService.GetDynamicCaps( capsDynamic );
+        if ( KErrNone != err )
+            {
+            LOGIT1("GetBearerSupportInfo: ERROR getting dynamic caps <%d>", err)
+            capsDynamic = 0;
+            }
+        }
+
+    if ( aConnectionId == EBearerIdGPRS || aConnectionId == EBearerIdWCDMA )
+        {
+        LOGIT2("GetBearerSupportInfo: GPRS and WCDMA, dynamic caps:   0x%04X <%d>", capsDynamic, err)
+
+        // 1. Is GPRS/WCDMA supported by this NETWORK CELL
+        if ( ( capsDynamic & RPacketService::KCapsManualAttach ) ||
+             ( capsDynamic & RPacketService::KCapsManualDetach ) )
+            {
+            // Is the phone registered on the packet network
+            RPacketService::TRegistrationStatus nwRegStatus( RPacketService::EUnknown );
+            TRequestStatus status( KErrNone );
+            iPacketService.GetNtwkRegStatus( status, nwRegStatus );
+            User::WaitForRequest( status );
+
+            LOGIT2("GetBearerSupportInfo: pckt service ntwrk reg status:  %d <%d>", nwRegStatus, status.Int())
+            if ( KErrNone == status.Int() &&
+                 nwRegStatus != RPacketService::ENotRegisteredNotSearching &&
+                 nwRegStatus != RPacketService::ENotRegisteredSearching    &&
+                 nwRegStatus != RPacketService::ERegistrationDenied        &&
+                 nwRegStatus != RPacketService::ENotRegisteredAndNotAvailable )
+                {
+                // Query the TSY for the attach mode
+                RPacketService::TAttachMode attachMode( RPacketService::EAttachWhenNeeded );
+                err = iPacketService.GetAttachMode( attachMode );
+
+                LOGIT2("GetBearerSupportInfo: pckt service attach mode:       %d <%d>", attachMode, err)
+                // Query packet network status (but only if the TSY is set to attach when possible)
+                if ( KErrNone == err && attachMode == RPacketService::EAttachWhenPossible )
+                    {
+                    RPacketService::TStatus pcktStatus( RPacketService::EStatusUnattached );
+                    err = iPacketService.GetStatus( pcktStatus );
+
+                    LOGIT2("GetBearerSupportInfo: pckt service status:            %d <%d>", pcktStatus, err)
+                    if ( KErrNone == err && pcktStatus != RPacketService::EStatusUnattached )
+                        {
+                        aByCell = ETrue;
+                        }
+                    }
+                else
+                    {
+                    // Attach mode is 'EAttachWhenNeeded'
+                    aByCell = ETrue;
+                    }
+                }
+            }
+
+        // 2. Check the PHONE'S MODE if it is known
+        TUint bearerId( 0 );
+        err = GetBearerId( bearerId );
+
+        // If phone mode query failed, mode is unknown, or bearer ID equals connection ID.
+        if ( bearerId == 0 || bearerId == aConnectionId )
+            {
+            // 3. Check the PHONE'S MODE CAPABILITIES
+            TUint32 capsPhone( 0 );
+            err = iMobilePhone.GetMultimodeCaps( capsPhone );
+
+            LOGIT2("GetBearerSupportInfo: mobile phone mode caps:         0x%04X <%d>", capsPhone, err)
+            if ( KErrNone == err )
+                {
+                if ( aConnectionId == EBearerIdGPRS &&
+                     ( capsPhone & RMobilePhone::KCapsGprsSupported ) )
+                    {
+                    aByPhone = ETrue;
+                    }
+                else if ( aConnectionId == EBearerIdWCDMA &&
+                        ( capsPhone &
+                        ( RMobilePhone::KCapsWcdmaSupported |
+                        RMobilePhone::KCapsGprsSupported ) ) )
+                    {
+                    aByPhone = ETrue;
+                    }
+                }
+            }
+        }
+    else if ( aConnectionId == EBearerIdCSD || aConnectionId == EBearerIdWcdmaCSD )
+        {
+        LOGIT2("GetBearerSupportInfo: CSD and WcdmaCSD, dynamic caps: 0x%04X <%d>", capsDynamic, err)
+
+        // 1. Is CSD/WcdmaCSD supported by this NETWORK CELL
+        if ( capsDynamic & RPacketService::KCapsRxCSCall )
+            {
+            // Has phone registered to the network
+            TRequestStatus status( KErrNone );
+            RMobilePhone::TMobilePhoneRegistrationStatus gsmReg(
+                    RMobilePhone::ERegistrationUnknown );
+
+            iMobilePhone.GetNetworkRegistrationStatus( status, gsmReg );
+            User::WaitForRequest( status );
+
+            LOGIT2("GetBearerSupportInfo: mobile phone reg status:        %d <%d>", gsmReg, status.Int())
+            if ( KErrNone == status.Int() )
+                {
+                if ( gsmReg == RMobilePhone::ERegisteredBusy ||
+                        gsmReg == RMobilePhone::ERegisteredOnHomeNetwork ||
+                        gsmReg == RMobilePhone::ERegisteredRoaming )
+                    {
+                    aByCell = ETrue;
+                    }
+                }
+            }
+
+        // 2. Check the PHONE'S MODE if it is known
+        TUint bearerId( 0 );
+        err = GetBearerId( bearerId, ETrue );
+
+        // If phone mode query failed, mode is unknown, or bearer ID equals connection ID.
+        if ( bearerId == 0 || bearerId == aConnectionId )
+            {
+            // 3. Check the PHONE'S CAPABILITIES
+            err = iTelServer.IsSupportedByModule(
+                    KMmTsyModuleName,
+                    KETelFuncMobileDataCall,
+                    aByPhone );
+            }
+        }
+    else
+        {
+        LOGIT1("GetBearerSupportInfo: invalid connection id: %d", aConnectionId)
+        err = KErrArgument;
+        }
+
+    LOGIT2("GetBearerSupportInfo: by cell: %d, by phone: %d", aByCell, aByPhone)
+    LOGEXITFN1("CConnMonIAP::GetBearerSupportInfo()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::GetBearerId
+// Gets the bearer ID matching the phone's current mode.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetBearerId( TUint& aBearerId, TBool aCsd ) const
+    {
+    aBearerId = 0;
+    RMobilePhone::TMobilePhoneNetworkMode mode;
+    TInt err = iMobilePhone.GetCurrentMode( mode );
+    // If GetCurrentMode() failed for any reason, aBearerId will be 0.
+
+    LOGIT2("CConnMonIAP::GetBearerId(): current phone mode %d <%d>", mode, err)
+    if ( err == KErrNone )
+        {
+        switch ( mode )
+            {
+            case RMobilePhone::ENetworkModeWcdma:
+                if ( aCsd )
+                    {
+                    aBearerId  = EBearerIdWcdmaCSD;
+                    }
+                else
+                    {
+                    aBearerId  = EBearerIdWCDMA;
+                    }
+                break;
+
+            case RMobilePhone::ENetworkModeGsm:
+            case RMobilePhone::ENetworkModeUnknown: // Emulator default
+                if ( aCsd )
+                    {
+                    aBearerId = EBearerIdCSD;
+                    }
+                else
+                    {
+                    aBearerId = EBearerIdGPRS;
+                    }
+                break;
+
+            case RMobilePhone::ENetworkModeCdma2000:
+                aBearerId = EBearerIdCDMA2000;
+                break;
+
+            // ENetworkModeUnregistered
+            // ENetworkModeAmps
+            // ENetworkModeCdma95
+            // ENetworkModeTdcdma
+            default:
+                break;
+            }
+        }
+    return err;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::Reconnect
+// A new connection has been established by reconnecting to an old connection.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::Reconnect( TUint& aConnectionId )
+    {
+    LOGENTRFN("CConnMonIAP::Reconnect()")
+    TInt err( KErrNone );
+
+    TInt index = Index( aConnectionId );
+    if ( index < 0  )
+        {
+        //return KErrNotFound;
+        err = KErrNotFound;
+        }
+    else
+        {
+        // Prevent ConnDown notifier from being deleted
+        // It will destroy itself later in reconnect case.
+        iConnInfos[index].iConnDownNotifier = 0;
+        TBearerInfo bearerInfo( EBearerInfoUnknown, EFalse );
+
+        TConnInfo connInfo( iConnInfos[index].iIapId, iConnInfos[index].iNetId, 0, 0, bearerInfo );
+
+        // AddConnectionL will remove the old connection
+        TInt err2( KErrNone );
+        TRAP( err2, ( err = AddConnectionL( connInfo ) ) );
+        if ( ( err2 != KErrNone ) || ( err != KErrNone ) )
+            {
+            err = KErrUnknown;
+            }
+        else
+            {
+            aConnectionId = connInfo.iConnectionId;
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::Reconnect()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::WlanSupportCheck
+//
+// Returns KErrNone if the given connection ID is EBearerIdWLAN, or belongs to
+// an active connection where bearer has been marked as EBearerIdWLAN.
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::WlanSupportCheck( const TUint& aConnectionId )
+    {
+    LOGENTRFN("CConnMonIAP::WlanSupportCheck()")
+    TInt ret( KErrNotSupported );
+
+    // Check if WLAN is supported at all
+    if ( !iWlanSupport )
+        {
+        LOGIT("WlanSupportCheck: no WLAN support")
+        ret = KErrNotSupported;
+        }
+    else
+        {
+        if ( EBearerIdWLAN == aConnectionId )
+            {
+            ret = KErrNone;
+            }
+        else
+            {
+            // Find connection matching the given ID
+            TInt index = Index( aConnectionId );
+            LOGIT2("WlanSupportCheck: checking connection id %d, index %d ", aConnectionId, index)
+            if ( index < 0 )
+                {
+                ret = KErrArgument;
+                }
+            else
+                {
+                // Connection found, check if bearer is EBearerWLAN
+                if ( EBearerWLAN == iConnInfos[index].iBearer )
+                    {
+                    ret = KErrNone;
+                    }
+                else
+                    {
+                    LOGIT1("WlanSupportCheck: connection bearer %d is not WLAN", iConnInfos[index].iBearer)
+                    ret = KErrArgument;
+                    }
+                }
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::WlanSupportCheck()", ret)
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::AppendAvailableWLANIaps
+// Gets available WLAN IAPs from WLAN engine.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::AppendAvailableWLANIaps( RArray<TUint>& aIdArray )
+    {
+    //LOGENTRFN("CConnMonIAP::AppendAvailableWLANIaps()")
+    TInt err( KErrNone );
+
+    if ( !iWlanSupport )
+        {
+        LOGIT("AppendAvailableWLANIaps: No WLAN support")
+        err = KErrNotSupported;
+        }
+    else
+        {
+        err = iWlanSupport->AppendAvailableIaps( aIdArray );
+        }
+
+    //LOGEXITFN1("CConnMonIAP::AppendAvailableWLANIaps()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::AppendAvailableWLANIapsBySsid
+// Gets available WLAN IAPs from CommsDat, matching with current WLAN connection SSID.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::AppendAvailableWLANIapsBySsid( RArray<TUint>& aIdArray )
+    {
+    //LOGENTRFN("CConnMonIAP::AppendAvailableWLANIapsBySsid()")
+    TInt err( KErrNone );
+
+    if ( !iWlanSupport )
+        {
+        LOGIT("AppendAvailableWLANIapsBySsid: No WLAN support")
+        err = KErrNotSupported;
+        }
+    else
+        {
+        TRAPD( err2, err = iWlanSupport->AppendAvailableIapsBySsidL( aIdArray ) );
+        if ( err2 != KErrNone )
+            {
+            LOGIT1("AppendAvailableWLANIapsBySsid: error, LEAVE <%d> from AppendAvailableIapsBySsidL()", err2)
+            err = err2;
+            }
+        }
+
+    //LOGEXITFN1("CConnMonIAP::AppendAvailableWLANIapsBySsid()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::EnableWlanScan
+// Enables WLAN scan for the next iap availability query.
+// -----------------------------------------------------------------------------------
+//
+void CConnMonIAP::EnableWlanScan()
+    {
+    if ( iWlanSupport )
+        {
+        iWlanSupport->EnableWlanScan();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::DtmStateChanged
+// -----------------------------------------------------------------------------
+//
+void CConnMonIAP::DtmStateChanged()
+    {
+    LOGENTRFN("CConnMonIAP::DtmStateChanged()")
+
+    TEventInfo eventInfo;
+    eventInfo.Reset();
+
+    // When not in dual mode and call is active, gprs and wcdma bearers are unavailable
+    // Note that even the WCDMA can be unavailable, if the phone doesn't support DTM
+    if ( iDualTransferModeNotifier && !iDualTransferModeNotifier->IsInDualMode() &&
+            iTelephonyNotifier && iTelephonyNotifier->IsCallActive() )
+        {
+        LOGIT("SERVER: DtmStateChanged: Packet data UNAVAILABLE (2G&3G), no DTM and call is active")
+        eventInfo.iEventType = EConnMonPacketDataUnavailable;
+
+        // Send event to all clients that are listening for bearer EBearerIdGPRS
+        LOGIT("SERVER: EVENT -> Packet data UNAVAILABLE (GPRS), no DTM and call is active")
+        eventInfo.iConnectionId = EBearerIdGPRS;
+        iServer->EventQueue()->Add( eventInfo ); // Create bearer availability event if needed
+
+        // Send event to all clients that are listening for bearer EBearerIdWCDMA
+        LOGIT("SERVER: EVENT -> Packet data UNAVAILABLE (WCDMA), no DTM and call is active")
+        eventInfo.iConnectionId = EBearerIdWCDMA;
+        iServer->EventQueue()->Add( eventInfo );
+        }
+    else
+        {
+        TBool byPhone( EFalse );
+        TBool byCell( EFalse );
+
+        // Lets check if GPRS bearer is available at all
+        TInt ret = GetBearerSupportInfo( EBearerIdGPRS, byCell, byPhone );
+        LOGIT2("Bearer support (GPRS): byCell %d, byPhone %d", byCell, byPhone)
+        if ( ret != KErrNone )
+            {
+            LOGIT1("SERVER: DtmStateChanged: GetBearerSupportInfo (GPRS) returned error <%d>", ret)
+            return; // No event on error
+            }
+
+        eventInfo.iConnectionId = EBearerIdGPRS;
+        if ( byCell && byPhone )
+            {
+            LOGIT("SERVER: EVENT -> Packet data AVAILABLE (GPRS), DTM or no call is active")
+            eventInfo.iEventType = EConnMonPacketDataAvailable;
+            }
+        else
+            {
+            LOGIT("SERVER: EVENT -> Packet data UNAVAILABLE (GPRS), no GPRS bearer")
+            eventInfo.iEventType = EConnMonPacketDataUnavailable;
+            }
+        // Send event to all clients that are listening for bearer EBearerIdGPRS
+        iServer->EventQueue()->Add( eventInfo );
+
+
+        // Same for WCDMA as for GPRS above
+        ret = GetBearerSupportInfo( EBearerIdWCDMA, byCell, byPhone );
+        LOGIT2("Bearer support (WCDMA): byCell %d, byPhone %d", byCell, byPhone)
+        if ( ret != KErrNone )
+            {
+            LOGIT1("SERVER: DtmStateChanged: GetBearerSupportInfo (WCDMA) returned error <%d>", ret)
+            return; // No event on error
+            }
+
+        eventInfo.iConnectionId = EBearerIdWCDMA;
+        if ( byCell && byPhone )
+            {
+            LOGIT("SERVER: EVENT -> Packet data AVAILABLE (WCDMA), DTM or no call is active")
+            eventInfo.iEventType = EConnMonPacketDataAvailable;
+            }
+        else
+            {
+            LOGIT("SERVER: EVENT -> Packet data UNAVAILABLE (WCDMA), no WCDMA bearer")
+            eventInfo.iEventType = EConnMonPacketDataUnavailable;
+            }
+        // Send event to all clients that are listening for bearer EBearerIdWCDMA
+        iServer->EventQueue()->Add( eventInfo );
+        }
+
+    LOGEXITFN("CConnMonIAP::DtmStateChanged()")
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::PhoneLineStatusChange
+// -----------------------------------------------------------------------------
+//
+void CConnMonIAP::PhoneLineStatusChange()
+    {
+    LOGENTRFN("CConnMonIAP::PhoneLineStatusChange()")
+
+    // At this time the implementation would be identical
+    // to DtmStateChanged so we just call it
+    DtmStateChanged();
+
+    LOGEXITFN("CConnMonIAP::PhoneLineStatusChange()")
+    }
+
+
+// PRIVATE METHODS BELOW
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::OpenAndAttachTo
+// Opens and attaches an RConnection instance.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::OpenAndAttachTo( TConnInfo& aConnInfo )
+    {
+    //LOGENTRFN("CConnMonIAP::OpenAndAttachTo()")
+    TInt err( KErrNone );
+    TConnectionInfo info;
+    TPckg<TConnectionInfo> pckgInfo( info );
+
+    // Leave left out intentionally, check for NULL instead
+    aConnInfo.iConnAttach = new RConnection(); // No (ELeave)
+    if ( !aConnInfo.iConnAttach )
+        {
+        err = KErrNoMemory;
+        }
+    if ( KErrNone == err )
+        {
+        err = aConnInfo.iConnAttach->Open( iSocketServer, KAfInet );
+        }
+
+    if ( KErrNone == err )
+        {
+        info.iIapId = aConnInfo.iIapId;
+        info.iNetId = aConnInfo.iNetId;
+
+        err = aConnInfo.iConnAttach->Attach( pckgInfo, RConnection::EAttachTypeMonitor );
+        if ( err != KErrNone )
+            {
+            aConnInfo.iConnAttach->Close();
+            delete aConnInfo.iConnAttach;
+            }
+        }
+
+    //LOGEXITFN1("CConnMonIAP::OpenAndAttachTo()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::StopConnection
+// Closes a connection.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::StopConnection( const TInt aIndex )
+    {
+    LOGENTRFN("CConnMonIAP::StopConnection()")
+    TInt err( KErrNone );
+
+    if ( ( aIndex < 0 ) || ( aIndex >= iConnInfos.Count() ) )
+        {
+        LOGEXITFN1("CConnMonIAP::StopConnection()", KErrArgument)
+        return KErrArgument;
+        }
+
+    if ( iConnInfos[aIndex].iBearer < EBearerExternalCSD )
+        {
+        // Stop an internal connection
+        RConnection connection;
+        TConnectionInfo info;
+
+        // Cancel data volume and activity notifiers before stopping
+        if ( iConnInfos[aIndex].iDLDataNotifier != 0 )
+            {
+            iConnInfos[aIndex].iDLDataNotifier->Cancel();
+            }
+        if ( iConnInfos[aIndex].iULDataNotifier != 0 )
+            {
+            iConnInfos[aIndex].iULDataNotifier->Cancel();
+            }
+        if ( iConnInfos[aIndex].iDataVolumeAO != 0 )
+            {
+            iConnInfos[aIndex].iDataVolumeAO->Cancel();
+            }
+        if ( iConnInfos[aIndex].iActivityNotifier != 0 )
+            {
+            iConnInfos[aIndex].iActivityNotifier->Cancel();
+            }
+
+        // RConnection object with EAttachTypeNormal is needed for stopping
+        err = connection.Open( iSocketServer, KAfInet );
+        if ( KErrNone == err )
+            {
+            info.iIapId = iConnInfos[aIndex].iIapId;
+            info.iNetId = iConnInfos[aIndex].iNetId;
+
+            err = connection.Attach( TPckg<TConnectionInfo>( info ),
+                    RConnection::EAttachTypeNormal );
+            if ( KErrNone == err )
+                {
+                err = connection.Stop( RConnection::EStopAuthoritative );
+                if ( KErrNone == err )
+                    {
+                    // Stop notifications, delete connection settings and remove from the table
+                    // If conn up/down notifier is active, let the event remove connection later.
+                    if ( !iConnUpDownNotifier || !iConnUpDownNotifier->IsActive() )
+                        {
+                        RemoveConnection( iConnInfos[aIndex] );
+                        }
+                    }
+                else
+                    {
+                    LOGIT1("StopConnection: RConnection::Stop() failed <%d>", err)
+                    }
+                }
+            else
+                {
+                LOGIT1("StopConnection: RConnection::Attach() failed <%d>", err)
+                }
+            connection.Close();
+            }
+        else
+            {
+            LOGIT1("StopConnection: RConnection::Open() failed <%d>", err)
+            }
+        }
+
+    else if ( iConnInfos[aIndex].iBearer == EBearerExternalGPRS     ||
+              iConnInfos[aIndex].iBearer == EBearerExternalEdgeGPRS ||
+              iConnInfos[aIndex].iBearer == EBearerExternalWCDMA    ||
+              iConnInfos[aIndex].iBearer == EBearerExternalCDMA2000 ||
+              ( !iConnInfos[aIndex].iBearerInfo.iInternal &&
+                ( iConnInfos[aIndex].iBearerInfo.iBearer == EBearerInfoHSDPA ||
+                  iConnInfos[aIndex].iBearerInfo.iBearer == EBearerInfoHSUPA ||
+                  iConnInfos[aIndex].iBearerInfo.iBearer == EBearerInfoHSxPA ) ) )
+        {
+        // EXTERNAL PSD
+        if ( iPsdFax )
+            {
+            err = iPsdFax->Stop( iConnInfos[aIndex].iConnectionId );
+            }
+        else
+            {
+            err = KErrNotFound;
+            }
+        }
+
+    else if ( iConnInfos[aIndex].iBearer == EBearerExternalCSD   ||
+              iConnInfos[aIndex].iBearer == EBearerExternalHSCSD ||
+              iConnInfos[aIndex].iBearer == EBearerExternalWcdmaCSD )
+        {
+        // EXTERNAL CSD
+        if ( iCsdFax )
+            {
+            err = iCsdFax->Stop();
+            }
+        else
+            {
+            err = KErrNotFound;
+            }
+        }
+    else
+        {
+        err = KErrNotSupported;
+        }
+
+    LOGEXITFN1("CConnMonIAP::StopConnection()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::AddConnNotificationsL
+// Adds connection specific event watchers (connection status, data volume, activity).
+// -----------------------------------------------------------------------------------
+//
+void CConnMonIAP::AddConnNotificationsL( const TInt& aIndex )
+    {
+    LOGENTRFN("CConnMonIAP::AddConnNotificationsL()")
+
+    if ( iConnInfos[aIndex].iBearer < EBearerExternalCSD )
+        {
+        // INTERNAL CONNECTIONS
+        TInt connectionStatus( 0 );
+        GetConnectionStatus( aIndex, connectionStatus );
+
+        // ----------------------
+        // Connection Status
+        // ----------------------
+        if ( iConnInfos[aIndex].iProgressNotifier == 0 )
+            {
+            TInt subConnectionId( 0 );
+
+            // Create an active object and add it to scheduler
+            iConnInfos[aIndex].iProgressNotifier = new( ELeave ) CProgressNotifier(
+                    iServer,
+                    iConnInfos[aIndex].iConnAttach,
+                    iConnInfos[aIndex].iConnectionId,
+                    subConnectionId );
+
+            iConnInfos[aIndex].iProgressNotifier->Construct();
+
+            if ( iConnUpDownNotifier->IsActive() )
+                {
+                // Client is starting notifications. Filter old status events.
+                iConnInfos[aIndex].iProgressNotifier->Receive( connectionStatus );
+                }
+            else
+                {
+                // Event is starting notifification. No filtering is needed.
+                iConnInfos[aIndex].iProgressNotifier->Receive();
+                }
+            }
+
+        // -------------------------
+        // Amount of Downlink data
+        // -------------------------
+        if ( iConnInfos[aIndex].iDLDataNotifier == 0 )
+            {
+            TInt subConnectionId( 0 );
+
+            // Create an active object and add it to scheduler
+            iConnInfos[aIndex].iDLDataNotifier = new( ELeave ) CDataNotifier(
+                    iServer,
+                    iConnInfos[aIndex].iConnAttach,
+                    iConnInfos[aIndex].iConnectionId,
+                    subConnectionId,
+                    CDataNotifier::EDownlink);
+
+            iConnInfos[aIndex].iDLDataNotifier->Construct();
+
+            if ( ( connectionStatus == KLinkLayerOpen ) ||
+                 ( connectionStatus == KPsdSuspended ) )
+                {
+                iConnInfos[aIndex].iDLDataNotifier->Receive();
+                }
+            }
+
+        // -------------------------
+        // Amount of Uplink data
+        // -------------------------
+        if ( iConnInfos[aIndex].iULDataNotifier == 0 )
+            {
+            TInt subConnectionId( 0 );
+
+            // Create an active object and add it to scheduler
+            iConnInfos[aIndex].iULDataNotifier = new( ELeave ) CDataNotifier(
+                    iServer,
+                    iConnInfos[aIndex].iConnAttach,
+                    iConnInfos[aIndex].iConnectionId,
+                    subConnectionId,
+                    CDataNotifier::EUplink);
+
+            iConnInfos[aIndex].iULDataNotifier->Construct();
+
+            if ( ( connectionStatus == KLinkLayerOpen ) ||
+                 ( connectionStatus == KPsdSuspended ) )
+                {
+                iConnInfos[aIndex].iULDataNotifier->Receive();
+                }
+            }
+
+        // ---------------------------------------
+        // Connection down event with data volumes
+        // ---------------------------------------
+        if ( iConnInfos[aIndex].iConnDownNotifier == 0 )
+            {
+            TInt subConnectionId( 0 );
+
+            // Create an active object and add it to scheduler
+            iConnInfos[aIndex].iConnDownNotifier = new( ELeave ) CSubConnUpDownNotifier(
+                    iServer,
+                    iConnInfos[aIndex].iConnAttach,
+                    iConnInfos[aIndex].iConnectionId,
+                    subConnectionId );
+
+            iConnInfos[aIndex].iConnDownNotifier->Construct();
+
+            // Receiving will start only when connection status reaches KLinkLayerOpen
+            if ( ( connectionStatus == KLinkLayerOpen ) ||
+                 ( connectionStatus == KPsdSuspended ) )
+                {
+                iConnInfos[aIndex].iConnDownNotifier->Receive();
+                }
+            }
+
+        // ----------------------
+        // Connection Activity
+        // ----------------------
+        if ( iConnInfos[aIndex].iActivityNotifier == 0 )
+            {
+            // To update internal table fast at the first time
+            if ( ( connectionStatus == KLinkLayerOpen ) ||
+                 ( connectionStatus == KPsdSuspended ) )
+                {
+                GetActivityOneShotL( aIndex );
+                }
+            }
+        else
+            {
+            if ( !iConnInfos[aIndex].iActivityNotifier->IsActive() )
+                {
+                iConnInfos[aIndex].iActivityNotifier->Receive( iConnInfos[aIndex].iActivity );
+                }
+            }
+
+        // ----------------------
+        // Connection Bearer
+        // ----------------------
+        if ( iConnInfos[aIndex].iBearerNotifier == 0 )
+            {
+            // Create an active object and add it to scheduler
+            iConnInfos[aIndex].iBearerNotifier = CConnMonBearerNotifier::NewL(
+                    iServer,
+                    iMobilePhone,
+                    iConnInfos[aIndex].iConnectionId );
+
+            // Receiving will start only when connection status reaches KLinkLayerOpen
+            if ( ( connectionStatus == KLinkLayerOpen ) ||
+                 ( connectionStatus == KPsdSuspended ) )
+                {
+                iConnInfos[aIndex].iBearerNotifier->Listen();
+                }
+            }
+
+        // Note. iDataVolumeAO is created when client asks data volume info
+        }
+    LOGEXITFN("CConnMonIAP::AddConnNotificationsL()")
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::DeleteConnNotifications
+// Deletes event watchers owned by a connection
+// -----------------------------------------------------------------------------------
+//
+void CConnMonIAP::DeleteConnNotifications( const TInt& aIndex )
+    {
+    LOGENTRFN("CConnMonIAP::DeleteConnNotifications()")
+    if ( iConnInfos[ aIndex ].iBearer < EBearerExternalCSD )
+        {
+        if ( iConnInfos[ aIndex ].iProgressNotifier )
+            {
+            iConnInfos[ aIndex ].iProgressNotifier->Cancel();
+            delete iConnInfos[ aIndex ].iProgressNotifier;
+            iConnInfos[ aIndex ].iProgressNotifier = NULL;
+            }
+
+        if ( iConnInfos[ aIndex ].iDLDataNotifier )
+            {
+            iConnInfos[ aIndex ].iDLDataNotifier->Cancel();
+            delete iConnInfos[ aIndex ].iDLDataNotifier;
+            iConnInfos[ aIndex ].iDLDataNotifier = NULL;
+            }
+
+        if ( iConnInfos[ aIndex ].iULDataNotifier )
+            {
+            iConnInfos[ aIndex ].iULDataNotifier->Cancel();
+            delete iConnInfos[ aIndex ].iULDataNotifier;
+            iConnInfos[ aIndex ].iULDataNotifier = NULL;
+            }
+
+        if ( iConnInfos[ aIndex ].iDataVolumeAO )
+            {
+            iConnInfos[ aIndex ].iDataVolumeAO->Cancel();
+            delete iConnInfos[ aIndex ].iDataVolumeAO;
+            iConnInfos[ aIndex ].iDataVolumeAO = NULL;
+            }
+
+        if ( iConnInfos[ aIndex ].iConnDownNotifier )
+            {
+            iConnInfos[ aIndex ].iConnDownNotifier->Cancel();
+            delete iConnInfos[ aIndex ].iConnDownNotifier;
+            iConnInfos[ aIndex ].iConnDownNotifier = NULL;
+            }
+
+        if ( iConnInfos[ aIndex ].iActivityNotifier )
+            {
+            iConnInfos[ aIndex ].iActivityNotifier->Cancel();
+            delete iConnInfos[ aIndex ].iActivityNotifier;
+            iConnInfos[ aIndex ].iActivityNotifier = NULL;
+            }
+
+        if ( iConnInfos[ aIndex ].iBearerNotifier )
+            {
+            iConnInfos[ aIndex ].iBearerNotifier->CancelListen();
+            delete iConnInfos[ aIndex ].iBearerNotifier;
+            iConnInfos[ aIndex ].iBearerNotifier = NULL;
+            }
+        }
+    LOGEXITFN("CConnMonIAP::DeleteConnNotifications()")
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::DeleteNotifications
+// Deletes all the event watchers from the system (expect connection up/down events)
+// -----------------------------------------------------------------------------------
+//
+void CConnMonIAP::DeleteNotifications()
+    {
+    if( iTelephonyNotifier )
+        {
+        delete iTelephonyNotifier;
+        iTelephonyNotifier = NULL;
+        }
+
+    if( iDualTransferModeNotifier )
+        {
+        delete iDualTransferModeNotifier;
+        iDualTransferModeNotifier = NULL;
+        }
+
+    if ( iPsdNetwStatusNotifier )
+        {
+        // Cancel any outstanding requests
+        iPsdNetwStatusNotifier->Cancel();
+        delete iPsdNetwStatusNotifier;
+        iPsdNetwStatusNotifier = NULL;
+        }
+
+    if ( iNetwRegistrationNotifier )
+        {
+        // Cancel any outstanding requests
+        iNetwRegistrationNotifier->Cancel();
+        delete iNetwRegistrationNotifier;
+        iNetwRegistrationNotifier = NULL;
+        }
+
+    if ( iEdgeNotifier )
+        {
+        // Cancel any outstanding requests
+        iEdgeNotifier->Cancel();
+        delete iEdgeNotifier;
+        iEdgeNotifier = NULL;
+        }
+
+    if ( iWcdmaNotifier )
+        {
+        iWcdmaNotifier->Cancel();
+        delete iWcdmaNotifier;
+        iWcdmaNotifier = NULL;
+        }
+
+    if ( iModeNotifier )
+        {
+        // Cancel any outstanding requests
+        iModeNotifier->Cancel();
+        delete iModeNotifier;
+        iModeNotifier = NULL;
+        }
+
+    if ( iGSMSignalNotifier )
+        {
+        // Cancel any outstanding requests
+        iGSMSignalNotifier->Cancel();
+        delete iGSMSignalNotifier;
+        iGSMSignalNotifier = NULL;
+        }
+
+    if ( iGSMBearerAvailabilityNotifier )
+        {
+        // Cancel any outstanding requests
+        iGSMBearerAvailabilityNotifier->Cancel();
+        delete iGSMBearerAvailabilityNotifier;
+        iGSMBearerAvailabilityNotifier = NULL;
+        }
+
+    if ( iWlanSupport )
+        {
+        iWlanSupport->DisableEventsToClients();
+        }
+
+    // Delete notifications owned by the connections
+    TInt count = iConnInfos.Count();
+    for ( TInt i = 0; i < count; i++ )
+        {
+        DeleteConnNotifications( i );
+        }
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::NewConnectionId
+// Returns a new unique connection id for the connection.
+// -----------------------------------------------------------------------------------
+//
+TUint CConnMonIAP::NewConnectionId()
+    {
+    ++iIdCounter;
+
+    if ( iIdCounter == KMaxConnectionId )
+        {
+        iIdCounter = 1;
+        }
+
+    return iIdCounter;
+    }
+
+// -----------------------------------------------------------------------------------
+// CConnMonIAP::Index
+// Finds the index of the matching object within the array.
+// KErrNotFound, if no matching object can be found.
+// -----------------------------------------------------------------------------------
+//
+TInt CConnMonIAP::Index( const TUint& aConnectionId )
+    {
+    TInt count = iConnInfos.Count();
+    for ( TInt i = 0; i < count; i++ )
+        {
+        if ( iConnInfos[i].iConnectionId == aConnectionId )
+            {
+            return i;
+            }
+        }
+
+    return KErrNotFound;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetAccessPointName
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetAccessPointName( const TUint& aConnectionId, TDes& aName )
+    {
+    LOGENTRFN("CConnMonIAP::GetAccessPointName()")
+    TInt err( KErrNone );
+
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+    if ( index < 0  )
+        {
+        err = KErrNotFound;
+        }
+    else
+        {
+        // Find out access point name
+        TBuf<KCommsDbSvrMaxFieldLength> settingName;
+        TBuf<KCommsDbSvrMaxFieldLength> settingValue;
+        settingName.Copy( TPtrC( IAP ) );
+        settingName.Append( TChar( '\\' ) );
+        settingName.Append( TPtrC( IAP_SERVICE_TYPE ) );
+
+        err = iConnInfos[index].iConnAttach->GetDesSetting(
+                TPtrC( settingName ),
+                settingValue );
+        if ( KErrNone == err )
+            {
+            if ( settingValue == TPtrC( OUTGOING_WCDMA ) ||
+                    settingValue == TPtrC( INCOMING_WCDMA ) )
+                {
+                settingName.Copy( settingValue );
+                settingName.Append( TChar( '\\' ) );
+                settingName.Append( TPtrC( GPRS_APN ) );
+
+                err = iConnInfos[index].iConnAttach->GetDesSetting(
+                        TPtrC( settingName ),
+                        aName );
+                }
+            else
+                {
+                err = KErrNotFound;
+                }
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetAccessPointName()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetTelNumber
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetTelNumber( const TUint& aConnectionId, TDes& aTelNum )
+    {
+    LOGENTRFN("CConnMonIAP::GetTelNumber()")
+    TInt err( KErrNone );
+
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+    if ( index < 0  )
+        {
+        err = KErrNotFound;
+        }
+    else
+        {
+        // Find out tel. number
+        TBuf<KCommsDbSvrMaxFieldLength> settingName;
+        TBuf<KCommsDbSvrMaxFieldLength> settingValue;
+        settingName.Copy( TPtrC( IAP ) );
+        settingName.Append( TChar( '\\' ) );
+        settingName.Append( TPtrC( IAP_SERVICE_TYPE ) );
+
+        err = iConnInfos[index].iConnAttach->GetDesSetting(
+                TPtrC( settingName ),
+                settingValue );
+        if ( KErrNone == err )
+            {
+            if ( settingValue == TPtrC( DIAL_OUT_ISP ) ||
+                    settingValue == TPtrC( DIAL_IN_ISP ) )
+                {
+                settingName.Copy( settingValue );
+                settingName.Append( TChar( '\\' ) );
+                settingName.Append( TPtrC( ISP_DEFAULT_TEL_NUM ) );
+
+                err = iConnInfos[index].iConnAttach->GetDesSetting(
+                        TPtrC( settingName ),
+                        aTelNum );
+                }
+            else
+                {
+                err = KErrNotFound;
+                }
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetTelNumber()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetConnectionStatus
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetConnectionStatus( const TInt& aIndex, TInt& aConnectionStatus )
+    {
+    //LOGENTRFN("CConnMonIAP::GetConnectionStatus()")
+    TInt err( KErrNone );
+    TNifProgress nifProgress;
+
+    if ( ( aIndex < 0 ) || ( aIndex >= iConnInfos.Count() ) )
+        {
+        LOGIT1("GetConnectionStatus: invalid index value: %d", aIndex)
+        err = KErrArgument;
+        }
+    else
+        {
+        aConnectionStatus = 0;
+        err = iConnInfos[aIndex].iConnAttach->Progress( nifProgress );
+        if ( KErrNone == err )
+            {
+            aConnectionStatus = nifProgress.iStage;
+            LOGIT1("GetConnectionStatus: iConnAttach->Progress() status: %d", aConnectionStatus)
+            }
+        else
+            {
+            LOGIT1("GetConnectionStatus: ERROR getting progress status <%d>", err)
+            }
+        }
+
+    //LOGEXITFN1("CConnMonIAP::GetConnectionStatus()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetPsdNetworkStatus
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetPsdNetworkStatus( TInt& aNetworkStatus ) const
+    {
+    LOGENTRFN("CConnMonIAP::GetPsdNetworkStatus()")
+    TInt err( KErrNone );
+
+    if ( iTSYLoaded && iPacketServLoaded )
+        {
+        RPacketService::TStatus packetStatus;
+        err = iPacketService.GetStatus( packetStatus );
+        if ( KErrNone == err )
+            {
+            aNetworkStatus = CalculateNetworkStatus( packetStatus );
+            LOGIT1("GetPsdNetworkStatus: status %d", aNetworkStatus)
+            }
+        }
+    else
+        {
+        aNetworkStatus = EConnMonStatusUnattached;
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetPsdNetworkStatus()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetNetworkRegistrationMode
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetNetworkRegistrationMode( TInt& aRegistration ) const
+    {
+    return GetNetworkRegistration( aRegistration );
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetNetworkRegistration
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetNetworkRegistration( TInt& aRegistration ) const
+    {
+    LOGENTRFN("CConnMonIAP::GetNetworkRegistration()")
+    TInt err( KErrNone );
+
+    if ( !FeatureManager::FeatureSupported( KFeatureIdNetworkRegistration ) )
+        {
+        LOGIT("GetNetworkRegistration: KFeatureIdNetworkRegistration not supported")
+        err = KErrNotSupported;
+        }
+    else
+        {
+        if ( iTSYLoaded )
+            {
+            TRequestStatus status( KErrNone );
+            RMobilePhone::TMobilePhoneRegistrationStatus registration(
+                    RMobilePhone::ERegistrationUnknown );
+
+            iMobilePhone.GetNetworkRegistrationStatus( status, registration );
+            User::WaitForRequest( status );
+            err = status.Int();
+            if ( KErrNone == err )
+                {
+                aRegistration = CalculateNetworkRegistration( registration );
+                LOGIT1("GetNetworkRegistration: registration %d", aRegistration)
+                }
+            }
+        else
+            {
+            aRegistration = ENetworkRegistrationNotAvailable;
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetNetworkRegistration()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetNetworkRegistration_v2
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetNetworkRegistration_v2( TInt& aRegistration ) const
+    {
+    LOGENTRFN("CConnMonIAP::GetNetworkRegistration_v2()")
+    TInt err( KErrNone );
+
+    if ( !FeatureManager::FeatureSupported( KFeatureIdNetworkRegistration ) )
+        {
+        LOGIT("GetNetworkRegistration_v2: KFeatureIdNetworkRegistration not supported")
+        err = KErrNotSupported;
+        }
+    else
+        {
+        if ( iTSYLoaded )
+            {
+            TRequestStatus status( KErrNone );
+            RMobilePhone::TMobilePhoneRegistrationStatus registration(
+                    RMobilePhone::ERegistrationUnknown );
+
+            iMobilePhone.GetNetworkRegistrationStatus( status, registration );
+            User::WaitForRequest( status );
+            err = status.Int();
+            if ( KErrNone == err )
+                {
+                aRegistration = CalculateNetworkRegistration_v2( registration );
+                LOGIT1("GetNetworkRegistration_v2: registration <%d>", aRegistration )
+                }
+            }
+        else
+            {
+            aRegistration = ENetworkRegistrationExtNotAvailable;
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetNetworkRegistration_v2()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetGSMSignalStrength
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetGSMSignalStrength( TInt& aSignalStrength ) const
+    {
+    LOGENTRFN("CConnMonIAP::GetGSMSignalStrength()")
+    TInt err( KErrNone );
+
+    if ( iTSYLoaded )
+        {
+        TRequestStatus status( KErrNone );
+        TInt32 strength( 0 );
+        TInt8 bar( -1 );
+
+        iMobilePhone.GetSignalStrength( status, strength, bar );
+        User::WaitForRequest( status );
+
+        err = status.Int();
+        if ( KErrNone == err )
+            {
+            aSignalStrength = strength;
+            LOGIT1("GetGSMSignalStrength: strength %d", aSignalStrength)
+            }
+        }
+    else
+        {
+        err = KErrNotSupported;
+        }
+
+    LOGEXITFN1("CConnMonIAP::GetGSMSignalStrength()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetProtocolTypeL
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetProtocolTypeL( const TUint& aConnectionId, TInt& aProtocolType )
+    {
+    LOGENTRFN("CConnMonIAP::GetProtocolTypeL()")
+    TInt err( KErrNone );
+
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+    if ( index < 0  )
+        {
+        LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", KErrNotFound)
+        return KErrNotFound;
+        }
+
+    aProtocolType = EProtocolTypeUnknown;
+
+    if ( iTSYLoaded && iPacketServLoaded )
+        {
+        // Get AP name for the connection
+        TBuf<KCommsDbSvrMaxFieldLength> apName;
+
+        err = GetAccessPointName( iConnInfos[index].iConnectionId, apName );
+
+        if ( KErrNotFound == err )
+            {
+            LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err)
+            return err;
+            }
+
+        // Enumerate all PDP contexts
+        TRequestStatus status( KErrNone );
+        TInt contextCount( 0 );
+        TInt maxContextCount( 0 );
+
+        iPacketService.EnumerateContexts( status, contextCount, maxContextCount );
+        User::WaitForRequest( status );
+
+        err = status.Int();
+        if ( err != KErrNone )
+            {
+            LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err)
+            return err;
+            }
+
+        RPacketService::TContextInfo contextInfo;
+        RPacketContext context;
+        CleanupClosePushL( context );
+
+        // Find PDP contexts matching the given connectionId
+        for ( TInt i = 0; ( i < contextCount ) && ( aProtocolType != EProtocolTypeIP ); i++ )
+            {
+            iPacketService.GetContextInfo( status, i, contextInfo ); //iName, iStatus
+            User::WaitForRequest( status );
+
+            err = status.Int();
+            if ( err != KErrNone )
+                {
+                LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err)
+                return err;
+                }
+
+            err = context.OpenExistingContext( iPacketService, contextInfo.iName );
+            if ( err != KErrNone )
+                {
+                LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err)
+                return err;
+                }
+
+            RPacketContext::TContextConfigGPRS* getParams;
+            getParams = new( ELeave ) RPacketContext::TContextConfigGPRS();
+            TPckg<RPacketContext::TContextConfigGPRS> getContextConfigPckg( *getParams );
+
+            context.GetConfig( status, getContextConfigPckg );
+            User::WaitForRequest( status );
+
+            err = status.Int();
+            if ( KErrNone == err )
+                {
+                TInt ret = CompareAccessPointNames( apName, getParams->iAccessPointName );
+
+                if ( ret == 0 )
+                    {
+                    // PDP context matching the IAP connection found
+                    if ( getParams->iPdpType == RPacketContext::EPdpTypeIPv4 )
+                        {
+                        if ( aProtocolType == EProtocolTypeIPv6 )
+                            {
+                            aProtocolType = EProtocolTypeIP;    // Both 4 & 6
+                            }
+                        else
+                            {
+                            aProtocolType = EProtocolTypeIPv4;
+                            }
+                        }
+                    else if ( getParams->iPdpType == RPacketContext::EPdpTypeIPv6 )
+                        {
+                        if ( aProtocolType == EProtocolTypeIPv4 )
+                            {
+                            aProtocolType = EProtocolTypeIP;    // Both 4 & 6
+                            }
+                        else
+                            {
+                            aProtocolType = EProtocolTypeIPv6;
+                            }
+                        }
+                    else
+                        {
+                        aProtocolType = EProtocolTypeUnknown;
+                        }
+                    }
+                }
+
+            delete getParams;
+            context.Close();
+
+            if ( err != KErrNone )
+                {
+                break;
+                }
+            } // for
+        CleanupStack::PopAndDestroy( &context );
+        } // if
+
+    LOGEXITFN1("CConnMonIAP::GetProtocolTypeL()", err)
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetActivityOneShotL
+// -----------------------------------------------------------------------------
+//
+void CConnMonIAP::GetActivityOneShotL( const TInt& aIndex )
+    {
+    if ( iConnInfos[aIndex].iActivityNotifier == 0 )
+        {
+        iConnInfos[aIndex].iActivityNotifier = new( ELeave ) CActivityNotifier(
+                iServer,
+                iConnInfos[aIndex].iConnAttach,
+                iConnInfos[aIndex].iConnectionId,
+                0 );
+        iConnInfos[aIndex].iActivityNotifier->Construct();
+        }
+
+    if ( !iConnInfos[aIndex].iActivityNotifier->IsActive() )
+        {
+        iConnInfos[aIndex].iActivityNotifier->ReceiveOne(
+                iConnInfos[aIndex].iActivity );
+
+        // This AO will cancel the activity notifier after one second in case it has not completed.
+        // AO will destroy itself in RunL.
+        CTimerAO* timerAO = new( ELeave ) CTimerAO(
+                iServer,
+                iConnInfos[aIndex].iConnectionId,
+                iConnInfos[aIndex].iActivity );
+
+        CleanupStack::PushL( timerAO );
+        timerAO->ConstructL();
+        CleanupStack::Pop( timerAO );
+
+        timerAO->Start();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::GetBearerFromETel
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::GetBearerFromETel(
+        const TDes& aNumber,
+        TInt& aBearer,
+        TBearerInfo& aBearerInfo )
+    {
+    TInt ret( KErrNone );
+    TInt countCalls( 0 );
+    RLine line;
+    RMobileCall call;
+
+    // Get phone info
+    RTelServer::TPhoneInfo phoneInfo;
+    ret = iTelServer.GetPhoneInfo( 0, phoneInfo );
+    if ( KErrNone != ret )
+        {
+        return ret;
+        }
+
+    ret = line.Open( iMobilePhone, KMmTsyDataLineName );
+    if ( KErrNone != ret )
+        {
+        return ret;
+        }
+
+    // Enumerate calls on data line
+    ret = line.EnumerateCall( countCalls );
+    if ( KErrNone != ret )
+        {
+        line.Close();
+        return ret;
+        }
+
+    // Get call info
+    for ( TInt j = 0; j < countCalls; j++ )
+        {
+        RLine::TCallInfo callInfo;
+
+        ret = line.GetCallInfo( j, callInfo );
+        if ( KErrNone != ret )
+            {
+            line.Close();
+            return ret;
+            }
+
+        if ( callInfo.iStatus != RCall::EStatusIdle )
+            {
+            TName callName;
+
+            callName.Copy( phoneInfo.iName );
+            callName.Append( KDoubleColon );
+            callName.Append( KMmTsyDataLineName );
+            callName.Append( KDoubleColon );
+            callName.Append( callInfo.iCallName );
+
+            ret = call.OpenExistingCall( iTelServer, callName );
+            if ( KErrNone != ret )
+                {
+                line.Close();
+                return ret;
+                }
+
+            RMobileCall::TMobileCallInfoV1 info;
+            RMobileCall::TMobileCallInfoV1Pckg infoPckg( info );
+
+            ret = call.GetMobileCallInfo( infoPckg );
+            if ( KErrNone == ret )
+                {
+                if ( infoPckg().iRemoteParty.iRemoteNumber.iTelNumber.Length() > 0 )
+                    {
+                    ret = aNumber.Compare( infoPckg().iRemoteParty.iRemoteNumber.iTelNumber );
+                    }
+                else if ( infoPckg().iDialledParty.iTelNumber.Length() > 0 )
+                    {
+                    ret = aNumber.Compare( infoPckg().iDialledParty.iTelNumber );
+                    }
+                else
+                    {
+                    ret = KErrNotFound;
+                    }
+
+                if ( ret == 0 )
+                    {
+                    aBearer = EBearerCSD;
+                    aBearerInfo.iBearer = EBearerInfoCSD;
+                    aBearerInfo.iInternal = ETrue;
+
+                    RMobileCall::TMobileCallHscsdInfoV1 hscsdInfo;
+                    RMobileCall::TMobileCallHscsdInfoV1Pckg hscsdInfoPckg( hscsdInfo );
+
+                    ret = call.GetCurrentHscsdInfo( hscsdInfoPckg );
+                    if ( KErrNone == ret )
+                        {
+                        if ( hscsdInfo.iAiur != RMobileCall::EAiurBpsUnspecified )
+                            {
+                            aBearer = EBearerHSCSD;
+                            aBearerInfo.iBearer = EBearerInfoHSCSD;
+                            }
+                        }
+                    call.Close();
+                    line.Close();
+                    return KErrNone;
+                    }
+                }
+            call.Close();
+            }
+        } // for
+    line.Close();
+    return KErrNotFound;
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::CompareAccessPointNames
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::CompareAccessPointNames(
+        const TDesC& aNameFromCommDB,
+        const TDesC& aNameFromETel ) const
+    {
+    return ( aNameFromETel.Compare( aNameFromCommDB ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::CompareAccessPointNames
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::CompareAccessPointNames(
+        const TDesC& aNameFromCommDB,
+        const TDesC8& aNameFromETel ) const
+    {
+    TBuf<KCommsDbSvrMaxFieldLength> tempBuffer;
+
+    CnvUtfConverter::ConvertToUnicodeFromUtf8( tempBuffer, aNameFromETel );
+
+    return( tempBuffer.Compare( aNameFromCommDB ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::SendConnectionEvents
+// -----------------------------------------------------------------------------
+//
+void CConnMonIAP::SendConnectionEvents( TConnMonBearerInfo& /*aBearerinfo*/ )
+    {
+    if ( iConnInfos.Count() > 0 )
+        {
+        for ( TInt i = 0; i < iConnInfos.Count(); i++ )
+            {
+            if ( iConnInfos[i].iBearerNotifier )
+                {
+                iConnInfos[i].iBearerNotifier->SendBearerInfoEvent();
+                iConnInfos[i].iBearerNotifier->SendBearerGroupEvent();
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CConnMonIAP::LastProgressError
+// -----------------------------------------------------------------------------
+//
+TInt CConnMonIAP::LastProgressError(
+        const TUint& aConnectionId,
+        TNifProgress& aProgress )
+    {
+    TInt err( KErrNone );
+
+    // Find connection matching the given Id
+    TInt index = Index( aConnectionId );
+
+    if ( index < 0  )
+        {
+        return KErrNotFound;
+        }
+
+    err = iConnInfos[index].iConnAttach->LastProgressError( aProgress );
+
+    LOGIT3("iConnection->Progress() ret <%d> stage %d error <%d>", err, aProgress.iStage, aProgress.iError)
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// CConnMonIAP::WlanRssGoodEnough
+// ---------------------------------------------------------------------------
+//
+TBool CConnMonIAP::WlanRssGoodEnough()
+    {
+    //LOGENTRFN("CConnMonIAP::WlanRssGoodEnough()")
+    TBool value( EFalse );
+
+    if ( !iWlanSupport )
+        {
+        LOGIT("WlanRssGoodEnough: No WLAN support")
+        value = EFalse;
+        }
+    else
+        {
+        value = iWlanSupport->WlanRssGoodEnough();
+        }
+
+    //LOGEXITFN1("CConnMonIAP::WlanRssGoodEnough()", value)
+    return value;
+    }
+
+// ---------------------------------------------------------------------------
+// CConnMonIAP::DiscoverBearerId
+// ---------------------------------------------------------------------------
+//
+TInt CConnMonIAP::BearerIdForBearerAvailability(
+        const TUint& aConnId,
+        TUint& aBearerId )
+    {
+    LOGENTRFN("CConnMonIAP::BearerIdForBearerAvailability()")
+    TInt err( KErrNone );
+
+    TInt index = Index( aConnId );
+    if ( index < 0 )
+        {
+        // Bearer specific connection id given as attribute
+        switch ( aConnId )
+            {
+            case EBearerIdWLAN:     aBearerId = EBearerIdWLAN;      break;
+            case EBearerIdGPRS:     aBearerId = EBearerIdGPRS;      break;
+            case EBearerIdWCDMA:    aBearerId = EBearerIdWCDMA;     break;
+            case EBearerIdCSD:      aBearerId = EBearerIdCSD;       break;
+            case EBearerIdWcdmaCSD: aBearerId = EBearerIdWcdmaCSD;  break;
+            // Let session send this request to the plugin
+            case EBearerIdLAN:      err = KErrCancel;               break;
+            default:                err = KErrNotFound;             break;
+            }
+        }
+    else
+        {
+        // Valid connection id given as attribute
+        switch ( iConnInfos[index].iBearer )
+            {
+            case EBearerWLAN:               aBearerId = EBearerIdWLAN;      break;
+            case EBearerGPRS:
+            case EBearerEdgeGPRS:
+            case EBearerExternalGPRS:
+            case EBearerExternalEdgeGPRS:   aBearerId = EBearerIdGPRS;      break;
+            case EBearerWCDMA:
+            case EBearerExternalWCDMA:      aBearerId = EBearerIdWCDMA;     break;
+            case EBearerCSD:
+            case EBearerHSCSD:
+            case EBearerExternalCSD:
+            case EBearerExternalHSCSD:      aBearerId = EBearerIdCSD;       break;
+            case EBearerWcdmaCSD:
+            case EBearerExternalWcdmaCSD:   aBearerId = EBearerIdWcdmaCSD;  break;
+            // Let session send this request to the plugin
+            case EBearerLAN:                err = KErrCancel;               break;
+            default:                        err = KErrNotSupported;         break;
+            }
+        }
+
+    LOGEXITFN1("CConnMonIAP::BearerIdForBearerAvailability()", err)
+    return err;
+    }
+
+// End-of-file