bearermanagement/mpm/src/mpmserver.cpp
changeset 0 5a93021fdf25
child 3 f7816ffc66ed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bearermanagement/mpm/src/mpmserver.cpp	Thu Dec 17 08:55:21 2009 +0200
@@ -0,0 +1,2191 @@
+/*
+* Copyright (c) 2004-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: MPM server implementation
+*
+*/
+
+/**
+@file mpmserver.cpp
+Mobility Policy Manager server implementation.
+*/
+
+// INCLUDE FILES
+#include <commdb.h>
+#include <etel3rdparty.h>                // Voice call notification
+#include <mmtsy_names.h>                 // KMmTsyModuleName
+#include <centralrepository.h>
+
+#include "mpmserver.h"
+#include "mpmserversession.h"
+#include "mpmconnmonevents.h"
+#include "mpmlogger.h"
+#include "mpmdtmwatcher.h"
+#include "mpmroamingwatcher.h"
+#include "mpmdisconnectdlg.h"
+#include "mpmconfirmdlgroaming.h"
+#include "mpmconfirmdlgstarting.h"
+#include "mpmdefaultconnection.h"
+#include "mpmcommsdataccess.h"
+#include "mpmwlanquerydialog.h"
+#include "mpmdialog.h"
+#include "mpmprivatecrkeys.h"
+#include "mpmcsidwatcher.h"
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// PanicServer 
+// Panics the server in case of programming error.
+// -----------------------------------------------------------------------------
+//
+void PanicServer( TInt aPanic )
+    {
+    User::Panic( KMPMPanicCategory, aPanic );
+    }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMPMServer::NewL
+// -----------------------------------------------------------------------------
+//
+CMPMServer* CMPMServer::NewL()
+    {
+    CMPMServer* self = new ( ELeave ) CMPMServer();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::CMPMServer
+// -----------------------------------------------------------------------------
+//
+CMPMServer::CMPMServer()
+    : CPolicyServer( CPolicyServer::EPriorityStandard, KMPMPolicy ),
+      iEvents( NULL ), 
+      iTSYLoaded( EFalse ),
+      iPacketServLoaded( EFalse ), 
+      iDtmWatcher( NULL ), 
+      iWLANScanRequired( EFalse ), 
+      iDisconnectQueue( NULL ), 
+      iRoamingQueue( NULL ), 
+      iStartingQueue( NULL ),
+      iWlanQueryQueue( NULL ),
+      iConnectDialogQueue( NULL ),
+      iDefaultConnection( NULL ), 
+      iConnectionCounter( 0 )
+    {
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::ConstructL()
+    {
+    // identify ourselves and open for service
+    MPMLOGSTRING( "MPMServer is starting" )
+    StartL( KMPMServerName );
+
+    // Connect to ETel server
+    // The RTelServer::Connect() might not always work with the first trial,
+    // because of a coding error related to using semaphores in the method.
+    TInt err( KErrNotReady );
+    TInt a = 0;
+    while( a < KPhoneRetryCount && err != KErrNone )
+        {
+        User::After( KPhoneRetryTimeout );
+        err = iTelServer.Connect();
+        a++;       
+        }
+    User::LeaveIfError( err );
+       
+    // Try to load phone.tsy
+    TBuf< KCommsDbSvrMaxColumnNameLength > tsyName;
+    tsyName.Copy( KMmTsyModuleName );
+    err = iTelServer.LoadPhoneModule( tsyName );
+
+    if ( err == KErrNone )
+        {
+        iTSYLoaded = ETrue;
+        // Phone info can be retrieved with value 0 if there is only 1 phone
+        RTelServer::TPhoneInfo info;
+        User::LeaveIfError( iTelServer.GetPhoneInfo( 0, info ) );
+        User::LeaveIfError( iMobilePhone.Open( iTelServer, info.iName ) );
+
+        // Open packet service
+        err = iPacketService.Open( iMobilePhone );
+        if ( err == KErrNone )
+            {
+            iPacketServLoaded = ETrue;
+            iDtmWatcher = CMPMDtmWatcher::NewL( iPacketService );
+            }
+#ifdef _DEBUG
+        else
+            {
+            MPMLOGSTRING2( 
+                "CMPMServer::ConstructL iPacketService.Open error: %d", err )  
+            }
+#endif // _DEBUG
+        }
+    
+    iRoamingWatcher = CMPMRoamingWatcher::NewL(iMobilePhone);
+
+    iCommsDatAccess = CMPMCommsDatAccess::NewL( );
+    
+    iDisconnectQueue = new ( ELeave ) CArrayPtrFlat<CMPMDisconnectDlg>( KGranularity );
+    iDisconnectQueue->Reset();
+
+    iRoamingQueue = new ( ELeave ) CArrayPtrFlat<CMPMConfirmDlgRoaming>( KGranularity );
+    iRoamingQueue->Reset();
+
+    iStartingQueue = new ( ELeave ) CArrayPtrFlat<CMPMConfirmDlgStarting>( KGranularity ); 
+    iStartingQueue->Reset();
+
+    iWlanQueryQueue = new ( ELeave ) CArrayPtrFlat<CMPMWlanQueryDialog>( KGranularity );
+    iWlanQueryQueue->Reset();
+
+    iConnectDialogQueue = new ( ELeave ) CArrayPtrFlat<CMPMDialog>( KGranularity );
+    iConnectDialogQueue->Reset();
+    
+    iDefaultConnection = CMPMDefaultConnection::NewL( this );    
+
+    // Create central repository watcher and start it
+    iMpmCsIdWatcher = CMpmCsIdWatcher::NewL();
+    iMpmCsIdWatcher->StartL();
+
+    // Define P&S keys (snap & iap) for the user connection
+    TInt ret = RProperty::Define( KMPMUserConnectionCategory,
+                                  KMPMPSKeyUserConnectionSnap,
+                                  KMPMUserConnectionSnapType,
+                                  KMPMUserConnectionReadPolicy,
+                                  KMPMUserConnectionWritePolicy );
+    
+    if ( (ret != KErrNone) && (ret != KErrAlreadyExists) )
+        {
+        User::Leave(err);
+        }
+    
+    ret = RProperty::Define( KMPMUserConnectionCategory,
+                             KMPMPSKeyUserConnectionIap,
+                             KMPMUserConnectionIapType,
+                             KMPMUserConnectionReadPolicy,
+                             KMPMUserConnectionWritePolicy );
+                                          
+    if ( (ret != KErrNone) && (ret != KErrAlreadyExists) )
+        {
+        User::Leave(err);
+        }
+
+    // Set initial values for the keys
+    User::LeaveIfError(RProperty::Set( KMPMUserConnectionCategory,
+                                       KMPMPSKeyUserConnectionSnap,
+                                       0 ));
+
+    User::LeaveIfError(RProperty::Set( KMPMUserConnectionCategory,
+                                       KMPMPSKeyUserConnectionIap,
+                                       0 ));
+
+    // Read dedicated clients from the central repository
+    CRepository* repository = CRepository::NewL( KCRUidMPM );
+    
+    CleanupStack::PushL( repository );
+    
+    TUint32 baseKey = KMpmDedicatedClientBase;
+    TInt value;
+    ret = KErrNone;
+    
+    while ( ret == KErrNone )
+        {
+        ret = repository->Get ( baseKey, value );
+
+        if ( ret == KErrNone )
+            {
+            iDedicatedClients.AppendL( value );
+            MPMLOGSTRING2( "CMPMServer::ConstructL: Dedicated client id: %d", value)
+            }
+
+        baseKey++;
+        }
+    
+    CleanupStack::PopAndDestroy ( repository );
+    
+    // Define P&S keys for the connection dialogs
+    ret = RProperty::Define( KMPMActiveConnectionCategory,
+                             KMPMPSKeyActiveConnectionIap,
+                             KMPMActiveConnectionIapType,
+                             KMPMActiveConnectionReadPolicy,
+                             KMPMActiveConnectionWritePolicy );
+    
+    if ( (ret != KErrNone) && (ret != KErrAlreadyExists) )
+        {
+        User::Leave(err);
+        }
+    
+    ret = RProperty::Define( KMPMActiveConnectionCategory,
+                             KMPMPSKeyActiveConnectionSnap,
+                             KMPMActiveConnectionSnapType,
+                             KMPMActiveConnectionReadPolicy,
+                             KMPMActiveConnectionWritePolicy );
+    
+    if ( (ret != KErrNone) && (ret != KErrAlreadyExists) )
+        {
+        User::Leave(err);
+        }
+
+    ret = RProperty::Define( KMPMActiveConnectionCategory,
+                             KMPMPSKeyActiveConnectionBearer,
+                             KMPMActiveConnectionBearerType,
+                             KMPMActiveConnectionReadPolicy,
+                             KMPMActiveConnectionWritePolicy );
+                                          
+    if ( (ret != KErrNone) && (ret != KErrAlreadyExists) )
+        {
+        User::Leave(err);
+        }
+        
+    PublishActiveConnection();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::~CMPMServer
+// -----------------------------------------------------------------------------
+//
+CMPMServer::~CMPMServer()
+    {
+    if ( iDisconnectQueue )
+        {
+        iDisconnectQueue->ResetAndDestroy();
+        }
+    delete iDisconnectQueue;
+
+    if ( iRoamingQueue )
+        {
+        iRoamingQueue->ResetAndDestroy();
+        }
+    delete iRoamingQueue;
+
+    if ( iStartingQueue )
+        {
+        iStartingQueue->ResetAndDestroy();
+        }
+    delete iStartingQueue;
+
+    while ( iWlanQueryQueue && iWlanQueryQueue->Count() > 0 )
+        {
+        iWlanQueryQueue->Delete( 0 );
+        }
+    delete iWlanQueryQueue;
+    
+    if ( iConnectDialogQueue )
+        {
+        iConnectDialogQueue->ResetAndDestroy();
+        }
+    delete iConnectDialogQueue;
+
+    delete iEvents;
+
+    for ( TInt i = 0; i < iBlackListIdList.Count(); i++ )
+        {
+        iBlackListIdList[i].Close();
+        }
+
+    iActiveBMConns.Close();
+    iSessions.Close();
+
+    delete iDtmWatcher;
+    delete iRoamingWatcher;
+
+    // Close "global" ETEL objects
+    if ( iPacketServLoaded )
+        {
+        iPacketService.Close();
+        }    
+
+    iMobilePhone.Close();
+    iTelServer.Close();
+    
+    delete iDefaultConnection;
+    
+    delete iMpmCsIdWatcher;    
+    
+    iDedicatedClients.Close();
+
+    delete iCommsDatAccess;    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::NewSessionL
+// -----------------------------------------------------------------------------
+//
+CSession2* CMPMServer::NewSessionL(
+    const TVersion& aVersion,
+    const RMessage2& /*aMessage*/) const
+    {
+    MPMLOGSTRING( "CMPMServer::NewSessionL" )
+    // Check we're the right version
+    if ( !User::QueryVersionSupported(TVersion(KMPMServerMajorVersionNumber,
+                                               KMPMServerMinorVersionNumber,
+                                               KMPMServerBuildVersionNumber ),
+                                     aVersion ) )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    CSession2* session = CMPMServerSession::NewL( 
+                             *const_cast<CMPMServer*>( this ));
+    return session;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::PanicClient
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::PanicClient(
+    const TInt aPanic) const
+    {
+    // let's have a look before we panic the client
+    __DEBUGGER()
+    // ok, go for it
+    RThread clientThread;
+
+    TInt err = Message().Client( clientThread );
+
+    if ( err == KErrNone )
+        {
+        clientThread.Panic( KMPMServerName, aPanic );
+        clientThread.Close();
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::AppendBMConnection
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::AppendBMConnection( const TConnectionId aConnId, 
+                                     const TUint32       aSnap,
+                                     const TUint32       aIapId, 
+                                     TConnectionState    aState,
+                                     CMPMServerSession&  aSession )
+    {
+    MPMLOGSTRING3(
+        "CMPMServer::AppendBMConnection - aConnId = 0x%x, aSnap = %i",
+        aConnId, aSnap )
+
+    // Set the Connection Id, SNAP, Iap Id and connection state
+    // 
+    TConnectionInfo connInfo;
+    connInfo.iConnId = aConnId;
+    connInfo.iSnap   = aSnap;
+    connInfo.iIapId  = aIapId;
+    connInfo.iState  = aState;
+
+    // Package into TActiveBMConn //TODO Redundant.. remove the other one.
+    // 
+    TActiveBMConn conn;
+    conn.iConnInfo          = connInfo;
+
+    TInt index1 = iActiveBMConns.Find( conn, TActiveBMConn::MatchConnInfo );
+
+    if ( index1 == KErrNotFound )
+        {
+        // If this connInfo is not yet there, insert it at the end of array
+        //
+        iActiveBMConns.Append( conn );
+        }
+    else
+        {
+        // connInfo already active, check whether Connection Id is there
+        //
+        if ( index1 < iActiveBMConns.Count() )
+            {
+            // Set the Iap Id and connection state
+            // 
+            iActiveBMConns[index1].iConnInfo.iIapId = aIapId;
+            iActiveBMConns[index1].iConnInfo.iState = aState;
+            iActiveBMConns[index1].iConnInfo.iAppUid = aSession.AppUid();
+            }
+        }
+
+    if ( aState == EStarted )
+        {
+        TInt ret = KErrNone;
+        
+        TRAP ( ret, UpdateActiveConnectionL( aSession ) );
+        
+        if ( ret != KErrNone )
+            {
+            iActiveBearerType = EMPMBearerTypeNone;
+            iActiveIapId = 0;
+            iActiveSnapId = 0;            
+            }
+        }
+
+#ifdef _DEBUG
+    // Dump array of active connections to log in order to support testing.
+    // 
+    DumpActiveBMConns();
+#endif // _DEBUG
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::ResetBMConnection
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::ResetBMConnection( const TConnectionId aConnId,
+                                    const TUint32       aIapId,
+                                    CMPMServerSession&  aSession )
+    {
+    MPMLOGSTRING3(
+        "CMPMServer::ResetBMConnection - aConnId = 0x%x, aIapId = %i", 
+        aConnId, aIapId )
+
+    // Get the current connection SNAP for this Connection Id
+    //
+    TUint32 snap = GetBMSnap( aConnId );
+
+    // Set the Connection Id and SNAP
+    // 
+    TConnectionInfo connInfo;
+    connInfo.iConnId = aConnId;
+    connInfo.iSnap   = snap;
+
+    // Set the Iap Id 
+    // 
+    TActiveBMConn conn;
+    conn.iConnInfo          = connInfo;
+    conn.iConnInfo.iIapId   = aIapId;
+
+    TInt index1 = iActiveBMConns.Find( conn, TActiveBMConn::MatchConnInfo );
+
+    if ( ( index1 != KErrNotFound ) && ( index1 < iActiveBMConns.Count() ) )
+//       && ( aIapId == iActiveBMConns[index1].iConnInfo.iIapId ) )
+        {
+        // If connInfo found, reset the Iap Id as zero and 
+        // update connection state as EIdle.
+        // 
+        // It is expected that MPM keeps the Connection Id and SNAP 
+        // relationship in a database entry and that this entry survives 
+        // a roaming event (an ApplicationLeavesConnection call).
+        //
+        iActiveBMConns[index1].iConnInfo.iIapId = 0;
+        iActiveBMConns[index1].iConnInfo.iState = EIdle;
+        
+        // Change state of P&S keys if needed
+        TInt ret = KErrNone;
+        
+        TRAP ( ret, UpdateActiveConnectionL( aSession ) );
+        
+        if ( ret != KErrNone )
+            {
+            iActiveBearerType = EMPMBearerTypeNone;
+            iActiveIapId = 0;
+            iActiveSnapId = 0;            
+            }
+        }
+#ifdef _DEBUG
+    // Dump array of active connections to log in order to support testing.
+    // 
+    DumpActiveBMConns();
+#endif // _DEBUG
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::RemoveBMConnection
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::RemoveBMConnection( const TConnectionId aConnId,
+                                     CMPMServerSession&  aSession )
+    {
+    MPMLOGSTRING2( "CMPMServer::RemoveBMConnection - aConnId = 0x%x", 
+        aConnId )
+
+    TInt count = iActiveBMConns.Count();
+    
+    // Decrement by one, because count is n, 
+    // but indexes in array are 0 .. n-1.
+    // 
+    count--;
+
+    // This time we are browsing the array from the end to the beginning, 
+    // because removing one element from array affects index numbering.
+    // 
+    for ( TInt i = count; i >= 0; i-- )
+        {
+        if ( iActiveBMConns[i].iConnInfo.iConnId == aConnId )
+            {
+            // If Connection Id found, remove it. 
+            //
+            iActiveBMConns.Remove( i );
+
+            // Update active connection
+            TInt ret = KErrNone;
+        
+            TRAP ( ret, UpdateActiveConnectionL( aSession ) );
+        
+            if ( ret != KErrNone )
+                {
+                iActiveBearerType = EMPMBearerTypeNone;
+                iActiveIapId = 0;
+                iActiveSnapId = 0;            
+                }
+            }
+        }
+
+#ifdef _DEBUG
+    // Dump array of active connections to log in order to support testing.
+    // 
+    DumpActiveBMConns();
+#endif // _DEBUG
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::GetBMIap
+// -----------------------------------------------------------------------------
+//
+TUint32 CMPMServer::GetBMIap( const TConnectionId aConnId )
+    {
+    MPMLOGSTRING2( "CMPMServer::GetBMIap - aConnId = 0x%x", aConnId )
+
+    TUint32 connectionIapId( 0 );
+
+    // Set the Connection Id and SNAP
+    // 
+    TConnectionInfo connInfo;
+    connInfo.iConnId = aConnId;
+
+    TActiveBMConn conn;
+    conn.iConnInfo = connInfo;
+
+    TInt index1 = iActiveBMConns.Find( conn, TActiveBMConn::MatchConnInfo );
+
+    if ( ( index1 != KErrNotFound ) && ( index1 < iActiveBMConns.Count() ) )
+        {
+        // If connInfo found, set the Iap Id as connectionIapId
+        //
+        connectionIapId = iActiveBMConns[index1].iConnInfo.iIapId;
+        }
+
+    MPMLOGSTRING2( "CMPMServer::GetBMIap - connectionIapId = %i", 
+        connectionIapId )
+    return connectionIapId;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::GetBMSnap
+// -----------------------------------------------------------------------------
+//
+TUint32 CMPMServer::GetBMSnap( const TConnectionId aConnId )
+    {
+    MPMLOGSTRING2( "CMPMServer::GetBMSnap - aConnId = 0x%x", aConnId )
+
+    TUint32 snap( 0 );
+    TBool   snapFound( EFalse );
+
+    for ( TInt i = 0; ( ( i < iActiveBMConns.Count() ) && !snapFound ); i++ )
+        {
+        if ( iActiveBMConns[i].iConnInfo.iConnId == aConnId )
+            {
+            snap = iActiveBMConns[i].iConnInfo.iSnap;
+            snapFound = ETrue;
+            }
+        }
+    MPMLOGSTRING2( "CMPMServer::GetBMSnap - SNAP = %i", snap )
+    return snap;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::GetConnectionState
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::GetConnectionState( const TConnectionId    aConnId,
+                                     TConnectionState&      aState )
+    {
+    MPMLOGSTRING2( "CMPMServer::GetConnectionState - aConnId = 0x%x", 
+        aConnId )
+
+    TConnectionInfo connInfo;
+    connInfo.iConnId = aConnId; 
+
+    TActiveBMConn conn;
+    conn.iConnInfo = connInfo;
+
+    TInt index1 = iActiveBMConns.Find( conn, TActiveBMConn::MatchConnInfo );
+
+    if ( ( index1 != KErrNotFound ) && ( index1 < iActiveBMConns.Count() ) )
+        {
+        // If connInfo found
+        //
+        aState = iActiveBMConns[index1].iConnInfo.iState;
+        }
+    else
+        {
+        // Since connInfo has no entry in iActiveBMConns, then 
+        // the state of connection must be EStarting.
+        // 
+        aState = EStarting;
+        }
+
+#ifdef _DEBUG
+    switch( aState )
+        {
+        case EStarting:
+            {
+            MPMLOGSTRING( "CMPMServer::GetConnectionState - Starting" )
+            break;
+            }
+        case EStarted:
+            {
+            MPMLOGSTRING( "CMPMServer::GetConnectionState - Started" )
+            break;
+            }
+        case EIdle:
+            {
+            MPMLOGSTRING( "CMPMServer::GetConnectionState - Idle" )
+            break;
+            }
+        case ERoaming:
+            {
+            MPMLOGSTRING( "CMPMServer::GetConnectionState - Roaming" )
+            break;
+            }
+        default:
+            {
+            MPMLOGSTRING( "CMPMServer::GetConnectionState - Unknown" )
+            break;
+            }
+        }
+#endif // _DEBUG
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::CheckIfStarted
+// -----------------------------------------------------------------------------
+//
+TBool CMPMServer::CheckIfStarted( const TUint32 aIapId )
+    {
+    MPMLOGSTRING2( "CMPMServer::CheckIfStarted - aIapId = %i", aIapId )
+
+    TConnectionState state( EIdle );
+    TBool stopLoop( EFalse );
+
+    // Loop all connections until EStarted is found or no more connections
+    // 
+    for ( TInt i = 0; ( ( i < iActiveBMConns.Count() ) && !stopLoop ); i++ )
+        {
+        // Check if IAP Id matches
+        // 
+        if ( iActiveBMConns[i].iConnInfo.iIapId == aIapId )
+            {
+            state = iActiveBMConns[i].iConnInfo.iState;  
+
+            // Stop looping if EStarted found
+            // 
+            if ( state == EStarted )
+                {
+                stopLoop = ETrue;
+                }
+            }
+        }
+
+#ifdef _DEBUG
+    switch( state )
+        {
+        case EStarting:
+            {
+            MPMLOGSTRING( "CMPMServer::CheckIfStarted - Starting" )
+            break;
+            }
+        case EStarted:
+            {
+            MPMLOGSTRING( "CMPMServer::CheckIfStarted - Started" )
+            break;
+            }
+        case EIdle:
+            {
+            MPMLOGSTRING( "CMPMServer::CheckIfStarted - Idle" )
+            break;
+            }
+        case ERoaming:
+            {
+            MPMLOGSTRING( "CMPMServer::CheckIfStarted - Roaming" )
+            break;
+            }
+        default:
+            {
+            MPMLOGSTRING( "CMPMServer::CheckIfStarted - Unknown" )
+            break;
+            }
+        }
+#endif // _DEBUG
+
+    if ( state == EStarted )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::IsWlanConnectionStartedL
+// -----------------------------------------------------------------------------
+//
+TUint32 CMPMServer::IsWlanConnectionStartedL( const CMPMCommsDatAccess* aCdbAccess )
+    {
+    TUint32 iapId( 0 );
+    
+    MPMLOGSTRING( "CMPMServer::IsWlanConnectionStartedL" )
+
+    TBool stopLoop( EFalse );
+
+    // Loop all connections until EStarted is found or no more connections
+    // 
+    for ( TInt i = 0; ( ( i < iActiveBMConns.Count() ) && !stopLoop ); i++ )
+        {
+        // Check if IAP Id matches
+        // 
+        if ( iActiveBMConns[i].iConnInfo.iState == EStarting ||
+             iActiveBMConns[i].iConnInfo.iState == EStarted )
+            {
+            if ( aCdbAccess->CheckWlanL( iActiveBMConns[i].iConnInfo.iIapId ) != ENotWlanIap )
+                {
+                stopLoop = ETrue;
+                iapId = iActiveBMConns[i].iConnInfo.iIapId;
+                MPMLOGSTRING2( "CMPMServer::IsWlanConnectionStartedL, found wlan iap %d", iapId )
+                }
+            }
+        }
+
+    
+    return iapId;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::AppendBMIAPConnectionL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::AppendBMIAPConnectionL( const TUint32       aIapId, 
+                                         const TConnectionId aConnId,
+                                         CMPMServerSession& aSession )
+    {
+    MPMLOGSTRING3(
+        "CMPMServer::AppendBMIAPConnectionL - aIapId = %i, aConnId = 0x%x", 
+        aIapId, aConnId )
+
+    TActiveBMConn conn;
+    conn.iConnInfo.iIapId = aIapId;
+    conn.iConnInfo.iState = EStarted;
+    conn.iConnInfo.iAppUid = aSession.AppUid();
+    
+    TInt index1 = iActiveBMConns.Find( conn, TActiveBMConn::MatchIapId );
+
+    if ( index1 == KErrNotFound )
+        {
+        // If this Iap is not yet there, insert it at the end of array
+        //
+        iActiveBMConns.AppendL( conn );
+        }
+    else
+        {
+        // Iap already active, update connection state as started. 
+        // This Iap could be shared by multiple applications, but 
+        // update only the one with matching connection id.
+        //
+        for ( TInt i = 0; i < iActiveBMConns.Count(); i++ )
+            {
+            if ( iActiveBMConns[i].iConnInfo.iConnId == aConnId )
+                {
+                iActiveBMConns[i].iConnInfo.iState = EStarted;
+                }
+            else if ( iActiveBMConns[i].iConnInfo.iSnap == 0 &&
+                    iActiveBMConns[i].iConnInfo.iIapId == aIapId )
+                {
+                iActiveBMConns[i].iConnInfo.iState = EStarted;
+                }
+            }
+        }
+
+    TInt ret = KErrNone;
+        
+    TRAP ( ret, UpdateActiveConnectionL( aSession ) );
+        
+    if ( ret != KErrNone )
+        {
+        iActiveBearerType = EMPMBearerTypeNone;
+        iActiveIapId = 0;
+        iActiveSnapId = 0;            
+        }
+
+#ifdef _DEBUG
+    // Dump array of active connections to log in order to support testing.
+    // 
+    DumpActiveBMConns();
+#endif // _DEBUG
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::RemoveBMIAPConnection
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::RemoveBMIAPConnection( const TUint32       aIapId, 
+                                        const TConnectionId aConnId,
+                                        CMPMServerSession&  aSession )
+    {
+    MPMLOGSTRING3(
+        "CMPMServer::RemoveBMIAPConnection - aIapId = %i, aConnId = 0x%x", 
+        aIapId, aConnId )
+
+    TActiveBMConn conn;
+    conn.iConnInfo.iIapId = aIapId;
+
+    // The IAP connection lifetime is determined by the two calls 
+    // IAPConnectionStarted and IAPConnectionStopped. 
+    //
+    TInt count = iActiveBMConns.Count();
+
+    // Decrement by one, because count is n, 
+    // but indexes in array are 0 .. n-1.
+    // 
+    count--;
+
+    // This time we are browsing the array from the end to the beginning, 
+    // because removing one element from array affects index numbering.
+    // 
+    for ( TInt i = count; i >= 0; i-- )
+        {
+        if ( iActiveBMConns[i].iConnInfo.iIapId == aIapId )
+            {
+            if ( iActiveBMConns[i].iConnInfo.iSnap == 0 )
+                {
+                // If IAPConnectionStopped has been called and SNAP is zero,
+                // then this entry can be removed from database.
+                // 
+                iActiveBMConns.Remove( i );
+                }
+            else
+                {
+                // If IAP found, reset the Iap Id as zero and 
+                // update connection state as idle.
+                // This Iap could be shared by multiple applications, 
+                // but update only the one with matching connection id.
+                // 
+                if ( iActiveBMConns[i].iConnInfo.iConnId == aConnId )
+                    {
+                    iActiveBMConns[i].iConnInfo.iIapId = 0;
+                    iActiveBMConns[i].iConnInfo.iState = EIdle;
+                    }
+                }
+            
+            // Update active connection
+            TInt ret = KErrNone;
+        
+            TRAP ( ret, UpdateActiveConnectionL( aSession ) );
+        
+            if ( ret != KErrNone )
+                {
+                iActiveBearerType = EMPMBearerTypeNone;
+                iActiveIapId = 0;
+                iActiveSnapId = 0;            
+                }
+            }
+        }
+
+#ifdef _DEBUG
+    // Dump array of active connections to log in order to support testing.
+    // 
+    DumpActiveBMConns();
+#endif // _DEBUG
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::AppendSessionL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::AppendSessionL( const CMPMServerSession* aSession )
+    {
+    MPMLOGSTRING( "CMPMServer::AppendSession" )
+    
+    iSessions.AppendL( aSession );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::RemoveSession
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::RemoveSession( const CMPMServerSession* aSession )
+    {
+    MPMLOGSTRING( "CMPMServer::RemoveSession" )
+
+    TInt index = iSessions.Find( aSession );
+    if ( index != KErrNotFound )
+        {
+        iSessions.Remove( index );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::NotifyBMPrefIapL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::NotifyBMPrefIapL( const TConnMonIapInfo& aIapInfo )
+    {
+    MPMLOGSTRING2( "CMPMServer::NotifyBMPrefIapL - IAPs count: %d", 
+        aIapInfo.iCount)
+    TConnMonIapInfo iapInfo = aIapInfo;
+    
+#ifdef _DEBUG
+    for (TUint i = 0; i < iapInfo.Count(); i++)
+        {
+        MPMLOGSTRING2( "CMPMServer::NotifyBMPrefIap - IAP: %d", 
+            iapInfo.iIap[i].iIapId) 
+        }
+#endif // _DEBUG
+
+    // Start possible forced roaming
+    TCmUsageOfWlan usageOfWlan = CommsDatAccess()->ForcedRoamingL();
+    if ( usageOfWlan == ECmUsageOfWlanKnown || usageOfWlan == ECmUsageOfWlanKnownAndNew )
+        {
+        StartForcedRoamingToWlanL( iapInfo );
+        StartForcedRoamingFromWlanL( iapInfo );
+        }
+    
+    MPMLOGSTRING2(
+    "CMPMServer::NotifyBMPrefIapL - Send notifications for %d sessions", 
+        iSessions.Count() )
+
+    for ( TInt i = 0; i < iSessions.Count(); i++ )
+        {
+        iapInfo = iSessions[i]->GetAvailableIAPs( );
+        iSessions[i]->PrefIAPNotificationL( iapInfo, EConnMon );
+        }
+
+    // If a session is displaying connection selection dialog 
+    // the contents of the dialog should be updated according to the 
+    // current iap availability
+    //
+    for ( TInt i( 0 ); i < iSessions.Count(); i++ )
+        {
+        iSessions[i]->UpdateConnectionDialogL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::UpdateSessionConnectionDlgL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::UpdateSessionConnectionDlgL()
+    {
+    MPMLOGSTRING( "CMPMServer::UpdateSessionConnectionDlgL" )
+
+    // If a session is displaying connection selection dialog 
+    // the contents of the dialog should be updated according to the 
+    // current iap availability
+    //
+    for ( TInt i( 0 ); i < iSessions.Count(); i++ )
+        {
+        iSessions[i]->UpdateConnectionDialogL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::HandleServerBlackListIap
+// -----------------------------------------------------------------------------
+//
+TInt CMPMServer::HandleServerBlackListIap( const TConnectionId  aConnId,
+                                           TUint32              aIapId, 
+                                           TBlacklistCategory   aCategory )
+    {
+    MPMLOGSTRING3(
+        "CMPMServer::HandleServerBlackListIap - aConnId = 0x%x, iapId = %i",
+        aConnId, aIapId )
+
+    MPMLOGSTRING2(
+        "CMPMServer::HandleServerBlackListIap - aCategory = %i", aCategory )
+
+    BlackListIap( aConnId, aIapId, aCategory ); 
+
+    TUint32 presumedIap = Events()->PresumedIapId( aConnId, 
+                                                   aIapId );
+    if ( ( presumedIap != 0 ) && 
+         ( presumedIap != aIapId ) )
+        {
+        MPMLOGSTRING2(
+            "CMPMServer::HandleServerBlackListIap - presumedIap = %i",
+            presumedIap )
+        BlackListIap( aConnId, presumedIap, aCategory ); 
+        }
+
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::BlackListIap
+// -----------------------------------------------------------------------------
+//
+TInt CMPMServer::BlackListIap( const TConnectionId  aConnId,
+                               TUint32              aIapId, 
+                               TBlacklistCategory   aCategory )
+    {
+    TInt i;
+    TBool found = EFalse;
+
+    found = FindBlacklistedConnIndex( aConnId, i );
+    if ( found )
+        {
+        TMPMBlackListConnId connIdInfo = iBlackListIdList[i];
+        connIdInfo.Append( aIapId, aCategory );
+        iBlackListIdList.Remove( i );
+        iBlackListIdList.Insert( connIdInfo, 0 );
+        }
+    else
+        {
+        TMPMBlackListConnId connIdInfo;
+        connIdInfo.iConnId = aConnId;
+        connIdInfo.Append( aIapId, aCategory );
+        iBlackListIdList.Insert( connIdInfo, 0 );
+        }
+
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::HandleServerUnblackListIap
+// -----------------------------------------------------------------------------
+//
+TInt CMPMServer::HandleServerUnblackListIap( 
+    const TConnectionId aConnId,
+    TUint32             aIapId )
+    {
+    MPMLOGSTRING3(
+        "CMPMServer::HandleServerUnblackListIap - aConnId = 0x%x, iapId = %i"
+        ,aConnId, aIapId )
+
+    TInt i;
+    TBool found = EFalse;
+
+    found = FindBlacklistedConnIndex( aConnId, i );
+    if ( found )
+        {
+        // found blacklisted Connection Id
+        TMPMBlackListConnId connIdInfo = iBlackListIdList[i];
+        iBlackListIdList.Remove( i ); // remove from the list 
+
+        if ( aIapId == 0 )
+            { // 0 will reset Connection Id blacklisted iap list 
+            connIdInfo.Close();
+            return KErrNone;
+            }
+
+        found = EFalse;
+        for (TInt j = 0; j < connIdInfo.Count(); j++)
+            {
+            if ( connIdInfo.Iap( j ) == aIapId )
+                {
+                // found and remove blacklisted iap
+                connIdInfo.Remove( j ); 
+                if ( connIdInfo.Count() == 0 )
+                    {
+                    return KErrNone;
+                    }
+
+                // reinsert connIdInfo at the beginning to reflect activeness
+                iBlackListIdList.Insert( connIdInfo, 0 ); 
+                return KErrNone;
+                }
+            }
+        // nothing found and reinsert at the beginning 
+        // connIdInfo to reflect activeness
+        iBlackListIdList.Insert( connIdInfo, 0 ); 
+        return KErrNotFound;
+        }
+    else
+        {
+        return KErrNotFound;
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::HandleServerUnblackListIap
+// -----------------------------------------------------------------------------
+//
+TInt CMPMServer::HandleServerUnblackListIap( 
+    const TConnectionId aConnId,
+    TBlacklistCategory  aCategory )
+    {
+    MPMLOGSTRING3( "CMPMServer::HandleServerUnblackListIap -\
+ aConnId = 0x%x, aCategory = %i", aConnId, aCategory )
+
+    TInt i;
+    TBool found = EFalse;
+
+    found = FindBlacklistedConnIndex( aConnId, i );
+    if ( found )
+        {
+        // found blacklisted Connection Id
+        TMPMBlackListConnId connIdInfo = iBlackListIdList[i];
+        iBlackListIdList.Remove( i ); // remove from the list 
+
+        found = EFalse;
+        for (TInt j = 0; j < connIdInfo.Count(); j++)
+            {
+            if ( connIdInfo.Category( j ) == aCategory ) 
+                {
+                // found and remove blacklisted iap
+                connIdInfo.Remove( j ); 
+                if ( connIdInfo.Count() == 0 )
+                    {
+                    return KErrNone;
+                    }
+
+                // reinsert connIdInfo at the beginning to reflect activeness
+                iBlackListIdList.Insert( connIdInfo, 0 ); 
+                return KErrNone;
+                }
+            }
+        // nothing found and reinsert at the beginning 
+        // connIdInfo to reflect activeness
+        iBlackListIdList.Insert( connIdInfo, 0 ); 
+        return KErrNotFound;
+        }
+    else
+        {
+        return KErrNotFound;
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::HandleServerUnblackListIap
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::HandleServerUnblackListIap( 
+    TBlacklistCategory  aCategory )
+    {
+    MPMLOGSTRING2( "CMPMServer::HandleServerUnblackListIap -\
+ aCategory = %i", aCategory )
+
+    for( TInt i( 0 ); i < iBlackListIdList.Count(); i++ )
+        {
+        // found blacklisted Connection Id
+        TMPMBlackListConnId connIdInfo = iBlackListIdList[i];
+        iBlackListIdList.Remove( i ); // remove from the list 
+
+        for (TInt j = 0; j < connIdInfo.Count(); j++)
+            {
+            if ( connIdInfo.Category( j ) == aCategory ) 
+                {
+                // found and remove blacklisted iap
+                connIdInfo.Remove( j ); 
+                }
+            }
+        // If any blacklisted iaps remain reinsert at the 
+        // beginning connIdInfo to reflect activeness
+        //
+        if( connIdInfo.Count() > 0 )
+            {
+            iBlackListIdList.Insert( connIdInfo, 0 );             
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::GetBlacklistedIAP
+// -----------------------------------------------------------------------------
+//
+TInt CMPMServer::GetBlacklistedIAP( TConnectionId    aConnId, 
+                                    RArray<TUint32> &aBlacklistedIAP )
+    {
+    TInt  i;
+    TBool found = EFalse;
+
+    found = FindBlacklistedConnIndex( aConnId, i );
+    if ( !found )
+        {
+        return KErrNotFound;
+        }
+
+    TMPMBlackListConnId connIdInfo = iBlackListIdList[i];
+    iBlackListIdList.Remove( i );
+    iBlackListIdList.Insert( connIdInfo, 0 );
+
+    for (TInt j = 0; j < connIdInfo.Count(); j++)
+        {
+        aBlacklistedIAP.Append( connIdInfo.Iap( j ) );
+        }
+
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::GetBlacklistedIAP
+// -----------------------------------------------------------------------------
+//
+TInt CMPMServer::GetBlacklistedIAP( RArray<TUint32> &aBlacklistedIAP )
+    {
+    // Returns all blacklisted IAPs regardless of Connection Id 
+    // 
+    for ( TInt i( 0 ); i < iBlackListIdList.Count(); i++ )
+        {
+        for ( TInt j( 0 ); j < iBlackListIdList[i].Count(); 
+              j++ )
+            {
+            // Inserts an object into the array in ascending unsigned 
+            // key order. No duplicate entries are permitted. 
+            // 
+            // The array remains unchanged following an attempt to 
+            // insert a duplicate entry.
+            // 
+            aBlacklistedIAP.InsertInUnsignedKeyOrder( 
+                                    iBlackListIdList[i].Iap( j ) );
+            }
+        }
+    return KErrNone;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::FindId
+// -----------------------------------------------------------------------------
+//
+TBool CMPMServer::FindBlacklistedConnIndex( const TConnectionId aConnId, 
+                                            TInt                &aIndex )
+    {
+    TInt  i;
+    TBool found = EFalse;
+
+    for (i = 0;( (i < iBlackListIdList.Count()) && !found ); i++)
+        {
+        if ( iBlackListIdList[i].iConnId == aConnId )
+            {
+            found = ETrue;
+            }
+        }
+    i--; // Since i is incremented after finding the correct iConnId
+    aIndex = i;
+    return found;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::IsVoiceCallActiveL
+// 
+// Checks if voice call is active or not.
+// Return ETrue if voice call is active.
+// Return EFalse if voice call is not active.
+// -----------------------------------------------------------------------------
+//
+TBool CMPMServer::IsVoiceCallActiveL() const
+    {
+    MPMLOGSTRING( "CMPMServer::IsVoiceCallActiveL" )
+
+    CTelephony*                   telephony = CTelephony::NewLC();
+    CTelephony::TCallStatusV1     callStatusV1;
+    CTelephony::TCallStatusV1Pckg callStatusV1Pckg( callStatusV1 );
+    CTelephony::TPhoneLine        line = CTelephony::EVoiceLine;
+
+    telephony->GetLineStatus( line, callStatusV1Pckg );
+    CTelephony::TCallStatus voiceLineStatus = callStatusV1.iStatus;
+
+    CleanupStack::PopAndDestroy( telephony );
+
+    if ( voiceLineStatus == CTelephony::EStatusDialling         ||
+         voiceLineStatus == CTelephony::EStatusRinging          ||
+         voiceLineStatus == CTelephony::EStatusAnswering        ||
+         voiceLineStatus == CTelephony::EStatusConnecting       ||
+         voiceLineStatus == CTelephony::EStatusConnected        ||
+         voiceLineStatus == CTelephony::EStatusReconnectPending ||
+         voiceLineStatus == CTelephony::EStatusDisconnecting    ||
+         voiceLineStatus == CTelephony::EStatusHold             ||
+         voiceLineStatus == CTelephony::EStatusTransferring     ||
+         voiceLineStatus == CTelephony::EStatusTransferAlerting  )
+        {
+        MPMLOGSTRING2(
+            "CMPMServer::IsVoiceCallActiveL Voice call is active: %d", 
+            voiceLineStatus )
+        return ETrue;
+        }
+    else if ( voiceLineStatus == CTelephony::EStatusIdle ||
+              voiceLineStatus == CTelephony::EStatusUnknown )
+        {
+        MPMLOGSTRING2(
+            "CMPMServer::IsVoiceCallActiveL Voice call is not active: %d", 
+            voiceLineStatus )
+        return EFalse;
+        }
+    else
+        {
+        MPMLOGSTRING2(
+            "CMPMServer::IsVoiceCallActiveL Unknown voice line status: %d", 
+            voiceLineStatus )
+        return EFalse;
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::IsModeGSM
+// 
+// Checks if mode is GSM or not.
+// Return ETrue if mode is GSM.
+// Return EFalse if mode is something else.
+// -----------------------------------------------------------------------------
+//
+TBool CMPMServer::IsModeGSM() const
+    {
+    MPMLOGSTRING( "CMPMServer::IsModeGSM" )
+
+    if ( iTSYLoaded )
+        {
+        RMobilePhone::TMobilePhoneNetworkMode mode( 
+            RMobilePhone::ENetworkModeUnknown );
+
+        TInt ret = iMobilePhone.GetCurrentMode( mode );
+
+        if ( ( ret == KErrNone ) && 
+             ( mode == RMobilePhone::ENetworkModeGsm ) )
+            {
+            MPMLOGSTRING( "CMPMServer::IsModeGSM Mode is GSM" )
+            return ETrue;
+            }
+        else
+            {
+            MPMLOGSTRING( "CMPMServer::IsModeGSM Mode is not GSM" )
+            return EFalse;
+            }
+        }
+    MPMLOGSTRING( "CMPMServer::IsModeGSM phone.tsy not loaded" )
+    return EFalse;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::IsDTMSupported
+// 
+// Checks if phone supports Dual Transfer Mode or not.
+// Return ETrue if phone supports DTM.
+// Return EFalse if phone does not support DTM.
+// -----------------------------------------------------------------------------
+//
+TBool CMPMServer::IsDTMSupported() const
+    {
+    MPMLOGSTRING( "CMPMServer::IsDTMSupported" )
+
+    if ( iPacketServLoaded )
+        {
+        TBool rv = iDtmWatcher->IsInDualMode();
+        if ( rv )
+            {
+            MPMLOGSTRING( "CMPMServer::IsDTMSupported DTM is supported" )
+            }
+        else
+            {
+            MPMLOGSTRING( "CMPMServer::IsDTMSupported DTM is not supported" )
+            }
+        return rv;
+        }
+ 
+    MPMLOGSTRING( "CMPMServer::IsDTMSupported Packet service not loaded" )
+    return EFalse;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::DumpActiveBMConns
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::DumpActiveBMConns()
+    {
+#ifdef _DEBUG
+    // Dump array of active connections to log in order to support testing.
+    // 
+    MPMLOGSTRING( "Display array of active connections - Start" )
+    MPMLOGSTRING( "" )
+
+    if ( iActiveBMConns.Count() == 0 )
+        {
+        MPMLOGSTRING( "Array of active connections is empty" )
+        MPMLOGSTRING( "" )
+        }
+
+    for ( TInt i = 0; i < iActiveBMConns.Count(); i++ )
+        {
+        MPMLOGSTRING3( "Connection Id = 0x%x Snap = %i", 
+            iActiveBMConns[i].iConnInfo.iConnId, 
+            iActiveBMConns[i].iConnInfo.iSnap )
+
+        switch( iActiveBMConns[i].iConnInfo.iState )
+            {
+            case EStarting:
+                {
+                MPMLOGSTRING2( "IAP %i: Connection state = Starting", 
+                    iActiveBMConns[i].iConnInfo.iIapId )
+                break;
+                }
+            case EStarted:
+                {
+                MPMLOGSTRING2( "IAP %i: Connection state = Started", 
+                    iActiveBMConns[i].iConnInfo.iIapId )
+                break;
+                }
+            case EIdle:
+                {
+                MPMLOGSTRING2( "IAP %i: Connection state = Idle", 
+                    iActiveBMConns[i].iConnInfo.iIapId )
+                break;
+                }
+            case ERoaming:
+                {
+                MPMLOGSTRING2( "IAP %i: Connection state = Roaming", 
+                    iActiveBMConns[i].iConnInfo.iIapId )
+                break;
+                }
+            default:
+                {
+                MPMLOGSTRING2( "IAP %i: Unknown connection state", 
+                    iActiveBMConns[i].iConnInfo.iIapId )
+                break;
+                }
+            }
+
+        MPMLOGSTRING( "" )
+        }
+
+    MPMLOGSTRING( "Display array of active connections - End" )
+#endif // _DEBUG
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMPMServer::DefaultConnection
+// -----------------------------------------------------------------------------
+//
+CMPMDefaultConnection* CMPMServer::DefaultConnection()
+    {
+    MPMLOGSTRING( "CMPMServer::DefaultConnection:\
+ Default Connection" )
+    return iDefaultConnection;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::StartedConnectionExists
+// -----------------------------------------------------------------------------
+//
+TInt CMPMServer::StartedConnectionExists( TInt aIapId )
+    {
+    MPMLOGSTRING( "CMPMServer::StartedConnectionExists" )
+
+    // Loop all connections until EStarted is found or no more connections
+    // 
+    for ( TInt i = 0; ( i < iActiveBMConns.Count() ); i++ )
+        {
+        if ( iActiveBMConns[i].iConnInfo.iState == EStarted &&
+                ( aIapId == KErrNotFound || aIapId == iActiveBMConns[i].iConnInfo.iIapId ) )
+            {
+            MPMLOGSTRING( "CMPMServer::StartedConnectionExists: True" )
+            return iActiveBMConns[i].iConnInfo.iIapId;
+            }
+        }
+    // Modem connection may exist, check from connection counter
+    // 
+    if ( ConnectionCounter() > 0 )
+        {
+        MPMLOGSTRING( "CMPMServer::StartedConnectionExists: True (modem connection)" )
+        return KMaxTInt; // arbitrary high number that is NOT from Iap range[0:255] 
+        }
+    else
+        {
+        MPMLOGSTRING( "CMPMServer::StartedConnectionExists: False" )
+        return KErrNotFound;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::AppendWlanQueryQueueL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::AppendWlanQueryQueueL( CMPMWlanQueryDialog* aDlg )
+    {
+    if( aDlg )
+        {
+        iWlanQueryQueue->AppendL( aDlg );
+        }
+    else
+        {
+        MPMLOGSTRING( "CMPMServer::AppendWlanQueryQueueL argument NULL, Error" )
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::StopConnections
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::StopConnections( TInt aIapId )
+    {
+    for (TInt index = 0; index < iSessions.Count(); index++)
+        {
+/*        if (iSessions[index]->UserConnection())
+            continue;
+  */          
+        // Stop connection
+        if ( aIapId == 0 )
+            {
+            iSessions[index]->StopConnection();
+            }
+        else
+            {
+            TRAP_IGNORE( iSessions[index]->StopIAPNotificationL( aIapId ));
+            }
+        
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::UpdateActiveConnectionL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::UpdateActiveConnectionL( CMPMServerSession& aSession )
+    {
+    MPMLOGSTRING( "CMPMServer::UpdateActiveConnectionL" )
+    TUint32 snapId;
+
+    if ( !NumberOfActiveConnections() )
+        {
+        // If no active connections then just reset keys and publish
+        iActiveBearerType = EMPMBearerTypeNone;
+        iActiveIapId = 0;
+        iActiveSnapId = 0;
+        PublishActiveConnection();
+        return;
+        }
+
+    // Check if all active connections are in same snap
+    if ( CommsDatAccess()->AreActiveIapsInSameSnapL(
+         iActiveBMConns, snapId ) )
+        {
+        // Select active connection according to priority
+        CommsDatAccess()->SelectActiveConnectionL (
+            snapId,
+            iActiveBMConns,
+            iActiveIapId,
+            iActiveSnapId,
+            iActiveBearerType,
+            aSession );
+
+        PublishActiveConnection();
+        return;
+        }
+
+    // Reset active connections
+    iActiveBearerType = EMPMBearerTypeNone;
+    iActiveIapId = 0;
+    iActiveSnapId = 0;
+            
+    // Active connections locating in different snaps
+    // Use priority order vpn, wlan and packet
+    for ( TInt index = 0; index < iActiveBMConns.Count(); index++ )
+        {
+        // Do check only for active connections
+        if ( iActiveBMConns[index].iConnInfo.iState == EStarted )
+            {
+            TMPMBearerType bearerType = EMPMBearerTypeOther;
+        
+            if ( iDedicatedClients.Find( iActiveBMConns[index].iConnInfo.iAppUid ) == 
+                 KErrNone )
+                {
+                // Skip dedicated client
+                continue;
+                }
+
+            bearerType = CommsDatAccess()->GetBearerTypeL( 
+                         iActiveBMConns[index].iConnInfo.iIapId );
+        
+            if ( bearerType == EMPMBearerTypeOther )
+                {
+                // Don't publish this connection
+                continue;
+                }
+                    
+            // This is true if,
+            // bearer type is smaller or different than none
+            // or
+            // bearer type is same and iap is different.
+            if ( ( bearerType < iActiveBearerType ) || 
+                 ( iActiveBearerType == EMPMBearerTypeNone ) ||
+                 ( ( bearerType == iActiveBearerType) &&
+                   ( iActiveIapId != iActiveBMConns[index].iConnInfo.iIapId ) ) )
+                {
+                iActiveBearerType = bearerType;
+                iActiveIapId = iActiveBMConns[index].iConnInfo.iIapId;
+                iActiveSnapId = iActiveBMConns[index].iConnInfo.iSnap;
+                }
+            }
+
+        PublishActiveConnection();  
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::MapBearerType
+// -----------------------------------------------------------------------------
+//
+TUint32 CMPMServer::MapBearerType(TMPMBearerType aBearerType)
+    {
+    MPMLOGSTRING( "CMPMServer::MapBearerType" )
+    
+    switch ( aBearerType )
+        {
+        case EMPMBearerTypeNone:
+            return 0;
+
+        case EMPMBearerTypeVpn:
+            return KCommDbBearerVirtual;
+            
+        case EMPMBearerTypeWlan:
+            return KCommDbBearerWLAN;
+            
+        case EMPMBearerTypePacketData:
+            return KCommDbBearerWcdma;
+
+        case EMPMBearerTypeOther:
+            return KCommDbBearerUnknown;
+            
+        default:
+            MPMLOGSTRING( "CMPMServer::MapBearerType: Unknown bearer type" )
+            break;
+        }
+    
+    return KCommDbBearerUnknown;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::PublishActiveConnection
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::PublishActiveConnection()
+    {
+    MPMLOGSTRING( "CMPMServer::PublishActiveConnection" )
+    
+    // update active connection keys
+    RProperty::Set( KMPMActiveConnectionCategory,
+                    KMPMPSKeyActiveConnectionIap,
+                    iActiveIapId );
+
+    RProperty::Set( KMPMActiveConnectionCategory,
+                    KMPMPSKeyActiveConnectionSnap,
+                    iActiveSnapId );
+
+    RProperty::Set( KMPMActiveConnectionCategory,
+                    KMPMPSKeyActiveConnectionBearer,
+                    MapBearerType( iActiveBearerType ) );    
+
+    MPMLOGSTRING4( "CMPMServer::PublishActiveConnection: Set to: %d, %d, %d",
+                   iActiveIapId, iActiveSnapId, iActiveBearerType )
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::NumberOfActiveConnections
+// -----------------------------------------------------------------------------
+//
+TInt CMPMServer::NumberOfActiveConnections()
+    {
+    MPMLOGSTRING( "CMPMServer::NumberOfActiveConnections" )
+    
+    TInt count( 0 );
+    
+    for ( TInt index = 0; index < iActiveBMConns.Count(); index++ )
+        {
+        if ( iActiveBMConns[index].iConnInfo.iState == EStarted )
+            {
+            count++;
+            }
+        }
+    
+    return count;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::UserConnectionInInternet
+// -----------------------------------------------------------------------------
+//
+TBool CMPMServer::UserConnectionInInternet() const
+    {
+    TBool isInternet = EFalse;
+    TInt ret = KErrNone;
+        
+    TRAP( ret, isInternet = iCommsDatAccess->IsInternetSnapL(
+          UserConnPref()->IapId(), UserConnPref()->SnapId() ) );
+
+    if ( ret != KErrNone )
+        {
+        isInternet = EFalse;
+        }
+    
+    return isInternet;
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::StartForcedRoamingToWlanL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::StartForcedRoamingToWlanL( const TConnMonIapInfo& aIapInfo )
+    {
+    MPMLOGSTRING( "CMPMServer::StartForcedRoamingToWlan" )
+
+    // First check that there is no active wlan connection
+    if ( IsWlanConnectionStartedL( CommsDatAccess() ) )
+        {
+        // Wlan already active can't roam to it
+        return;
+        }
+
+    // Copy all available wlan iap ids to own array
+    RArray<TUint32> wlanIapIds;
+    CleanupClosePushL( wlanIapIds );
+    RAvailableIAPList iapList;
+    CleanupClosePushL( iapList );
+
+    for ( TInt index = 0; index < aIapInfo.iCount; index++ )
+        {
+        if ( CommsDatAccess()->CheckWlanL( aIapInfo.iIap[index].iIapId ) != ENotWlanIap )
+            {
+            // Accept only wlan iaps in internet snap
+            if ( iCommsDatAccess->IsInternetSnapL( aIapInfo.iIap[index].iIapId, 0 ) )
+                {
+                wlanIapIds.AppendL( aIapInfo.iIap[index].iIapId );
+                }
+            }
+        // Fill iap list to be used later to check best iap
+        iapList.AppendL( aIapInfo.iIap[index].iIapId );
+        }
+
+    // No wlans available -> no reason to continue
+    if ( !wlanIapIds.Count() )
+        {
+        CleanupStack::PopAndDestroy( &iapList );
+        CleanupStack::PopAndDestroy( &wlanIapIds );
+        return;
+        }
+
+    // Go through all active connections and start roaming for the ones connected
+    // to snap containing wlan and not using mobility api
+    for ( TInt index = 0; index < iActiveBMConns.Count(); index++ )
+        {
+        // Check if snap is internet snap
+        TBool internetSnap =
+            iCommsDatAccess->IsInternetSnapL(
+                iActiveBMConns[index].iConnInfo.iIapId,
+                iActiveBMConns[index].iConnInfo.iSnap );
+
+        CMPMServerSession* serverSession = GetServerSession(
+                iActiveBMConns[index].iConnInfo.iConnId );
+
+        // Check that connection is started, established to snap and
+        // choose best iap is called for the connection
+        if ( ( iActiveBMConns[index].iConnInfo.iState == EStarted ) &&
+             ( iActiveBMConns[index].iConnInfo.iSnap ) && 
+             ( serverSession->ChooseBestIapCalled() ) &&
+             ( internetSnap ) )
+            {
+            // Notify client to disconnect
+            NotifyDisconnectL( index, wlanIapIds, iapList, ETrue,
+                EMPMBearerTypeWlan );
+            }
+        }
+    CleanupStack::PopAndDestroy( &iapList );
+    CleanupStack::PopAndDestroy( &wlanIapIds );
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::StartForcedRoamingFromWlanL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::StartForcedRoamingFromWlanL( const TConnMonIapInfo& aIapInfo )
+    {
+    MPMLOGSTRING( "CMPMServer::StartForcedRoamingFromWlan" )
+
+    // Copy all available packet data iap ids to own array
+    RArray<TUint32> packetDataIapIds;
+    CleanupClosePushL( packetDataIapIds );
+
+    for ( TInt index = 0; index < aIapInfo.iCount; index++ )
+        {
+        if ( CommsDatAccess()->GetBearerTypeL( aIapInfo.iIap[index].iIapId ) ==
+            EMPMBearerTypePacketData )
+            {
+            // Accept only packet data iaps in internet snap
+            if ( iCommsDatAccess->IsInternetSnapL( aIapInfo.iIap[index].iIapId, 0 ) )
+                {
+                packetDataIapIds.AppendL( aIapInfo.iIap[index].iIapId );
+                }
+            }
+        }
+
+    // No packet data iaps available -> no reason to continue
+    if ( !packetDataIapIds.Count() )
+        {
+        CleanupStack::PopAndDestroy( &packetDataIapIds );
+        return;
+        }
+    
+    // Go through all active connections and start roaming for the ones connected
+    // to a wlan not anymore listed in available iaps and not using mobility api
+    for ( TInt index = 0; index < iActiveBMConns.Count(); index++ )
+        {
+        if ( iCommsDatAccess->CheckWlanL( iActiveBMConns[index].iConnInfo.iIapId )
+            == EWlanIap )
+            {
+            // Check if used WLAN is still available
+            TBool currentWlanIapAvailable = EFalse;
+            for ( TInt iapIndex = 0; iapIndex < aIapInfo.iCount; iapIndex++ )
+                {
+                if ( aIapInfo.iIap[iapIndex].iIapId ==
+                    iActiveBMConns[index].iConnInfo.iIapId )
+                    {
+                    // Current WLAN IAP found from list of available IAPs
+                    currentWlanIapAvailable = ETrue;
+                    break;
+                    }
+                }
+            
+            if ( !currentWlanIapAvailable )
+                {
+                // Current WLAN not available anymore
+                // Check if snap is internet snap
+                TBool internetSnap = iCommsDatAccess->IsInternetSnapL(
+                    iActiveBMConns[index].iConnInfo.iIapId,
+                    iActiveBMConns[index].iConnInfo.iSnap );
+    
+                CMPMServerSession* serverSession = GetServerSession(
+                    iActiveBMConns[index].iConnInfo.iConnId );
+                
+                // Check that connection is started, established to snap,
+                // choose best iap is called for the connection
+                if ( ( iActiveBMConns[index].iConnInfo.iState == EStarted ) &&
+                    ( iActiveBMConns[index].iConnInfo.iSnap ) && 
+                    ( serverSession->ChooseBestIapCalled() ) &&
+                    ( internetSnap ) )
+                    {
+                    // Notify client to disconnect, don't check if current
+                    // WLAN IAP is the best because we want to disconnect
+                    // it anyway (it was not included in available IAP
+                    // list anymore)
+                    RAvailableIAPList iapList;
+                    CleanupClosePushL( iapList );
+                    NotifyDisconnectL( index, packetDataIapIds, iapList, EFalse,
+                        EMPMBearerTypePacketData );
+                    CleanupStack::PopAndDestroy( &iapList );
+                    }
+                }
+            }
+        }
+    CleanupStack::PopAndDestroy( &packetDataIapIds );
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::NotifyDisconnectL
+// -----------------------------------------------------------------------------
+//
+void CMPMServer::NotifyDisconnectL( TInt aConnIndex,
+                                    RArray<TUint32>& aAvailIapIds,
+                                    RAvailableIAPList& aIapList,
+                                    TBool aCheckForBestIap,
+                                    TMPMBearerType aDestinationBearerType )
+    {
+    MPMLOGSTRING( "CMPMServer::NotifyDisconnectL" )
+    
+    // Get iaps in internet snap
+    RArray<TNetIap> destNetIds;
+    CleanupClosePushL( destNetIds );
+    CommsDatAccess()->SearchDNEntriesL( iActiveBMConns[aConnIndex].iConnInfo.iSnap,
+                                        destNetIds );
+
+    // Save available iaps in internet snap
+    RArray<TUint32> iapIdsInInternet;
+    CleanupClosePushL( iapIdsInInternet );
+                        
+    for ( TInt iIndex = 0; iIndex < destNetIds.Count(); iIndex++ )
+        {
+        for ( TInt wIndex = 0; wIndex < aAvailIapIds.Count(); wIndex++ )
+            {
+            if ( destNetIds[iIndex].iIapId == aAvailIapIds[wIndex] )
+                {
+                iapIdsInInternet.AppendL( destNetIds[iIndex].iIapId );
+                break;
+                }
+            }
+                    
+        if ( iapIdsInInternet.Count() )
+            {
+            // Leave loop when count is non-zero
+            break;
+            }
+        }
+
+    // Check if an iap in internet snap is available
+    if ( iapIdsInInternet.Count() )
+        {
+        // Find session and notify error
+        for (TInt sIndex = 0; sIndex < iSessions.Count(); sIndex++ )
+            {
+            // Check that CMPMIapSelection object exists for the session.
+            TRAPD( error, iSessions[sIndex]->IapSelectionL() );
+            if ( error == KErrNone )
+                {
+                MPMLOGSTRING( "CMPMServer::NotifyDisconnectL: IapSelectionL() != NULL" )
+                // Check the connection preferences for forced roaming
+                if ( iSessions[sIndex]->ForcedRoaming() )
+                    {
+                    MPMLOGSTRING( "CMPMServer::NotifyDisconnectL: ForcedRoaming == ETrue" )
+                    // Notify disconnect error for session,
+                    // if mobility api is not used
+                    if ( ( iSessions[sIndex]->ConnectionId() ==
+                        iActiveBMConns[aConnIndex].iConnInfo.iConnId ) &&
+                        !iSessions[sIndex]->PreferredIapRequested() &&
+                        iSessions[sIndex]->IsBearerAccepted( aDestinationBearerType ) )
+                        {
+                        if ( aCheckForBestIap )
+                            {
+                            // Check whether current IAP and the best IAP are the same.
+                            // Disconnection not done if IAPs are the same   
+                            TMpmConnPref connPref;
+                            connPref.SetIapId( 0 );
+                            connPref.SetSnapId(
+                                iActiveBMConns[aConnIndex].iConnInfo.iSnap );
+
+                            iSessions[sIndex]->IapSelectionL()->ChooseBestIAPL( connPref, aIapList );
+
+                            // if the best iap is the current iap, don't roam, move to next item
+                            if ( ( aIapList.Count() > 0 ) && 
+                                ( connPref.IapId() == iActiveBMConns[aConnIndex].iConnInfo.iIapId ) )
+                                {
+                                MPMLOGSTRING( "CMPMServer::NotifyDisconnectL: Same IAP selected. Disconnection not done." )
+                                break;
+                                }
+                            }
+    
+                        MPMLOGSTRING2( "CMPMServer::NotifyDisconnectL: \
+Disconnected Connection Id = 0x%x", iSessions[sIndex]->ConnectionId() )
+                        iSessions[sIndex]->ClientErrorNotificationL( KErrDisconnected );
+                        }
+                    }
+                }
+            }
+        }
+            
+    CleanupStack::PopAndDestroy( &iapIdsInInternet );
+    CleanupStack::PopAndDestroy( &destNetIds );
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::IsVisitorNetwork
+// 
+// Checks if phone is in visitor network or in home network.
+// Return ETrue if phone is in visitor network.
+// Return EFalse if phone is not in visitor network.
+// -----------------------------------------------------------------------------
+//
+TBool CMPMServer::IsVisitorNetwork() const
+    {
+    MPMLOGSTRING( "CMPMServer::IsVisitorNetwork" )
+    
+    if ( iRoamingWatcher->RoamingStatus()== EMPMInternationalRoaming )
+        {
+        MPMLOGSTRING( "CMPMServer::IsVisitorNetwork: TRUE" )
+        return ETrue;
+        } 
+    else
+        {
+        MPMLOGSTRING( "CMPMServer::IsVisitorNetwork: FALSE" )
+        return EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMPMServer::GetServerSession
+// -----------------------------------------------------------------------------
+//
+CMPMServerSession* CMPMServer::GetServerSession( TConnectionId aConnId ) const
+    {
+    MPMLOGSTRING2( "CMPMServer::GetServerSession: \
+Connection Id = 0x%x", aConnId );
+
+    CMPMServerSession* serverSession = NULL;
+    for ( TInt sIndex = 0; sIndex < iSessions.Count(); sIndex++ )
+        {
+        if ( iSessions[sIndex]->ConnectionId() == aConnId )
+            {
+            serverSession = iSessions[sIndex];
+            }
+        }
+
+    ASSERT( serverSession != NULL );
+
+    return serverSession;
+    }
+
+// -----------------------------------------------------------------------------
+// TMPMBlackListConnId::Append
+// -----------------------------------------------------------------------------
+//
+void TMPMBlackListConnId::Append( TUint32 aIap, TBlacklistCategory aCategory )
+    {
+    iBlackListIap.Append( aIap );
+    iCategory.Append( aCategory );
+    }
+
+// -----------------------------------------------------------------------------
+// TMPMBlackListConnId::Remove
+// -----------------------------------------------------------------------------
+//
+void TMPMBlackListConnId::Remove( TInt aIndex )
+    {
+    iBlackListIap.Remove( aIndex );
+    iCategory.Remove( aIndex );    
+    }
+
+// -----------------------------------------------------------------------------
+// TMPMBlackListConnId::Close
+// -----------------------------------------------------------------------------
+//
+void TMPMBlackListConnId::Close()
+    {
+    iBlackListIap.Close();
+    iCategory.Close();    
+    }
+
+// -----------------------------------------------------------------------------
+// TMPMBlackListConnId::Count
+// -----------------------------------------------------------------------------
+//
+TInt TMPMBlackListConnId::Count() const
+    {
+    return iBlackListIap.Count();
+    }
+
+// -----------------------------------------------------------------------------
+// TConnectionInfo::TConnectionInfo
+// -----------------------------------------------------------------------------
+//
+TConnectionInfo::TConnectionInfo() 
+    : iConnId( 0 ),
+      iSnap( 0 ),
+      iIapId( 0 ), 
+      iState( EIdle ),
+      iAppUid( 0 )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// TConnectionInfo::MatchId
+// -----------------------------------------------------------------------------
+//
+TBool TConnectionInfo::MatchId( const TConnectionInfo& aFirst,
+                                       const TConnectionInfo& aSecond )
+    {
+    if ( aFirst.iConnId == aSecond.iConnId )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// TConnectionInfo::MatchIdSnap
+// -----------------------------------------------------------------------------
+//
+TBool TConnectionInfo::MatchIdSnap( const TConnectionInfo& aFirst,
+                                    const TConnectionInfo& aSecond )
+    {
+    if ( ( aFirst.iConnId  == aSecond.iConnId ) &&
+         ( aFirst.iSnap    == aSecond.iSnap ) )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// TActiveBMConn::TActiveBMConn
+// -----------------------------------------------------------------------------
+//
+TActiveBMConn::TActiveBMConn() 
+    : iConnInfo()
+    {
+    }
+
+
+// -----------------------------------------------------------------------------
+// TActiveBMConn::MatchIapId
+// -----------------------------------------------------------------------------
+//
+TBool TActiveBMConn::MatchIapId( const TActiveBMConn& aFirst,
+                                 const TActiveBMConn& aSecond )
+    {
+    if ( aFirst.iConnInfo.iIapId == aSecond.iConnInfo.iIapId )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// TActiveBMConn::MatchConnInfo
+// -----------------------------------------------------------------------------
+//
+TBool TActiveBMConn::MatchConnInfo( const TActiveBMConn& aFirst,
+                                    const TActiveBMConn& aSecond )
+    { 
+    if ( TConnectionInfo::MatchId( aFirst.iConnInfo, aSecond.iConnInfo ) )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+
+//  End of File