diff -r 000000000000 -r 5a93021fdf25 bearermanagement/mpm/src/mpmserversession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bearermanagement/mpm/src/mpmserversession.cpp Thu Dec 17 08:55:21 2009 +0200 @@ -0,0 +1,3838 @@ +/* +* 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 session implementation +* +*/ + +/** +@file mpmserversession.cpp +Mobility Policy Manager server session implementation. +*/ + +// INCLUDE FILES +#include +#include // KErrPacketDataTsyMaxPdpContextsReached +#include // KErrUmtsMaxNumOfContextExceededByNetwork +#include // For feature flags +#include // FeatureManager +#include // CRepository +#include // KCRUidCoreApplicationUIs, + // KCoreAppUIsNetworkConnectionAllowed +#include +#include +#include +#include +#include +#include + +#include "mpmcommsdataccess.h" +#include "mpmserversession.h" +#include "mpmconnmonevents.h" +#include "mpmdialog.h" +#include "mpmdisconnectdlg.h" +#include "mpmconfirmdlgstarting.h" +#include "mpmconfirmdlgroaming.h" +#include "mpmlogger.h" +#include "mpmpropertydef.h" +#include "mpmdefaultconnection.h" +#include "mpmiapselection.h" +#include "mpmcsidwatcher.h" + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMPMServerSession::NewL +// ----------------------------------------------------------------------------- +// +CMPMServerSession* CMPMServerSession::NewL(CMPMServer& aServer) + { + CMPMServerSession* self = new ( ELeave ) CMPMServerSession(aServer); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::CMPMServerSession +// ----------------------------------------------------------------------------- +// +CMPMServerSession::CMPMServerSession(CMPMServer& aServer) + : CSession2(), + iMyServer( aServer ), + iDisconnectDlg( NULL ), + iConfirmDlgRoaming( NULL ), + iStoredIapInfo(), + iIapSelection( NULL ), + iMigrateState( EMigrateNone ) + { + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ConstructL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::ConstructL() + { + MPMLOGSTRING( "CMPMServerSession::ConstructL" ) + if ( !iMyServer.Events() ) + { + iMyServer.SetEvents(CMPMConnMonEvents::NewL( + *const_cast( &iMyServer ), *this )); + } + + FeatureManager::InitializeLibL(); + iOfflineFeatureSupported = FeatureManager::FeatureSupported( + KFeatureIdOfflineMode ); + + FeatureManager::UnInitializeLib(); + + // Append session pointer to server + // + iMyServer.AppendSessionL( this ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::~CMPMServerSession +// ----------------------------------------------------------------------------- +// +CMPMServerSession::~CMPMServerSession() + { + delete iDisconnectDlg; + delete iConfirmDlgRoaming; + delete iIapSelection; + + // Remove serverside objects for notification session. + // + iMyServer.RemoveSession( this ); + + if (UserConnection()) + { + iMyServer.ClearUserConnection(); + ClearUserConnection(); + + // Set PS keys to zero + RProperty::Set( KMPMUserConnectionCategory, + KMPMPSKeyUserConnectionSnap, + 0 ); + + RProperty::Set( KMPMUserConnectionCategory, + KMPMPSKeyUserConnectionIap, + 0 ); + + MPMLOGSTRING( "CMPMServerSession::HandleServerApplicationConnectionEnds -\ +User connection deactivated" ) + } + + // Make sure the connection is removed from server's information array. + iMyServer.RemoveBMConnection( iConnId, *this ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ServiceL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::ServiceL( const RMessage2& aMessage ) + { + switch ( aMessage.Function() ) + { + case EMPMServerChooseIap: + { + HandleServerChooseIapL( aMessage ); + break; + } + case EMPMServerCancelRequest: + { + HandleServerCancelRequest( aMessage ); + break; + } + case EMPMServerApplicationLeavesConnection: + { + HandleServerApplicationLeavesConnection( aMessage ); + break; + } + case EMPMServerIapConnectionStopped: + { + HandleServerIapConnectionStopped( aMessage ); + break; + } + case EMPMServerProcessError: + { + HandleServerProcessErrorL( aMessage ); + break; + } + case EMPMServerRegisterPrefIAPNotif: + { + HandleServerRegisterPrefIAPNotifL( aMessage ); + break; + } + case EMPMServerUnregisterPrefIAPNotif: + { + HandleServerUnregisterPrefIAPNotif( aMessage ); + break; + } + case EMPMServerWaitNotification: + { + HandleServerWaitNotificationL( aMessage ); + break; + } + case EMPMServerSortSNAP: + { + HandleServerSortSNAPL( aMessage ); + break; + } + case EMPMServerApplicationJoinsConnection: + { + HandleServerApplicationJoinsConnection( aMessage ); + break; + } + case EMPMServerIapConnectionActivated: + { + HandleServerIapConnectionActivatedL( aMessage ); + break; + } + case EMPMServerIapConnectionStarted: + { + HandleServerIapConnectionStartedL( aMessage ); + break; + } + case EMPMServerApplicationConnectionEnds: + { + HandleServerApplicationConnectionEnds( aMessage ); + break; + } + case EMPMServerApplicationMigratesToCarrier: + { + HandleServerApplicationMigratesToCarrierL( aMessage ); + break; + } + case EMPMServerApplicationIgnoredTheCarrier: + { + HandleServerApplicationIgnoredTheCarrier( aMessage ); + break; + } + case EMPMServerApplicationAcceptedTheCarrier: + { + HandleServerApplicationAcceptedTheCarrier( aMessage ); + break; + } + case EMPMServerApplicationRejectedTheCarrier: + { + HandleServerApplicationRejectedTheCarrierL( aMessage ); + break; + } + case EMPMServerEasyWlanSsid: + { + // Easy WLAN SSID not used anymore as connecting + // notes have been removed + // + MPMLOGSTRING( "CMPMServerSession::ServiceL \ +completing EMPMServerEasyWlanSsid" ) + aMessage.Complete( KErrNone ); + break; + } + case EMPMServerReselectIap: + { + HandleServerReselectIapL( aMessage ); + break; + } +#ifdef _DEBUG + case EMPMDebugGenerateStopIAPNotification: + { + HandleDebugGenerateStopIAPNotification( aMessage ); + break; + } + case EMPMDebugSwitchConnMonEventsOn: + { + HandleDebugFilterConnMonEvents( aMessage, EFalse ); + break; + } + case EMPMDebugSwitchConnMonEventsOff: + { + HandleDebugFilterConnMonEvents( aMessage, ETrue ); + break; + } + case EMPMDebugShutdown: + { + HandleDebugShutdown( aMessage, ETrue ); + break; + } +#endif //_DEBUG + default: + { + iMyServer.PanicClient( KErrNotSupported ); + } + } + } + +#ifdef _DEBUG +void CMPMServerSession::HandleDebugGenerateStopIAPNotification( const RMessage2& aMessage ) + { + MPMLOGSTRING( "CMPMServerSession::HandleDebugGenerateStopIAPNotification" ) + TInt iap = static_cast( aMessage.Int0() ); + MyServer().StopConnections( iap ); + aMessage.Complete( KErrNone ); + } + +void CMPMServerSession::HandleDebugFilterConnMonEvents( const RMessage2& aMessage, const TBool aVal ) + { + MPMLOGSTRING2( "CMPMServerSession::HandleDebugFilterConnMonEvents FilteringEnabled=%d", aVal ) + TInt iap = static_cast( aMessage.Int0() ); + MyServer().Events()->FilterAvailableIAPEvents( aVal ); + aMessage.Complete( KErrNone ); + } + +void CMPMServerSession::HandleDebugShutdown( const RMessage2& aMessage, const TBool /*aVal*/ ) + { + MPMLOGSTRING( "CMPMServerSession::HandleDebugShutdown" ) + aMessage.Complete( KErrNone ); + + TFindProcess processFinder( _L("*MPMServer*") ); + TFullName name; + + if ( processFinder.Next( name ) == KErrNone ) + { + RProcess process; + + TInt err = process.Open( name ); + + if ( err == KErrNone ) + { + process.Kill( 0 ); + } + + process.Close(); + } + } +#endif //_DEBUG + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ServiceError +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::ServiceError( const RMessage2& aMessage, + TInt aError ) + + { + // Handles the situation when a call to CSession2::ServiceL(), + // which services a client request, leaves. + // + // The default behaviour of this function is to complete the message, + // using the leave value, if it has not already been completed. + // + // Servers can re-implement this as appropriate. + // + MPMLOGSTRING3( + "CMPMServerSession::ServiceError: Service %d failed with error: %d", + aMessage.Function(), + aError ) + if( aMessage.Function() == EMPMServerChooseIap || + aMessage.Function() == EMPMServerReselectIap ) + { + // complete locally stored iChooseIapMessage + // + ChooseIapComplete( aError, NULL ); + } + else if( aMessage.Function() == EMPMServerProcessError ) + { + // complete locally stored iProcessErrorMessage + // + ProcessErrorComplete( aError, NULL, NULL ); + } + else if( !aMessage.IsNull() ) + { + // Complete message if it hasn't been + // already completed + // + aMessage.Complete( aError ); + } + else + { + MPMLOGSTRING( + "CMPMServerSession::ServiceError: Message has already been completed" ) + } + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerChooseIapL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerChooseIapL( const RMessage2& aMessage ) + { + MPMLOGSTRING2( "CMPMServerSession::HandleServerChooseIapL session <0x%x>", this ) + + // Read the Connection Id of the application + // + iConnId = aMessage.Int1(); + MPMLOGSTRING2( "CMPMServerSession::HandleServerChooseIapL: \ +Connection Id = 0x%x", iConnId ) + + // Sanity check that client only has one outstanding ChooseBestIAP() or ReselectBestIAP() -call. + // + if ( !iChooseIapMessage.IsNull() ) + { + MPMLOGSTRING2( "CMPMServerSession::HandleServerChooseIapL: - Error \ +ChooseBestIAP() or ReselectBestIAP() already exists %d", KErrServerBusy ); + aMessage.Complete( KErrServerBusy ); + } + + // Sanity check that client doesn't call ChooseBestIAPL() twice for the same session. + // + if ( ChooseBestIapCalled() ) + { + MPMLOGSTRING2( "CMPMServerSession::HandleServerChooseIapL: - Error \ +ChooseBestIAP() already completed or in progress %d", KErrAlreadyExists ) + aMessage.Complete( KErrAlreadyExists ); + return; + } + + // We must save the RMessage in order to complete it later. + // + iChooseIapMessage = aMessage; + TConnPref connPref; + aMessage.ReadL( KFirstArgument, connPref ); + + // Extract connection preferences + // + TMpmConnPref mpmConnPref; + TInt error = ExtractConnPref( connPref, mpmConnPref ); + + if ( error != KErrNone ) + { + MPMLOGSTRING( "CMPMServerSession::HandleServerChooseIapL - Error \ +while extracting TCommDbConnPref from TConnPref" ) + aMessage.Complete( error ); + return; + } + + // Store the Uid of the application to the member variable so + // that it can be used to avoid DisconnectDialog popping up when + // AlwaysOnline connection is being established. + // + iAppUid = aMessage.Int2(); + + if ( !iIapSelection ) + { + iIapSelection = CMPMIapSelection::NewL( iMyServer.CommsDatAccess(), + this ); + } + + MPMLOGSTRING3( "CMPMServerSession::HandleServerChooseIapL - iap %d \ +connType %d", mpmConnPref.IapId(), mpmConnPref.ConnType() ) + + iIapSelection->ChooseIapL( mpmConnPref ); + + if ( iAppUid == iMyServer.CsIdWatcher()->ConnectScreenId() ) + { + MPMLOGSTRING( "CMPMServerSession::HandleServerChooseIapL -\ + User connection activated" ) + + // This is user connection + iMyServer.SetUserConnection(); + SetUserConnection(); + iMyServer.SetUserConnPref( mpmConnPref ); + + // Set PS keys according to user connection + // Do not check return values. Can do nothing in case of failing. + RProperty::Set( KMPMUserConnectionCategory, + KMPMPSKeyUserConnectionSnap, + mpmConnPref.SnapId() ); + + RProperty::Set( KMPMUserConnectionCategory, + KMPMPSKeyUserConnectionIap, + mpmConnPref.IapId() ); + } + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerCancelRequest +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerCancelRequest( const RMessage2& aMessage ) + { + TInt cancelcode = aMessage.Int0(); + MPMLOGSTRING2( + "CMPMServerSession::HandleServerCancelRequest - Request code = %i", + cancelcode ) + + switch ( cancelcode ) + { + case EMPMReselectBestIAP: + case EMPMChooseBestIAP: + { + // Complete original request + // + ChooseIapComplete( KErrCancel, NULL ); + + // Complete cancel request + // + MPMLOGSTRING( + "CMPMServerSession::HandleServerCancelRequest - Complete with KErrNone" ) + aMessage.Complete( KErrNone ); + + // Cancel WLAN scan request if one exists + // + TRAP_IGNORE( iMyServer.Events()->CancelScanL( *this ) ) + + if ( iIapSelection ) + { + delete iIapSelection; + iIapSelection = NULL; + } + return; + } + case EMPMProcessError: + { + ProcessErrorComplete( KErrCancel, + NULL, + NULL ); + // Complete cancel request + // + MPMLOGSTRING( + "CMPMServerSession::HandleServerCancelRequest - Complete with KErrNone" ) + aMessage.Complete( KErrNone ); + + // Cancel WLAN scan request if one exists + // + TRAP_IGNORE( iMyServer.Events()->CancelScanL( *this ) ) + + if ( iDisconnectDlg ) + { + MPMLOGSTRING( "CMPMServerSession::HandleServerCancelRequest: \ +removing dconn dlg" ) + delete iDisconnectDlg; + iDisconnectDlg = NULL; + } + return; + } + case EMPMWaitNotification: + { + if ( iNotifRequested ) + { + iNotifRequested = EFalse; + iNotifMessage.Complete( KErrCancel ); + } + break; + } + case EMPMSortSNAP: + { + if ( !iServerSortSNAPMessage.IsNull() ) + { + // TODO Change CancelScanL to non-leaving. + // Otherwise, nothing clever can be done here. + // And OOM may risk MPM stability. + TRAP_IGNORE( iMyServer.Events()->CancelScanL( *this )) + iServerSortSNAPMessage.Complete( KErrCancel ); + } + break; + } + default: + { + MPMLOGSTRING( "CMPMServerSession::HandleServerCancelRequest - \ +Unknown cancel request received" ) + } + } + MPMLOGSTRING( + "CMPMServerSession::HandleServerCancelRequest - Complete with KErrNone" ) + aMessage.Complete( KErrNone ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerApplicationJoinsConnection +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerApplicationJoinsConnection( + const RMessage2& aMessage ) + { + // Read Iap Id + // + TUint32 joinIap = static_cast( aMessage.Int0() ); + + // Read the Connection Id of the application + // + TConnectionId joinId = aMessage.Int1(); + + //-jl- Make sure id is known & assert it stays the same. + ASSERT(iConnId == joinId || iConnId == NULL); + iConnId = joinId; + + MPMLOGSTRING3( + "CMPMServerSession::HandleServerApplicationJoinsConnection \ +- IAP Id = %i, Connection Id = 0x%x", joinIap, joinId ) + + // Get the current connection SNAP for this Connection Id + // + TUint32 snapId = iMyServer.GetBMSnap( joinId ); + + + // Decides the correct state by the IAP status. + if ( iMyServer.StartedConnectionExists( joinIap ) == joinIap ) + { + iMyServer.AppendBMConnection( joinId, + snapId, + joinIap, + EStarted, + *this ); + } + else + { + iMyServer.AppendBMConnection( joinId, + snapId, + joinIap, + EStarting, + *this ); + } + + aMessage.Complete( KErrNone ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerApplicationLeavesConnection +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerApplicationLeavesConnection( + const RMessage2& aMessage ) + { + // Read Iap Id + // + TUint32 leaveIap = static_cast( aMessage.Int0() ); + + // Read the Connection Id of the application + // + TConnectionId leaveId = aMessage.Int1(); + + MPMLOGSTRING3( + "CMPMServerSession::HandleServerApplicationLeavesConnectionL \ +- IAP Id = %i, Connection Id = 0x%x", leaveIap, leaveId ) + + iMyServer.Events()->ResetConnInfo( leaveId ); + iMyServer.ResetBMConnection( leaveId, leaveIap, *this ); + + aMessage.Complete( KErrNone ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerIapConnectionActivatedL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerIapConnectionActivatedL( + const RMessage2& aMessage ) + { + // Read Iap Id + // + TUint32 activatedIap = static_cast( aMessage.Int0() ); + + // Read the Connection Id of the application + // + TConnectionId activatedId = aMessage.Int1(); + + //-jl- Make sure id is known & assert it stays the same. + ASSERT(iConnId == activatedId || iConnId == NULL); + iConnId = activatedId; + + MPMLOGSTRING3( + "CMPMServerSession::HandleServerIapConnectionActivatedL \ +- IAP Id = %i, Connection Id = 0x%x", activatedIap, activatedId ) + + MPMLOGSTRING( + "CMPMServerSession::HandleServerIapConnectionActivatedL \ +- Complete IapConnectionActivated" ) + aMessage.Complete( KErrNone ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerIapConnectionStarted +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerIapConnectionStartedL( + const RMessage2& aMessage ) + { + // Read Iap Id + // + TUint32 startedIap = static_cast( aMessage.Int0() ); + + // Read the Connection Id of the application + // + TConnectionId startedId = aMessage.Int1(); + + //-jl- Make sure id is known & assert it stays the same. + ASSERT(iConnId == startedId || iConnId == NULL); + iConnId = startedId; + + MPMLOGSTRING3( "CMPMServerSession::HandleServerIapConnectionStarted\ + - IAP Id = %i, Connection Id = 0x%x", startedIap, startedId ) + + iMyServer.AppendBMIAPConnectionL( startedIap, startedId, *this ); + + // Unblacklist all IAPs related to the connection error + // when connection has started. + // + iMyServer.HandleServerUnblackListIap( startedId, ETemporary ); + + // Complete the message as soon as possible to avoid latency in BM + // + aMessage.Complete( KErrNone ); + + IapSelectionL()->ConnectionStarted(); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerIapConnectionStopped +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerIapConnectionStopped( + const RMessage2& aMessage ) + { + // Read Iap Id + // + TUint32 stoppedIap = static_cast( aMessage.Int0() ); + + // Read the Connection Id of the application + // + TConnectionId stoppedId = aMessage.Int1(); + + MPMLOGSTRING3( "CMPMServerSession::HandleServerIapConnectionStopped\ + - IAP Id = %i, Connection Id = 0x%x", stoppedIap, stoppedId ) + + iMyServer.RemoveBMIAPConnection( stoppedIap, stoppedId, *this ); + + // Complete the message as soon as possible to avoid latency in BM + // + aMessage.Complete( KErrNone ); + + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerApplicationConnectionEnds +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerApplicationConnectionEnds( + const RMessage2& aMessage ) + { + // Read the Connection Id of the application + // + TConnectionId endId = aMessage.Int0(); + + if (UserConnection()) + { + iMyServer.ClearUserConnection(); + ClearUserConnection(); + + // Set PS keys to zero + RProperty::Set( KMPMUserConnectionCategory, + KMPMPSKeyUserConnectionSnap, + 0 ); + + RProperty::Set( KMPMUserConnectionCategory, + KMPMPSKeyUserConnectionIap, + 0 ); + + MPMLOGSTRING( "CMPMServerSession::HandleServerApplicationConnectionEnds -\ +User connection deactivated" ) + } + + MPMLOGSTRING2( "CMPMServerSession::HandleServerApplicationConnectionEnds\ + - Connection Id = 0x%x", endId ) + + // Unblacklist all IAPs related to this connection + // when connection closes. + // + iMyServer.HandleServerUnblackListIap( endId, 0 ); + + // Remove info about this connection + // + iMyServer.Events()->RemoveConnInfo( endId ); + + // SNAP lifetime is determined by the two calls ChooseBestIAP + // and ApplicationConnectionEnds. + // + iMyServer.RemoveBMConnection( endId, *this ); + + // Clear notification registration if one exists for the connection + // + iPreferredIAPRequested = EFalse; + + // Complete message before calling synchronous Cancel functions + aMessage.Complete( KErrNone ); + + delete iConfirmDlgRoaming; + iConfirmDlgRoaming = NULL; + + if( iIapSelection ) + { + delete iIapSelection; + iIapSelection = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::IsConfirmFirstL +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::IsConfirmFirstL( const TUint32 aIapId ) + { + TCmGenConnSettings genConnSettings; + TBool isConfirmFirst( EFalse ); + + MPMLOGSTRING3( "CMPMServerSession::IsConfirmFirstL - IAP Id = %i Connection Id = 0x%x", + aIapId, + iConnId ) + + // check whether a started connection exists which already + // uses this IAP. If so, it won't need to be confirmed again + // + if( iMyServer.CheckIfStarted( aIapId ) ) + { + MPMLOGSTRING( + "CMPMServerSession::IsConfirmFirstL - IAP already started, \ +confirm not necesary - False" ) + return EFalse; + } + + if ( IsBackgroundApplication( iAppUid ) || IsMMSIap( aIapId ) ) + { + MPMLOGSTRING( + "CMPMServerSession::IsConfirmFirstL - background IAP, \ +should not be confirmed - False" ) + return EFalse; + } + + // Read global OCC seamlessness values from CommsDat's DefConn table + genConnSettings = iMyServer.CommsDatAccess()->ReadGenConnSettingsL(); + + TUint32 currentSeamlessness( genConnSettings.iSeamlessnessHome ); + + if ( iMyServer.IsVisitorNetwork() ) + { + currentSeamlessness = genConnSettings.iSeamlessnessVisitor; + } + + if ( currentSeamlessness == ECmSeamlessnessShowprogress || + currentSeamlessness == ECmSeamlessnessFullySeamless ) + { + MPMLOGSTRING( "CMPMServerSession::IsConfirmFirstL - False" ) + isConfirmFirst = EFalse; + } + else + { + // The currentSeamlessness value ECmSeamlessnessConfirmFirst + // matches with need to display confirmation dialog. + // + MPMLOGSTRING( + "CMPMServerSession::IsConfirmFirstL - True" ) + isConfirmFirst = ETrue; + } + return isConfirmFirst; + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerApplicationMigratesToCarrierL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerApplicationMigratesToCarrierL( + const RMessage2& aMessage ) + { + // Read Iap Id + // + iMigrateIap = static_cast( aMessage.Int0() ); + + // Complete the message ApplicationMigratesToCarrier already here, + // otherwise MPM would be hanging Esock thread when displaying the + // confirmation dialog while roaming. + // + aMessage.Complete( KErrNone ); + + MPMLOGSTRING3( + "CMPMServerSession::HandleServerApplicationMigratesToCarrierL\ + - IAP Id = %i, Connection Id = 0x%x", iMigrateIap, iConnId ) + + delete iConfirmDlgRoaming; + iConfirmDlgRoaming = NULL; + + // Get the current connection SNAP for this Connection Id + // + TUint32 snapId = iMyServer.GetBMSnap( iConnId ); + + // We have to find out the current IAP of connection in order + // to determine whether this is an upgrade or downgrade. + // + TUint32 currentIap = iMyServer.GetBMIap( iConnId ); + + iMyServer.AppendBMConnection( iConnId, + snapId, + iMigrateIap, + ERoaming, + *this ); + + iMigrateState = EMigrateUserConfirmation; + + // Confirm only if this IAP is not already in use + // + if ( ( currentIap != iMigrateIap ) && + IsConfirmFirstL( iMigrateIap ) ) + { + TBool nextBestExists( EFalse ); + TMpmConnPref mpmConnPref; + RAvailableIAPList availableIAPList; + + CleanupClosePushL( availableIAPList ); + AvailableUnblacklistedIapsL( availableIAPList, + iConnId ); + + mpmConnPref.SetSnapId( snapId ); + + IapSelectionL()->ChooseBestIAPL( mpmConnPref, availableIAPList, nextBestExists ); + + TBool reconnect ( EFalse ); + if ( !IsUpgrade( currentIap, iMigrateIap, availableIAPList ) ) + { + reconnect = ETrue; + } + + //Display confirm dialog only if we are moving to cellular IAP + if ( MyServer().CommsDatAccess()->CheckWlanL( iMigrateIap ) == ENotWlanIap ) + { + if ( !( iIapSelection->MpmConnPref().NoteBehaviour() & TExtendedConnPref::ENoteBehaviourConnDisableQueries ) ) + { + if ( MyServer().RoamingWatcher()->RoamingStatus() == EMPMInternationalRoaming ) + { + //Check if cellular data usage query has already been presented to the user in this country + if ( MyServer().RoamingWatcher()->AskCellularDataUsageAbroad() == true ) + { + //International roaming + iConfirmDlgRoaming = CMPMConfirmDlgRoaming::NewL( + *this, + snapId, + iMigrateIap, + CMPMConfirmDlg::EConfirmDlgVisitorNetwork, + reconnect ); + } + else + { + //Handle like user would have answered "Connect this time" to dialog + RoamingConfirmationCompletedL( KErrNone, EMsgQueryThisTime, reconnect ); + } + } + else + { + //Home network + iConfirmDlgRoaming = CMPMConfirmDlgRoaming::NewL( + *this, + snapId, + iMigrateIap, + CMPMConfirmDlg::EConfirmDlgHomeNetwork, + reconnect ); + } + } + + else + { + RoamingConfirmationCompletedL( KErrCancel, EMsgQueryCancelled, reconnect ); + } + } + //IAP was WLAN IAP + else + { + //Handle like user would have answered "Connect this time" to dialog + RoamingConfirmationCompletedL( KErrNone, EMsgQueryThisTime, reconnect ); + } + + // Release memory + // + CleanupStack::PopAndDestroy( &availableIAPList ); + } + else + { + // Handle next state in migration + // + MigrateCallbackL( KErrNone ); + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::MigrateCallbackL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::MigrateCallbackL( TInt aError ) + { + if( iMigrateState == EMigrateUserConfirmation ) + { + MPMLOGSTRING2( "CMPMServerSession<0x%x>::MigrateCallbackL: State user confirmation", + iConnId ) + if( aError == KErrNone ) + { + iMigrateState = EMigrateOfflineConfirmation; + if( IapSelectionL()->StartWlanQueryIfNeededL( iMigrateIap, ETrue ) ) + { + return; + } + } + } + else if( iMigrateState == EMigrateOfflineConfirmation ) + { + MPMLOGSTRING3( "CMPMServerSession<0x%x>::MigrateCallbackL: State offline confirmation error: %d", + iConnId, + aError ) + if( aError != KErrNone ) + { + ErrorNotificationL( aError, EMPMMobilityErrorNotification ); + } + } + else // EMigrateNone + { + MPMLOGSTRING2( "CMPMServerSession<0x%x>::MigrateCallbackL: State none", + iConnId ) + + } + MigrateDoneL( aError ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::RoamingConfirmationCompletedL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::RoamingConfirmationCompletedL( TInt aError, + TMsgQueryLinkedResults aResponse, + TBool aReconnect ) + { + TInt error( KErrNone); + MPMLOGSTRING5( "CMPMServerSession<0x%x>::RoamingConfirmationCompleted: \ +aError %d, aResponse %d, aReconnect %d", + iConnId, + aError, + aResponse, + aReconnect ) + + if( aError == KErrNone ) + { + if( aResponse == EMsgQueryCancelled ) + { + if( !aReconnect ) + { + // Send a preferred IAP notification + // + TConnMonIapInfo availableIAPs; + availableIAPs = GetAvailableIAPs(); + + // Get the current and presumed IapId for this connId + // + TUint32 currentIap = iMyServer.GetBMIap( ConnectionId() ); + TUint32 presumedIap = MyServer().Events()->PresumedIapId( + ConnectionId(), iMigrateIap ); + + MyServer().HandleServerBlackListIap( ConnectionId(), + currentIap, + EConnectionLifetime ); + if ( ( presumedIap != 0 ) && + ( presumedIap != currentIap ) ) + { + iMyServer.HandleServerBlackListIap( ConnectionId(), + presumedIap, + EConnectionLifetime ); + } + + TRAPD( err, PrefIAPNotificationL( availableIAPs, + EConfirmDlgRoaming ) ); + if ( err == KErrNotFound ) + { + // We need to send a notification error to BearerMan + // if sending preferred IAP notifications failed. + // + ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ); + + } + } + else // aReconnect + { + ErrorNotificationL( KErrCancel, + EMPMMobilityErrorNotification ); + } + + error = KErrCancel; + } + //User selected Connect automatically + else if ( aResponse == EMsgQueryAutomatically ) + { + //Store selected value to commsdat if we are in home network + if ( MyServer().RoamingWatcher()->RoamingStatus() == EMPMHomenetwork ) + { + TCmGenConnSettings genConnSettings; + + TRAPD(errorCode,genConnSettings = MyServer().CommsDatAccess()->ReadGenConnSettingsL()); // call a function + + //If reading of database failed we do not write back to the database to prevent random values + if (errorCode == KErrNone) + { + genConnSettings.iSeamlessnessHome = ECmSeamlessnessShowprogress; + TRAP_IGNORE(MyServer().CommsDatAccess()->WriteGenConnSettingsL( genConnSettings )); + } + } + else + { + //In foreign country connect automatically is not stored in commsdat + //even user selected so. We just do not ask confirmation for the cellular + //connection again in this country: + MyServer().RoamingWatcher()->SetAskCellularDataUsageAbroad( false ); + } + } + + //user selected connect this time + else + { + MPMLOGSTRING3( "CMPMServerSession<0x%x>::RoamingConfirmationCompleted: \ +Unknown response: %d", iConnId, aResponse ) + } + } + else // error occurred + { + ErrorNotificationL( aError, EMPMMobilityErrorNotification ); + error = KErrCancel; + } + MigrateCallbackL( error ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::StopConnection +// ----------------------------------------------------------------------------- +// +TInt CMPMServerSession::StopConnection() + { + TInt ret = KErrNone; + MPMLOGSTRING( "CMPMServerSession::StopConnection" ) + + TConnectionState state( EIdle ); + + iMyServer.GetConnectionState( iConnId, state ); + + if ( state == EStarted || state == EStarting ) + { + TRAP(ret, StopIAPNotificationL()); + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerApplicationIgnoredTheCarrier +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerApplicationIgnoredTheCarrier( + const RMessage2& aMessage ) + { + TInt error( KErrNotFound ); + + // MPM has been waiting for the response to preferred. + // Release the possible new notifications. + // + iStoredIapInfo.ResetStoredIapInfo(); + + // Read Iap Id + // + TUint32 ignoredIap = static_cast( aMessage.Int0() ); + + // Read the Connection Id of the application + // + TConnectionId ignoredId = aMessage.Int1(); + + MPMLOGSTRING3( + "CMPMServerSession::HandleServerApplicationIgnoredTheCarrier \ +- IAP Id = %i, Connection Id = 0x%x", ignoredIap, ignoredId ) + + // Blacklisting should be done before ResetConnInfo(), + // since iPresumedIapId is reset during ResetConnInfo(). + // + iMyServer.HandleServerBlackListIap( ignoredId, + ignoredIap, + EConnectionLifetime ); + + iMyServer.Events()->ResetConnInfo( ignoredId ); + + TConnMonIapInfo availableIAPs; + availableIAPs = GetAvailableIAPs(); + + if ( availableIAPs.iCount > 0 ) + { + TRAP( error, PrefIAPNotificationL( availableIAPs, EBearerMan ) ); + if ( error == KErrNotFound ) + { + TRAP( error, ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ); + } + } + else + { + MPMLOGSTRING( + "CMPMServerSession::HandleServerApplicationIgnoredTheCarrier - \ +No IAPs available, send error notification" ) + TRAP( error, ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ); + } + aMessage.Complete( error ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerApplicationAcceptedTheCarrier +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerApplicationAcceptedTheCarrier( + const RMessage2& aMessage ) + { + // Read Iap Id + // + TUint32 acceptedIap = static_cast( aMessage.Int0() ); + + // Read the Connection Id of the application + // + TConnectionId acceptedId = aMessage.Int1(); + + MPMLOGSTRING3( + "CMPMServerSession::HandleServerApplicationAcceptedTheCarrier \ +- IAP Id = %i, Connection Id = 0x%x", acceptedIap, acceptedId ) + + // Get the current connection SNAP for this Connection Id + // + TUint32 snapId = iMyServer.GetBMSnap( acceptedId ); + + iMyServer.AppendBMConnection( acceptedId, + snapId, + acceptedIap, + EStarted, + *this ); + + aMessage.Complete( KErrNone ); + + // If there is saved IAP info, handle it now + // + TConnMonIapInfo iapInfo; + if( iStoredIapInfo.HandleIapInfoWaiting( iapInfo ) ) + { + iStoredIapInfo.ResetStoredIapInfo(); + // Attempt to send the preferred IAP notification + // if notification has arrived during roaming. + // + TRAPD( error, PrefIAPNotificationL( iapInfo, EConnMon ) ); + if( error != KErrNone ) + { + MPMLOGSTRING2( + "CMPMServerSession::HandleServerApplicationAcceptedTheCarrier \ +PrefIAPNotification error = %i, ", error ) + } + } + else + { + iStoredIapInfo.ResetStoredIapInfo(); + } + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerApplicationRejectedTheCarrierL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerApplicationRejectedTheCarrierL( + const RMessage2& aMessage ) + { + // PrefIAPNotif will be attempted with latest available IAPs + // + iStoredIapInfo.ResetStoredIapInfo(); + + TInt error( KErrNone ); + + // Read Iap Id + // + TUint32 rejectedIap = static_cast( aMessage.Int0() ); + + // Read the Connection Id of the application + // + TConnectionId rejectedId = aMessage.Int1(); + + MPMLOGSTRING3( + "CMPMServerSession::HandleServerApplicationRejectedTheCarrierL \ +- IAP Id = %i, Connection Id = 0x%x", rejectedIap, rejectedId ) + + // Blacklisting should be done before ResetConnInfo(), + // since iPresumedIapId is reset during ResetConnInfo(). + // + iMyServer.HandleServerBlackListIap( rejectedId, + rejectedIap, + EConnectionLifetime ); + + iMyServer.Events()->ResetConnInfo( rejectedId ); + iMyServer.ResetBMConnection( rejectedId, rejectedIap, *this ); + + // If possible to roam from a WLAN IAP to another WLAN IAP + // perform WLAN scan first. + // Currently ConnMon can't send notifications during this time as it + // handles requests syncronously. So, that shouldn't cause problems now, + // but issue should be reviewed if that changes. + // + TUint32 snapId = iMyServer.GetBMSnap( rejectedId ); + RArray iapPath; + CleanupClosePushL( iapPath ); + if( ( iMyServer.CommsDatAccess()->CheckWlanL( rejectedIap ) != ENotWlanIap ) && + iMyServer.CommsDatAccess()->SnapContainsWlanL( snapId, iapPath, KMPMNrWlansTwo ) ) + { + // perform WLAN scan + // message is completed in callback function + // CompleteCarrierRejected + // + iMyServer.Events()->ScanWLANNetworksL( this, + ConnectionId(), + EWlanScanCallbackCarrierRejected ); + CleanupStack::PopAndDestroy( &iapPath ); + aMessage.Complete( error ); + return; + } + else + { + CompleteCarrierRejected(); + } + CleanupStack::PopAndDestroy( &iapPath ); + aMessage.Complete( error ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::GetServiceIdSettingL +// ----------------------------------------------------------------------------- +// +TInt CMPMServerSession::GetServiceIdSettingL() + { + TUint32 iap( 0 ); + TInt id( KErrNotFound ); + + MPMLOGSTRING2( "CMPMServerSession::GetServiceIdSettingL - \ +Setting name %S", &KIapProxyServiceSetting() ) + + iap = GetPresumedIap(); + if( !iap ) + { + MPMLOGSTRING( "CMPMServerSession::HandleServerGetIntSetting - \ + Iap for the connection not found" ) + id = KErrNotFound; + } + else + { + id = iMyServer.CommsDatAccess()->GetIapServiceIdL( iap ); + // validate commsdat value. + id = id > 0 && id <= 256 ? id : KErrNotFound; + } + return id; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerReselectIapL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerReselectIapL( const RMessage2& aMessage ) + { + MPMLOGSTRING2( "CMPMServerSession::HandleServerReselectIapL session <0x%x>", this ) + // Sanity check that client only has one outstanding ChooseBestIAP() or ReselectBestIAP() -call. + // + if ( !iChooseIapMessage.IsNull() ) + { + MPMLOGSTRING2( "CMPMServerSession::HandleServerReselectIapL: - Error \ + ChooseBestIAP() or ReselectBestIAP() already exists %d", KErrServerBusy ) + aMessage.Complete( KErrServerBusy ); + } + + // We must save the RMessage in order to complete it later. + // + iChooseIapMessage = aMessage; + + if ( !ChooseBestIapCalled() ) + { + MPMLOGSTRING( "CMPMServerSession::HandleServerReselectIapL - Error: \ +ChooseBestIap hasn't been called yet" ) + aMessage.Complete( KErrNotReady ); + return; + } + + MPMLOGSTRING3( "CMPMServerSession::HandleServerReselectIapL - iap %d \ +connType %d", iIapSelection->MpmConnPref().IapId(), iIapSelection->MpmConnPref().ConnType() ) + + iIapSelection->ChooseIapL( iIapSelection->MpmConnPref() ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerProcessErrorL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerProcessErrorL( + const RMessage2& aMessage ) + { + // Store message. This is used to complete the message later + // if asynchronous services are needed first or in Service error + iProcessErrorMessage = aMessage; + + if ( iIapSelection ) + { + iIapSelection->StopDisplayingStartingDlg(); + } + + // Read Error code + // + TInt error( KErrNone ); + TPtr8 errorPtr( reinterpret_cast< TUint8* >( NULL ), 0 ); + errorPtr.Set( reinterpret_cast< TUint8* >( &error ), + sizeof( error ), + sizeof( error ) ); + + // Read the contents of the client pointer into a TPtr8. + // + TInt res = iProcessErrorMessage.Read( KFirstArgument, errorPtr ); + if ( res != KErrNone ) + { + iMyServer.PanicClient( KErrBadDescriptor ); + return; + } + + if ( !ChooseBestIapCalled() ) + { + MPMLOGSTRING( "CMPMServerSession::HandleServerProcessErrorL - \ +Warning: ChooseBestIap has not been called yet" ) + TBMNeededAction neededAction( EPropagateError ); + ProcessErrorComplete( KErrNone, &error, &neededAction ); + return; + } + + // Show error popup if it's allowed per client request + if ( !( iIapSelection->MpmConnPref().NoteBehaviour() & + TExtendedConnPref::ENoteBehaviourConnDisableNotes ) ) + { + CConnectionUiUtilities* connUiUtils = CConnectionUiUtilities::NewL(); + // Note: Below function shows the discreet popup only if the error code + // belongs to the set of errors that are shown to the user. + // Otherwise the popup is not shown. + connUiUtils->ConnectionErrorDiscreetPopup( error ); + delete connUiUtils; + connUiUtils = NULL; + } + + // Read the Connection Id of the application + // + TConnectionId connId = iProcessErrorMessage.Int1(); + + MPMLOGSTRING3( "CMPMServerSession::HandleServerProcessErrorL\ + - error code = %i, Connection Id = 0x%x", error, connId ) + + // Get the current connection IapId for this connId + // + TUint32 currentIap = iMyServer.GetBMIap( connId ); + + // Get the current connection SNAP for this Connection Id + // + TUint32 snapId = iMyServer.GetBMSnap( connId ); + + TConnMonIapInfo availableIAPs; + availableIAPs = GetAvailableIAPs(); + + RemoveUnavailableIap( availableIAPs, currentIap ); + + TBMNeededAction neededAction( EIgnoreError ); + + // Get the state of the connection for this Iap Id. + // + TConnectionState state; + iMyServer.GetConnectionState( connId, state ); + + // We need to blacklist the presumed IAP too + // + TUint32 presumedIap = MyServer().Events()->PresumedIapId( connId, + currentIap ); + + // Reset connection info. + // + iMyServer.Events()->ResetIapConnInfo( currentIap ); + + // Check if IAP is reported by MMS + // + TBool isMMSIap = IsMMSIap( currentIap ); + if ( isMMSIap ) + { + MPMLOGSTRING( "CMPMServerSession::HandleServerProcessErrorL\ + - DisconnectDialog is not started because of MMS reported IAP" ) + } + + TInt* returnError( NULL ); + if ( ( state == EStarting ) || ( state == ERoaming ) ) + { + // Process error according to the fact that the connection + // has not yet been started. + // + if ( DisconnectDlgErrorCode( error ) && + !IsBackgroundApplication( iAppUid ) && + !isMMSIap && + iIapSelection->MpmConnPref().DisconnectDialog() && + iMyServer.StartedConnectionExists() != KErrNotFound ) + { + // Start the Disconnect dialog + // + MPMLOGSTRING( "CMPMServerSession::HandleServerProcessErrorL\ + - Start Disconnect dialog" ) + iDisconnectDlg = CMPMDisconnectDlg::NewL( *const_cast(this), + error, + *MyServer().DisconnectQueue() ); + return; + } + else + { + MPMLOGSTRING( "CMPMServerSession::HandleServerProcessErrorL - \ +Error not handled with disconnect dialog" ) + + if ( state == EStarting ) + { + if ( ( snapId == 0 ) || ( error == KErrCancel ) ) + { + neededAction = EPropagateError; + + MPMLOGSTRING( + "CMPMServerSession::HandleServerProcessErrorL - \ +Tell BM to end the client connection with appropriate error code" ) + } + else + { + neededAction = EDoReselection; + + MPMLOGSTRING( + "CMPMServerSession::HandleServerProcessErrorL - \ +Tell BM to ignore error and do reselection" ) + + iMyServer.HandleServerBlackListIap( connId, + currentIap, + ETemporary ); + if ( ( presumedIap != 0 ) && + ( presumedIap != currentIap ) ) + { + iMyServer.HandleServerBlackListIap( connId, + presumedIap, + ETemporary ); + } + } + } + else if ( state == ERoaming ) + { + // ERoaming means commsfw stack is moving to new IAP and failed. + // Hence, MPM should mark to current iap as zero. + // + iMyServer.ResetBMConnection( iConnId, currentIap, *this ); + + // Notification will be sent with latest + // availability info + // + iStoredIapInfo.ResetStoredIapInfo(); + + neededAction = EIgnoreError; + + iMyServer.HandleServerBlackListIap( connId, + currentIap, + ETemporary ); + if ( ( presumedIap != 0 ) && + ( presumedIap != currentIap ) ) + { + iMyServer.HandleServerBlackListIap( connId, + presumedIap, + ETemporary ); + } + TRAP( error, PrefIAPNotificationL( availableIAPs, + EBearerMan ) ); + if ( error == KErrNotFound ) + { + neededAction = EPropagateError; + + returnError = &error; + + TRAP_IGNORE( ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ); + MPMLOGSTRING( + "CMPMServerSession::HandleServerProcessErrorL - \ +Tell BM to end the client connection with appropriate error code" ) + } + else + { + MPMLOGSTRING( + "CMPMServerSession::HandleServerProcessErrorL - \ +Tell BM to ignore error and let MPM notify application about preferred IAP" ) + } + } + else + { + MPMLOGSTRING2( + "CMPMServerSession::HandleServerProcessErrorL - \ +Unknown state %d", state ) + } + + // Error might be different from KErrNone if there + // is no preferred IAP among the available IAPs. + // + ProcessErrorComplete( KErrNone, + returnError, + &neededAction ); + return; + } + } + else if ( state == EStarted ) + { + // Process error according to the fact that the connection + // has already been started. + // + if ( ( error == KErrCancel ) || ( error == KErrTimedOut ) ) + { + neededAction = EPropagateError; + + MPMLOGSTRING( + "CMPMServerSession::HandleServerProcessErrorL - \ +Tell BM to end the client connection with appropriate error code" ) + + // Send error notification. + // Not sent if connection not registered + // + TRAP_IGNORE( ErrorNotificationL( error, + EMPMMobilityErrorNotification ) ) + } + else if ( iPreferredIAPRequested ) + { + // IAP connection + // + if( snapId == 0 ) + { + neededAction = EPropagateError; + + MPMLOGSTRING( + "CMPMServerSession::HandleServerProcessErrorL - \ +Tell BM to end the client connection with appropriate error code" ) + + TRAP_IGNORE( ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ) + } + // SNAP connection + // + else + { + // If this has been WLAN IAP and the SNAP contains + // other WLAN IAPs, we need to perform WLAN scan before + // knowing the availability of those + // + RArray iapPath; + CleanupClosePushL( iapPath ); + + iMyServer.HandleServerBlackListIap( connId, + currentIap, + ETemporary ); + if ( ( presumedIap != 0 ) && + ( presumedIap != currentIap ) ) + { + iMyServer.HandleServerBlackListIap( connId, + presumedIap, + ETemporary ); + } + + // current iap is either WLAN or EasyWlan + // + if( ( iMyServer.CommsDatAccess()->CheckWlanL( currentIap ) != ENotWlanIap ) && + iMyServer.CommsDatAccess()->SnapContainsWlanL( snapId, iapPath, KMPMNrWlansTwo ) ) + { + // perform WLAN scan + // message is completed in callback function + // ProcessErrorWlanScanCompletedL + // + iMyServer.Events()->ScanWLANNetworksL( this, + ConnectionId(), + EWlanScanCallbackProcessErr ); + CleanupStack::PopAndDestroy( &iapPath ); + return; + } + + CleanupStack::PopAndDestroy( &iapPath ); + neededAction = EIgnoreError; + + TRAPD( err2, PrefIAPNotificationL( availableIAPs, EBearerMan ) ); + if ( err2 == KErrNotFound ) + { + error = err2; + neededAction = EPropagateError; + + TRAP_IGNORE( ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ) + MPMLOGSTRING( + "CMPMServerSession::HandleServerProcessErrorL - \ +Tell BM to end the client connection with appropriate error code" ) + } + else + { + MPMLOGSTRING( + "CMPMServerSession::HandleServerProcessErrorL - \ +Tell BM to ignore error and let MPM notify application about preferred IAP" ) + } + } + } + else + { + neededAction = EPropagateError; + + MPMLOGSTRING( + "CMPMServerSession::HandleServerProcessErrorL - \ +Tell BM to end the client connection with appropriate error code" ) + + } + ProcessErrorComplete( KErrNone, &error, &neededAction ); + + } + else + { + MPMLOGSTRING2( + "CMPMServerSession::HandleServerProcessErrorL Unknown state %d", + state ) + ProcessErrorComplete( KErrCorrupt, + NULL, + NULL ); + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerRegisterPrefIAPNotifL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerRegisterPrefIAPNotifL( + const RMessage2& aMessage ) + { + MPMLOGSTRING( "CMPMServerSession::HandleServerRegisterPrefIAPNotifL" ) + + // Read the Connection Id of the application + // + TConnectionId regId = aMessage.Int0(); + MPMLOGSTRING2( "CMPMServerSession::HandleServerRegisterPrefIAPNotifL \ +- regId = 0x%x", regId ) + + // Get the current connection SNAP for this Connection Id + // + TUint32 regNetId = iMyServer.GetBMSnap( regId ); + + // Get the current connection IapId for this Connection Id + // + TUint32 currentIap = iMyServer.GetBMIap( regId ); + MPMLOGSTRING2( "CMPMServerSession::HandleServerRegisterPrefIAPNotifL \ +- currentIap = %i", currentIap) + + // Check that there is a connection using + // either IAP or SNAP + // + if ( regNetId == 0 && currentIap == 0 ) + { + MPMLOGSTRING( "CMPMServerSession::\ + HandleServerRegisterPrefIAPNotifL - return KErrNotSupported" ) + aMessage.Complete( KErrNotSupported ); + return; + } + + // Append info about registration + iPreferredIAPRequested = ETrue; + + TConnMonIapInfo availableIAPs; + availableIAPs = GetAvailableIAPs(); + + MPMLOGSTRING2( "CMPMServerSession::HandleServerRegisterPrefIAPNotifL \ +- IAPs count: %d", availableIAPs.iCount) + +#ifdef _DEBUG + for (TUint i = 0; i < availableIAPs.Count(); i++) + { + MPMLOGSTRING2( + "CMPMServerSession::HandleServerRegisterPrefIAPNotifL \ +- IAP: %d", availableIAPs.iIap[i].iIapId) + } +#endif // _DEBUG + + // Call now the method that handles notifications for + // checking if notification is already triggered + // If SNAP is 0, don't try sending notifications + // + if ( availableIAPs.iCount > 0 && regNetId ) + { + PrefIAPNotificationL( availableIAPs, EBearerMan ); + } + + // In case the mobility application register to preferred IAP notification + // we have to make sure we get availability every once in a while. + // + RArray iapPath; + CleanupClosePushL( iapPath ); + CleanupStack::PopAndDestroy( &iapPath ); + aMessage.Complete( KErrNone ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerUnregisterPrefIAPNotif +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerUnregisterPrefIAPNotif( + const RMessage2& aMessage ) + { + // Read the Connection Id of the application + // + TConnectionId unregId = aMessage.Int0(); + MPMLOGSTRING2( "CMPMServerSession::HandleServerUnregisterPrefIAPNotif\ + - unregId = 0x%x", unregId ) + + // Currently will remove all registration for this Connection Id. + // If needed change BM-MPM API to support unregistration for certain SNAP + // + iPreferredIAPRequested = EFalse; + iLastNotifiedIap = 0; + // Unblacklist all IAPs related to this connection + // when unregistering from preferred IAP notification. + // + iMyServer.HandleServerUnblackListIap( unregId, 0 ); + + aMessage.Complete( KErrNone ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerWaitNotificationL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerWaitNotificationL( + const RMessage2& aMessage ) + { + MPMLOGSTRING2( "CMPMServerSession::HandleServerWaitNotification - \ +iNotifRequested = %i", iNotifRequested ) + + if ( !iNotifRequested ) + { + // Save message for later completion + // + iNotifMessage = aMessage; + + // Set requested flag + // + iNotifRequested = ETrue; + } + else + { + aMessage.Complete( KErrServerBusy ); + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::HandleServerSortSNAPL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::HandleServerSortSNAPL( const RMessage2& aMessage ) + { + MPMLOGSTRING( "CMPMServerSession::HandleServerSortSNAPL()" ) + if ( !iServerSortSNAPMessage.IsNull() ) + { + MPMLOGSTRING2( + "CMPMServerSession::HandleServerSortSNAPL: Failed with: %d",KErrNotReady ) + + // Error, only one request of each type per session. + aMessage.Complete( KErrNotReady ); + } + + // Store message for later usage. + iServerSortSNAPMessage = aMessage; + + TUint32 aSeconds = static_cast( iServerSortSNAPMessage.Int2() ); + + // To display up to date information the WLAN scan should be done first + iMyServer.Events()->ScanWLANNetworksL( this, + ConnectionId(), + EWlanScanCallbackSortSnap, + aSeconds ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::CompleteServerSortSNAPL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::CompleteServerSortSNAP() + { + if ( iServerSortSNAPMessage.IsNull() ) + { + return; + } + + // Read SNAP + // + TUint32 snapId = static_cast( iServerSortSNAPMessage.Int0() ); + + MPMLOGSTRING2( "CMPMServerSession::CompleteServerSortSNAPL - SNAP = %i", + snapId ) + + TMpmSnapBuffer sortedIapList; + + TRAPD( err, SortSnapL( snapId, sortedIapList ) ) + if ( err != KErrNone ) + { + MPMLOGSTRING2( + "CMPMServerSession::CompleteServerSortSNAPL: Sorting failed with: %d", err ) + iServerSortSNAPMessage.Complete( err ); + return; + } + + // Write results to message + // + TPtrC8 e( reinterpret_cast< TUint8* >( &sortedIapList ), + sizeof( sortedIapList ) ); + TRAP( err, iServerSortSNAPMessage.WriteL( KSecondArgument, e ) ) + if ( err != KErrNone ) + { + MPMLOGSTRING2( + "CMPMServerSession::CompleteServerSortSNAPL: RMessage.WriteL() Failure: %d", err ) + iServerSortSNAPMessage.Complete( err ); + return; + } + + MPMLOGSTRING( + "CMPMServerSession::CompleteServerSortSNAPL: Sorting available uncategorised IAPs completed" ) + iServerSortSNAPMessage.Complete( KErrNone ); + return; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ProcessErrorWlanScanCompletedL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::ProcessErrorWlanScanCompletedL() + { + MPMLOGSTRING( "CMPMServerSession::ProcessErrorWlanScanCompletedL" ) + TBMNeededAction neededAction( EIgnoreError ); + + // Read the Connection Id of the application + // + TConnectionId connId = iProcessErrorMessage.Int1(); + + // Read Error code + // + TInt error( KErrNone); + + TPtr8 errorPtr( reinterpret_cast< TUint8* >( NULL ), 0 ); + errorPtr.Set( reinterpret_cast< TUint8* >( &error ), + sizeof( error ), + sizeof( error ) ); + + // Read the contents of the client pointer into a TPtr8. + // + TInt res = iProcessErrorMessage.Read( KFirstArgument, errorPtr ); + if ( res != KErrNone ) + { + iMyServer.PanicClient( KErrBadDescriptor ); + return; + } + + // Get the current connection IapId for this connId + // + TUint32 currentIap = iMyServer.GetBMIap( connId ); + + // get available iaps + TConnMonIapInfo availableIAPs; + availableIAPs = GetAvailableIAPs(); + + RemoveUnavailableIap( availableIAPs, currentIap ); + + TRAPD( err2, PrefIAPNotificationL( availableIAPs, EBearerMan ) ); + if ( err2 == KErrNotFound ) + { + error = err2; + neededAction = EPropagateError; + + TRAP_IGNORE( ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ) + MPMLOGSTRING( "CMPMServerSession::ProcessErrorWlanScanCompletedL - \ +Tell BM to end the client connection with appropriate error code" ) + } + else + { + MPMLOGSTRING( "CMPMServerSession::ProcessErrorWlanScanCompletedL - \ +Tell BM to ignore error and let MPM notify application about preferred IAP" ) + } + + ProcessErrorComplete( KErrNone, &error, &neededAction ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::SortSnapL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::SortSnapL( const TUint32 aSnapId, + TMpmSnapBuffer& aSortedIaps ) + { + MPMLOGSTRING2( "CMPMServerSession::SortSnapL - SNAP = %i", + aSnapId ) + + TBool hideIap( EFalse ); + + // In case snapId is zero, return the + // list of available uncategorised IAPs + // + if ( aSnapId == KSortUncategorisedIaps ) + { + RAvailableIAPList availableUncatIAPList; + CleanupClosePushL( availableUncatIAPList ); + AvailableUnblacklistedIapsL( availableUncatIAPList, iConnId ); + + iMyServer.CommsDatAccess()->RemoveCategorisedIapsL( availableUncatIAPList ); + + aSortedIaps.Reset(); + + for ( TInt i( 0 ); ( (i < availableUncatIAPList.Count()) ); i++ ) + { + // Check first if metadata EMetaHiddenAgent is enabled. + // + hideIap = iMyServer.CommsDatAccess()->CheckHiddenAgentL( availableUncatIAPList[i] ); + if ( hideIap ) + { + // In that case IAP can't be shown in Connection Dialog. + // + MPMLOGSTRING2( + "CMPMServerSession::SortSnapL: Remove HiddenAgent IAP = %i", + availableUncatIAPList[i] ) + } + else + { + aSortedIaps.iIapId[aSortedIaps.iCount] = availableUncatIAPList[i]; + aSortedIaps.iCount++; + } + } + +#ifdef _DEBUG + // Print info into the log file + // + MPMLOGSTRING( "CMPMServerSession::SortSnapL: Sorted IAPs" ) + for ( TInt p = 0; p < aSortedIaps.Count(); p++ ) + { + MPMLOGSTRING2( + "CMPMServerSession::SortSnapL: IapId = %i", + aSortedIaps.iIapId[p] ) + } +#endif // _DEBUG + + // Release memory + // + CleanupStack::PopAndDestroy( &availableUncatIAPList ); + return; + } + + RArray destNetIaps, embeddedIaps; + CleanupClosePushL( destNetIaps ); + CleanupClosePushL( embeddedIaps ); + + // Find the valid IAPs belonging to the Snap. + // + iMyServer.CommsDatAccess()->SearchDNEntriesWithEmbeddedL( aSnapId, destNetIaps, embeddedIaps ); + + RAvailableIAPList availableIAPList; + CleanupClosePushL( availableIAPList ); + AvailableUnblacklistedIapsL( availableIAPList, iConnId ); + + // Remove any unavailable IAP from destNetIaps + // + TInt ret = KErrNotFound; + TInt destCount = destNetIaps.Count(); + + // Decrement by one, because count is n, + // but indexes in array are 0 .. n-1. + // + destCount--; + + // This time we are browsing the array from the end to the beginning, + // because removing one element from array affects index numbering. + // + for ( TInt k = destCount; k >= 0; k-- ) + { + ret = availableIAPList.Find( destNetIaps[k].iIapId ); + if ( ret == KErrNotFound ) + { + MPMLOGSTRING2( "CMPMServerSession::SortSnapL: \ +Remove unavailable IAP = %i", destNetIaps[k].iIapId ) + destNetIaps.Remove( k ); + } + else + { + // Check first if metadata EMetaHiddenAgent is enabled. + // + hideIap = iMyServer.CommsDatAccess()->CheckHiddenAgentL( destNetIaps[k].iIapId ); + if ( hideIap ) + { + // In that case IAP can't be shown in Connection Dialog. + // + MPMLOGSTRING2( + "CMPMServerSession::SortSnapL: Remove HiddenAgent IAP = %i", + destNetIaps[k].iIapId ) + destNetIaps.Remove( k ); + } + } + } + + // Remove any unavailable IAP from embeddedIaps + // + if ( embeddedIaps.Count() > 0 ) + { + TInt embedCount = embeddedIaps.Count(); + embedCount--; + + for ( TInt m = embedCount; m >= 0; m-- ) + { + ret = availableIAPList.Find( embeddedIaps[m].iIapId ); + if ( ret == KErrNotFound ) + { + MPMLOGSTRING2( "CMPMServerSession::SortSnapL: \ +Remove unavailable IAP = %i", embeddedIaps[m].iIapId ) + embeddedIaps.Remove( m ); + } + else + { + // Check first if metadata EMetaHiddenAgent is enabled. + // + hideIap = iMyServer.CommsDatAccess()->CheckHiddenAgentL( embeddedIaps[m].iIapId ); + if ( hideIap ) + { + // In that case IAP can't be shown in Connection Dialog. + // + MPMLOGSTRING2( + "CMPMServerSession::SortSnapL: Remove HiddenAgent IAP = %i", + embeddedIaps[m].iIapId ) + embeddedIaps.Remove( m ); + } + } + } + } + + // Determine the actual priorities for virtual IAPs and embedded Snaps + // + iMyServer.CommsDatAccess()->DeterminePrioritiesL( destNetIaps, availableIAPList, + *this ); + if ( embeddedIaps.Count() > 0 ) + { + iMyServer.CommsDatAccess()->DeterminePrioritiesL( embeddedIaps, + availableIAPList, + *this ); + } + + aSortedIaps.Reset(); + + // Start sorting destNetIaps and embeddedIaps. + // + for( TInt p = 0; ( destNetIaps.Count() > 0 ) || + ( embeddedIaps.Count() > 0 ); p++ ) + { + // Go through the destNetIaps-array and check the global bearer + // priority for both destNetIaps and embeddedIaps until the best + // available IAP is found. + // + TUint32 destNetPriority( KLowestPriority ); + TUint32 embeddedPriority( KLowestPriority ); + + if( destNetIaps.Count() > 0 ) + { + iMyServer.CommsDatAccess()->GlobalBearerPriorityL( destNetIaps[0].iIapId, + destNetPriority ); + } + + if( embeddedIaps.Count() > 0 ) + { + iMyServer.CommsDatAccess()->GlobalBearerPriorityL( embeddedIaps[0].iIapId, + embeddedPriority ); + } + + // Compare the global bearer priorities of the first IAPs and + // select the better. + // + // If the priorities are equal, prioritize the Snap + // over the embedded Snap. + // + // When comparing the priorities, smaller value is better. + // + // Finally, append IapId to sortedList. + // + if( destNetPriority <= embeddedPriority ) + { + if( destNetIaps.Count() > 0 ) + { + aSortedIaps.iIapId[p] = destNetIaps[0].iIapId; + aSortedIaps.iCount++; + MPMLOGSTRING2( + "CMPMServerSession::SortSnapL: IapId = %i", + destNetIaps[0].iIapId ) + MPMLOGSTRING2( + "CMPMServerSession::SortSnapL: Snap = %i", + destNetIaps[0].iSnap ) + destNetIaps.Remove( 0 ); + } + } + else + { + if( embeddedIaps.Count() > 0 ) + { + aSortedIaps.iIapId[p] = embeddedIaps[0].iIapId; + aSortedIaps.iCount++; + MPMLOGSTRING2( + "CMPMServerSession::SortSnapL: IapId = %i", + embeddedIaps[0].iIapId ) + MPMLOGSTRING2( + "CMPMServerSession::SortSnapL: Snap = %i", + embeddedIaps[0].iSnap ) + embeddedIaps.Remove( 0 ); + } + } + } + + // Release memory + // + CleanupStack::PopAndDestroy( &availableIAPList ); + CleanupStack::PopAndDestroy( &embeddedIaps ); + CleanupStack::PopAndDestroy( &destNetIaps ); + +#ifdef _DEBUG + // Print info into the log file + // + MPMLOGSTRING( "CMPMServerSession::SortSnapL: Sorted IAPs" ) + for ( TInt n = 0; n < aSortedIaps.Count(); n++ ) + { + MPMLOGSTRING2( + "CMPMServerSession::SortSnapL: IapId = %i", + aSortedIaps.iIapId[n] ) + } +#endif // _DEBUG + + MPMLOGSTRING( + "CMPMServerSession::SortSnapL: Sorting completed" ) + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::UpdateConnectionDialog +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::UpdateConnectionDialogL() + { + if( iIapSelection ) + { + iIapSelection->UpdateConnectionDialogL(); + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::CompleteCarrierRejected +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::CompleteCarrierRejected() + { + TInt error( KErrNotFound ); + + MPMLOGSTRING( "CMPMServerSession::CompleteCarrierRejected" ) + + TConnMonIapInfo availableIAPs; + availableIAPs = GetAvailableIAPs(); + + if ( availableIAPs.iCount > 0 ) + { + TRAP( error, PrefIAPNotificationL( availableIAPs, EBearerMan ) ); + if ( error == KErrNotFound ) + { + TRAP( error, ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ); + } + } + else + { + MPMLOGSTRING( + "CMPMServerSession::CompleteCarrierRejected - \ +No IAPs available, send error notification" ) + TRAP( error, ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ); + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ExtractConnPref +// ----------------------------------------------------------------------------- +// +TInt CMPMServerSession::ExtractConnPref( + const TConnPref& aBasePref, + TMpmConnPref& aMpmConnPref ) const + { + TInt error( KErrNone ); + + // Extract connection preferences from TConnPref to TMpmConnPref + // based on the type of the connection preferences. + // + switch ( aBasePref.ExtensionId() ) + { + case TConnPref::EConnPrefCommDb: // TCommDbConnPref + { + MPMLOGSTRING( + "CMPMServerSession::ExtractConnPref - EConnPrefCommDb" ) + error = ExtractConnPrefCommDb( aBasePref, aMpmConnPref ); + break; + } + case TConnPref::EConnPrefCommDbMulti: // TCommDbMultiConnPref + { + MPMLOGSTRING( + "CMPMServerSession::ExtractConnPref - EConnPrefCommDbMulti" ) + error = ExtractConnPrefCommDbMulti( aBasePref, aMpmConnPref ); + break; + } + case TConnPref::EConnPrefSnap: // TConnSnapPref + { + MPMLOGSTRING( + "CMPMServerSession::ExtractConnPref - EConnPrefSnap" ) + error = ExtractConnPrefSnap( aBasePref, aMpmConnPref ); + break; + } + case TMpmConnPref::EConnPrefMpm: // TMpmConnPref + { + MPMLOGSTRING( + "CMPMServerSession::ExtractConnPref - EConnPrefMpm" ) + error = ExtractConnPrefMpm( aBasePref, aMpmConnPref ); + break; + } + case TConnPref::EConnPrefUnknown: // Default connection + { + MPMLOGSTRING( "CMPMServerSession::ExtractConnPref - \ +EConnPrefUnknown overriding to default conn" ) + break; + } + default: + { + MPMLOGSTRING( "CMPMServerSession::ExtractConnPref - \ +Unrecognised connection preference type" ) + error = KErrArgument; + } + } + + ResolveConnType( aMpmConnPref ); + + MPMLOGSTRING2( "CMPMServerSession::ExtractConnPref - \ +Error code in the end: %d", error ) + return error; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ExtractConnPrefCommDb +// ----------------------------------------------------------------------------- +// +TInt CMPMServerSession::ExtractConnPrefCommDb( + const TConnPref& aBasePref, + TMpmConnPref& aMpmConnPref ) const + { + ASSERT( aBasePref.ExtensionId() == TConnPref::EConnPrefCommDb ); + TInt error( KErrNone ); + + // Cast down to a TCommDbConnPref + TCommDbConnPref commDbPref; + commDbPref = TCommDbConnPref::Cast( aBasePref ); + + // This is an old sanity check which is not complete but we cannot + // expand it to keep backwards compatibility. + if ( commDbPref.IapId() == 0 && commDbPref.NetId() != 0 && + commDbPref.DialogPreference() != ECommDbDialogPrefPrompt ) + { + error = KErrArgument; + } + else + { + // Map dialog preference. Only request for connection selection + // dialog is needed as other values either match the default values of TMpmConnPref + // or are ignored (ECommDbDialogPrefWarn and + // ECommDbDialogPrefPromptIfWrongMode). + if ( commDbPref.DialogPreference() == ECommDbDialogPrefPrompt ) + { + aMpmConnPref.SetConnSelectionDialog( ETrue ); + } + else + { + // Map IAP id. + aMpmConnPref.SetIapId( commDbPref.IapId() ); + } + + // commDbPref.NetId() is ignored as it's retrieved by MPM based on + // final selection. + // commDbPref.Direction() is ignored as it's not used in MPM. + + // Transfer bearerset from aCommDbPref to aMpmConnPref + // in case 'prompt from user' or 'explicit SNAP requested'. + // If only IAP is given, bearer set is ignored and not set. + // If bearer set is set for IAP connection here, implementation of + // "WLAN Only" setting feature will prevent cellular IAP connection + // from happening + if ( commDbPref.DialogPreference() != ECommDbDialogPrefUnknown && + ( commDbPref.IapId() == 0 || + commDbPref.DialogPreference() == ECommDbDialogPrefPrompt ) ) + { + if ( commDbPref.BearerSet() & ECommDbBearerWLAN ) + { + aMpmConnPref.SetBearerSet( aMpmConnPref.BearerSet() | + TExtendedConnPref::EExtendedConnBearerWLAN ); + } + + if ( commDbPref.BearerSet() & ECommDbBearerWcdma || + commDbPref.BearerSet() & DeprecatedCDMA2000 ) + { + aMpmConnPref.SetBearerSet( aMpmConnPref.BearerSet() | + TExtendedConnPref::EExtendedConnBearerCellular ); + } + } + } + + return error; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ExtractConnPrefCommDbMulti +// ----------------------------------------------------------------------------- +// +TInt CMPMServerSession::ExtractConnPrefCommDbMulti( + const TConnPref& aBasePref, + TMpmConnPref& aMpmConnPref ) const + { + ASSERT( aBasePref.ExtensionId() == TConnPref::EConnPrefCommDbMulti ); + TInt error( KErrNone ); + + // Cast down to a TCommDbMultiConnPref + TCommDbMultiConnPref multiPrefs; + multiPrefs = TCommDbMultiConnPref::Cast( aBasePref ); + + // Try to retrieve the connection preference for the first attempt + TCommDbConnPref commDbPref; + error = multiPrefs.GetPreference( 1, commDbPref ); + + if ( error == KErrNone ) + { + error = ExtractConnPrefCommDb( commDbPref, aMpmConnPref ); + } + + return error; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ExtractConnPrefSnap +// ----------------------------------------------------------------------------- +// +TInt CMPMServerSession::ExtractConnPrefSnap( + const TConnPref& aBasePref, + TMpmConnPref& aMpmConnPref ) const + { + ASSERT( aBasePref.ExtensionId() == TConnPref::EConnPrefSnap ); + + // Cast down to a TConnSnapPref + TConnSnapPref snapPref; + snapPref = *reinterpret_cast( + const_cast( &aBasePref ) ); + + // Check whether old net id, new snap id, or zero is given. + // If snap id equals to zero, doing nothing here implies default + // connection is used. We cannot give error in this case because it has + // worked as default connection request earlier. + TInt snapid(0); + TInt error( KErrNone ); + if ( snapPref.Snap() > 0 && + snapPref.Snap() <= 0x100 ) + { + // Old Destination network id passed. Convert to SNAP id. + TRAP( error, + snapid = iMyServer.CommsDatAccess()->MapNetIdtoSnapAPL( + snapPref.Snap() ) ); + } + else if ( snapPref.Snap() != 0 ) + { + // Snap id passed. + snapid = snapPref.Snap(); + } + + aMpmConnPref.SetSnapId( snapid ); + + return error; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ExtractConnPrefMpm +// ----------------------------------------------------------------------------- +// +TInt CMPMServerSession::ExtractConnPrefMpm( + const TConnPref& aBasePref, + TMpmConnPref& aMpmConnPref ) const + { + ASSERT( aBasePref.ExtensionId() == TMpmConnPref::EConnPrefMpm ); + TInt error( KErrNone ); + + aMpmConnPref = *reinterpret_cast( + const_cast( &aBasePref ) ); + + // Validate connection preferences and if they are valid, resolve needed + // information into more practical format for MPM. + error = ValidateExtendedConnPref( aMpmConnPref ); + if ( error == KErrNone ) + { + // Find the SNAP id based on SNAP purpose. + CMManager::TSnapPurpose aSnapPurpose = aMpmConnPref.SnapPurpose(); + TInt error = KErrNone; + + // MPM searches SnapId for requested purpose by going through all + // destinations in CommsDat. + if ( aSnapPurpose != CMManager::ESnapPurposeUnknown ) + { + TUint32 snapId(0); + TRAP( error, snapId = iMyServer.CommsDatAccess()->DestinationIdL( + aSnapPurpose ) ); + if ( error == KErrNone ) + { + aMpmConnPref.SetSnapId( snapId ); + } + } + + // Mark IAP as mandated if IAP id is given. + if ( aMpmConnPref.IapId() != 0 ) + { + aMpmConnPref.SetMandateIap( ETrue ); + } + } + + return error; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ValidateExtendedConnPref +// +// Makes a sanity check to the custom preferences and return KErrArgument +// if there are illegal combinations in the connection preferences +// ----------------------------------------------------------------------------- +// +TInt CMPMServerSession::ValidateExtendedConnPref( + TMpmConnPref& aMpmConnPref ) const + { + // If iap id is set, neither snap nor bearer set can be defined + if ( aMpmConnPref.IapId() != 0 ) + { + if ( ( aMpmConnPref.SnapId() != 0 ) || + ( aMpmConnPref.BearerSet() != + TExtendedConnPref::EExtendedConnBearerUnknown ) ) + { + return KErrArgument; + } + } + + // If snap purpose is set, then neither iap nor snap id should be defined + if ( aMpmConnPref.SnapPurpose() != CMManager::ESnapPurposeUnknown ) + { + if ( ( aMpmConnPref.IapId() != 0 ) || + ( aMpmConnPref.SnapId() != 0 ) ) + { + return KErrArgument; + } + } + + // If selection dialog is enabled, Snap id, iap id and snap purpose + // should not be set + if ( aMpmConnPref.ConnSelectionDialog() ) + { + if ( ( aMpmConnPref.SnapId() != 0 ) || + ( aMpmConnPref.IapId() != 0 ) || + ( aMpmConnPref.SnapPurpose() != CMManager::ESnapPurposeUnknown ) ) + { + return KErrArgument; + } + } + + // Check that the given enumerations are within the enumeration ranges + if ( ( aMpmConnPref.SnapPurpose() < CMManager::ESnapPurposeUnknown ) || + ( aMpmConnPref.SnapPurpose() > CMManager::ESnapPurposeIntranet ) || + ( aMpmConnPref.NoteBehaviour() > + TExtendedConnPref::ENoteBehaviourConnSilent ) || + ( aMpmConnPref.BearerSet() > + ( TExtendedConnPref::EExtendedConnBearerCellular + + TExtendedConnPref::EExtendedConnBearerWLAN ) ) ) + { + return KErrArgument; + } + + // Check that one of SNAP purpose, SNAP id, IAP id or Connection selection + // dialog is given + if ( ( aMpmConnPref.SnapPurpose() == CMManager::ESnapPurposeUnknown ) && + ( aMpmConnPref.SnapId() == 0 ) && + ( aMpmConnPref.IapId() == 0 ) && + ( aMpmConnPref.ConnSelectionDialog() == EFalse ) ) + { + return KErrArgument; + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ResolveConnType +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::ResolveConnType( TMpmConnPref& aMpmConnPref ) const + { + // Define the connection type based on the connection preferences. + if ( aMpmConnPref.ConnSelectionDialog() ) + { + // Connection selection dialog was requested. + aMpmConnPref.SetConnType( TMpmConnPref::EConnTypeImplicit ); + } + else if ( aMpmConnPref.IapId() != 0 || + aMpmConnPref.SnapId() != 0 || + aMpmConnPref.SnapPurpose() != CMManager::ESnapPurposeUnknown ) + { + // Either IAP id, SNAP id or SNAP purpose was given. + aMpmConnPref.SetConnType( TMpmConnPref::EConnTypeExplicit ); + } + else + { + // Otherwise this is handled as a request to default connection. + aMpmConnPref.SetConnType( TMpmConnPref::EConnTypeDefault ); + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::IapSelectionL +// ----------------------------------------------------------------------------- +// +CMPMIapSelection* CMPMServerSession::IapSelectionL() + { + if( !iIapSelection ) + { + MPMLOGSTRING( "CMPMServerSession::IapSelectionL error, no connection started" ) + User::Leave( KErrNotFound ); + } + return iIapSelection; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::PrefIAPNotificationL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::PrefIAPNotificationL( + const TConnMonIapInfo& aIapInfo, + const TPrefIAPNotifCaller aCaller ) + { + MPMLOGSTRING( "CMPMServerSession::PrefIAPNotificationL" ) + + if ( !iNotifRequested || !iPreferredIAPRequested ) + { + MPMLOGSTRING( "CMPMServerSession::PrefIAPNotificationL - \ +No notification requested" ) + return; + } + + // Dig out the state of this connection. + // + TConnectionState state; + iMyServer.GetConnectionState( iConnId, state ); + + // If session is roaming, notification must be delayed. + // But, only ConnMon initiated notifications need to be delayed. + // Required notifications must go through whenever MPM decides + // to initiate them. + // + if( ( iStoredIapInfo.HoldPrefIapNotif() && aCaller == EConnMon) || + ( state == ERoaming && aCaller == EConnMon ) ) + { + MPMLOGSTRING( "CMPMServerSession::PrefIAPNotificationL - \ +Mobility ongoing, notification will be handled later" ) + iStoredIapInfo.SetStoredIapInfo( aIapInfo ); + return; + } + + TInt err(0); + TInt currentIap = MyServer().GetBMIap( iConnId ); + MPMLOGSTRING4( "CMPMServerSession::PrefIAPNotificationL - \ +current iap %d, last notified %d, err %d ", currentIap, iLastNotifiedIap, err ) + if( err != KErrNone ) + { + MPMLOGSTRING( "CMPMServerSession::PrefIAPNotificationL: Connection is not \ +registered for notifications" ) + return; + } + + TBool iapTypeLanOrWlan( EFalse ); + RAvailableIAPList availableIAPList; + CleanupClosePushL( availableIAPList ); + TUint32 validateIapId( 0 ); + TUint32 oldIapId( 0 ); + + TMpmNotificationPrefIAPAvailable notifInfo; + notifInfo.iMPMNotificationType = EMPMPreferredIAPAvailable; + + AvailableUnblacklistedIapsL( availableIAPList, aIapInfo, iConnId); + oldIapId = currentIap; + + // If connection is using SNAP + // + TUint32 snap = iMyServer.GetBMSnap( iConnId ); + if( snap != 0 ) + { + TMpmConnPref tempMpmConnPref; + tempMpmConnPref.SetIapId( 0 ); + tempMpmConnPref.SetSnapId( snap ); + IapSelectionL()->ChooseBestIAPL( tempMpmConnPref, availableIAPList ); + validateIapId = tempMpmConnPref.IapId(); + if ( ( validateIapId == 0 ) && ( aCaller == EConnMon ) ) + { + // Since Connection Monitor is the only component which + // is unaware of Connection Id and SNAP, it can't send + // the error notification in case ChooseBestIAPL could + // not find any available IAP for this SNAP. + // + // All the other components take responsibility of + // sending the error notification. + // + TRAP_IGNORE( ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ) + } + + TUint32 retNetId = 0; + iMyServer.CommsDatAccess()->ValidateIapL( iConnId, + validateIapId, + retNetId, + iapTypeLanOrWlan, + *this ); + + if ( CheckNotifNeed( currentIap, + iLastNotifiedIap, + validateIapId ) ) + { + MPMLOGSTRING2( "CMPMServerSession::PrefIAPNotificationL: \ +Sending pref iap notification connId: 0x%x", iConnId ) + + iLastNotifiedIap = validateIapId; + + notifInfo.iIsUpgrade = IsUpgrade( oldIapId, + validateIapId, + availableIAPList ); + + // Put real value of iIsSeamless here for NLR. + // + notifInfo.iIsSeamless = EFalse; + notifInfo.iConnId = iConnId; + + MPMLOGSTRING3( "CMPMServerSession::PrefIAPNotificationL: \ +Roaming from Iap %i to Iap %i", oldIapId, validateIapId ) + + notifInfo.iNewIapId = validateIapId; + notifInfo.iOldIapId = oldIapId; + + if ( aCaller != EConfirmDlgRoaming ) + { + delete iConfirmDlgRoaming; + iConfirmDlgRoaming = NULL; + } + + // Write buffer to BM + // + TPtrC8 d( reinterpret_cast< TUint8* >( ¬ifInfo ), + notifInfo.Length() ); + iNotifMessage.WriteL( KFirstArgument, d ); + + // Reset flag + // + iNotifRequested = EFalse; + + // Hold the preferred IAP already during the preferred IAP notification. + // In Freeway new PreferredCarrier can only be processed after the + // response for the previous one is received. + // + iStoredIapInfo.SetHoldPrefIapNotif(); + + // Now complete WaitNotification to BM + // + MPMLOGSTRING( "CMPMServerSession::PrefIAPNotificationL - \ +Send preferred IAP notification" ) + iNotifMessage.Complete( KErrNone ); + } + } + // Connection is using IAP + // In this case only check if the current IAP is found + // in available IAP list. + // If it's not, then notify error. + // + else + { + err = availableIAPList.Find( oldIapId ); + if( err == KErrNotFound ) + { + MPMLOGSTRING2( "CMPMServerSession::PrefIAPNotificationL: \ +SNAP 0 and IAP %d not available, notifying error", oldIapId ) + TRAP_IGNORE( ErrorNotificationL( KErrNotFound, + EMPMMobilityErrorNotification ) ) + } + } + + // Release memory + // + CleanupStack::PopAndDestroy( &availableIAPList ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::StartIAPNotificationL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::StartIAPNotificationL( const TUint32 aIapId ) + { + MPMLOGSTRING3( "CMPMServerSession::StartIAPNotificationL: aConnId = 0x%x,\ + aIapId = %i", iConnId, aIapId ) + + iStoredIapInfo.SetHoldPrefIapNotif(); + + if ( !iNotifRequested ) + { + MPMLOGSTRING( "CMPMServerSession::StartIAPNotificationL - \ +No notification requested" ) + return; + } + + TMpmNotificationStartIAP notifInfo; + notifInfo.iMPMNotificationType = EMPMStartIAPNotification; + notifInfo.iInfo.iIap = aIapId; + notifInfo.iInfo.iConnId = iConnId; + notifInfo.iInfo.iServiceId = GetServiceIdSettingL(); + + // Write buffer to BM + // + TPtrC8 d(reinterpret_cast< TUint8* >( ¬ifInfo ), + notifInfo.Length() ); + iNotifMessage.WriteL( KFirstArgument, d ); + + // Reset flag + // + iNotifRequested = EFalse; + + // Now complete WaitNotification to BM + // + MPMLOGSTRING( "CMPMServerSession::StartIAPNotificationL - \ +Send start IAP notification" ) + iNotifMessage.Complete( KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::StopIAPNotificationL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::StopIAPNotificationL( TInt aIapId ) + { + MPMLOGSTRING2( "CMPMServerSession::StopIAPNotificationL: aConnId = 0x%x", iConnId) + + if ( !iNotifRequested ) + { + MPMLOGSTRING( "CMPMServerSession::StopIAPNotificationL - \ +No notification requested" ) + return; + } + + TMpmNotificationStopIAP notifInfo; + notifInfo.iMPMNotificationType = EMPMStopIAPNotification; + notifInfo.iInfo.iConnId = iConnId; + notifInfo.iInfo.iIap = aIapId; + + // Write buffer to BM + // + TPtrC8 d(reinterpret_cast< TUint8* >( ¬ifInfo ), + notifInfo.Length() ); + iNotifMessage.WriteL( KFirstArgument, d ); + + // Reset flag + // + iNotifRequested = EFalse; + + // Now complete WaitNotification to BM + // + MPMLOGSTRING( "CMPMServerSession::StopIAPNotificationL - \ +Send stop IAP notification" ) + iNotifMessage.Complete( KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ErrorMobilityNotificationL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::MobilityErrorNotificationL( TInt aError ) + { + MPMLOGSTRING2( + "CMPMServerSession::MobilityErrorNotificationL: aError = %i ", + aError ) + + ErrorNotificationL( aError, EMPMMobilityErrorNotification ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ErrorClientNotificationL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::ClientErrorNotificationL( TInt aError ) + { + MPMLOGSTRING2( + "CMPMServerSession::ClientErrorNotificationL: aError = %i ", + aError ) + + ErrorNotificationL( aError, EMPMClientErrorNotification ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ErrorNotificationL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::ErrorNotificationL( TInt aError, + TMpmNotifications aNotificationType ) + { + MPMLOGSTRING3( + "CMPMServerSession::ErrorNotificationL: aError = %i, aNotificationType = %i", + aError, aNotificationType ) + + if ( !iNotifRequested ) + { + MPMLOGSTRING( "CMPMServerSession::ErrorNotificationL - \ +No notification requested" ) + return; + } + + TMpmNotificationError errorNotif; + + errorNotif.iMPMNotificationType = aNotificationType; + errorNotif.iError = aError; + errorNotif.iConnId = iConnId; + + // Write buffer to BM + TPtrC8 d(reinterpret_cast< TUint8* >( &errorNotif ), + errorNotif.Length() ); + iNotifMessage.WriteL( KFirstArgument, d ); + + // Reset flag + iNotifRequested = EFalse; + + // Now complete error notification to BM + MPMLOGSTRING("CMPMServerSession::ErrorNotificationL - Send error notification" ) + iNotifMessage.Complete( KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::IsPhoneOfflineL +// +// Checks if phone is in offline mode or not. +// Return ETrue if phone is in offline mode. +// Return EFalse if phone is not in offline mode. +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::IsPhoneOfflineL() const + { + MPMLOGSTRING( "CMPMServerSession::IsPhoneOfflineL" ) + if ( iOfflineFeatureSupported ) + { + CRepository* repository = CRepository::NewLC(KCRUidCoreApplicationUIs); + TInt connAllowed = ECoreAppUIsNetworkConnectionAllowed; + repository->Get( KCoreAppUIsNetworkConnectionAllowed, connAllowed ); + CleanupStack::PopAndDestroy( repository ); + if ( !connAllowed ) + { + MPMLOGSTRING( + "CMPMServerSession::IsPhoneOfflineL Phone is in offline mode" ) + return ETrue; + } + } + MPMLOGSTRING( + "CMPMServerSession::IsPhoneOfflineL Phone is not in offline mode" ) + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::AvailableUnblacklistedIapsL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::AvailableUnblacklistedIapsL( + RAvailableIAPList& aAvailableIAPs, + const TConnectionId aConnId ) + { + MPMLOGSTRING( "CMPMServerSession::AvailableUnblacklistedIapsL" ) + + TConnMonIapInfo availableIAPList; + availableIAPList = GetAvailableIAPs(); + + AvailableUnblacklistedIapsL( aAvailableIAPs, + availableIAPList, + aConnId ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::AvailableUnblacklistedIapsL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::AvailableUnblacklistedIapsL( + RAvailableIAPList& aAvailableIAPs, + const TConnMonIapInfo& aIapInfo, + const TConnectionId aConnId ) + { + RArray blacklistiaps; + CleanupClosePushL( blacklistiaps ); + TWlanSsid ssid; + TUint32 iapId( 0 ); + + aAvailableIAPs.Reset(); + + for (TUint i = 0; i < aIapInfo.iCount; i++) + { + aAvailableIAPs.AppendL( aIapInfo.iIap[i].iIapId ); + } + + // Get list of blacklisted IAPs. + // + iMyServer.GetBlacklistedIAP( aConnId, blacklistiaps ); + + // If there is an active WLAN connection + // + if ( iMyServer.Events()->ActiveWlanConnection( ssid, iapId ) ) + { + RAvailableIAPList unavailableIAPs; + CleanupClosePushL( unavailableIAPs ); + TRAP_IGNORE( UnavailableIAPsL( aAvailableIAPs, + unavailableIAPs ) ) + + TBool activeAvailable( ETrue ); + if (unavailableIAPs.Find(iapId) != KErrNotFound) + { + MPMLOGSTRING( "CMPMServerSession::AvailableUnblacklistedIapsL: Active IAP unavailable" ) + activeAvailable = EFalse; + } + + // If the active WLAN connection is blacklisted, then + // there is no need to check if any of the unavailable + // WLAN IAPs have same SSID as active WLAN connection. + // + // Same goes for unavailable active connection. + // + if ( activeAvailable && + blacklistiaps.Find( iapId ) == KErrNotFound ) + { + for ( TInt i( 0 ); ( (i < unavailableIAPs.Count()) ); i++ ) + { + // Check if any of the unavailable WLAN IAPs have + // the same SSID as the active WLAN connection. + // + TBool usesSame( EFalse ); + + if ( !iMyServer.CommsDatAccess()->CheckEasyWLanL( unavailableIAPs[i] ) ) + { + TRAP_IGNORE( iMyServer.CommsDatAccess()->MatchSSIDL( ssid, + unavailableIAPs[i], + usesSame, + *this ) ) + + if ( usesSame ) + { + // Append unavailable IAP to list of available IAPs + // if it uses same SSID as active WLAN connection. + // + MPMLOGSTRING2( + "CMPMServerSession::AvailableUnblacklistedIapsL:\ + Append unavailable IapId = %i", unavailableIAPs[i] ) + aAvailableIAPs.AppendL( unavailableIAPs[i] ); + } + } + } + } + CleanupStack::PopAndDestroy( &unavailableIAPs ); + } + + TInt index( KErrNotFound ); + + // Remove any blacklisted IAP. + // + for (TInt i = 0; i < blacklistiaps.Count(); i++) + { + index = aAvailableIAPs.Find( blacklistiaps[i] ); + if (( index != KErrNotFound ) && ( index < aAvailableIAPs.Count() )) + { + MPMLOGSTRING2( "CMPMServerSession::AvailableUnblacklistedIapsL: \ +Remove blacklisted IapId = %i", aAvailableIAPs[index] ) + aAvailableIAPs.Remove( index ); + } + } + CleanupStack::PopAndDestroy( &blacklistiaps ); + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::IsUpgrade +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::IsUpgrade( + const TUint32 aIapId, + const TUint32 aMigrateIapId, + const RAvailableIAPList& aAvailableIAPs ) const + { + if ( aIapId == aMigrateIapId ) + { + // If the current Iap Id and migrate Iap Id are identical, + // then it is considered that this a downgrade. + // + MPMLOGSTRING( "CMPMServerSession::IsUpgrade - Downgrade" ) + return EFalse; + } + + if ( aAvailableIAPs.Find( aIapId ) == KErrNotFound ) + { + // If the registered Iap Id is not found in the list of + // available IAPs, then it is considered that the new + // validated IAP is a downgrade compared to previous. + // + MPMLOGSTRING( "CMPMServerSession::IsUpgrade - Downgrade" ) + return EFalse; + } + else + { + // If the registered Iap Id is found in the list of + // available IAPs, then it is considered that the new + // validated IAP is an upgrade compared to previous. + // + MPMLOGSTRING( "CMPMServerSession::IsUpgrade - Upgrade" ) + return ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::CheckNotifNeed +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::CheckNotifNeed( const TUint32 aCurrentIap, + const TUint32 aLastNotifiedIap, + const TUint32 aValidatedIap ) + { + TBool retValue( EFalse ); + + // Get the state of the connection for this Connection Id + // + TConnectionState state; + iMyServer.GetConnectionState( iConnId, + state ); + // New IAP to be notified is different from last + if ( aValidatedIap != aLastNotifiedIap ) + { + if( aCurrentIap == aValidatedIap) + { + MPMLOGSTRING( "CMPMServerSession::CheckNotifNeed: current IAP is same preferred IAP, no need to send notification" ) + retValue = EFalse; + } + else + { + MPMLOGSTRING( "CMPMServerSession::CheckNotifNeed: notif needed" ) + retValue = ETrue; + } + } + else + { + MPMLOGSTRING( "CMPMServerSession::CheckNotifNeed: Last notified IAP is same as preferred IAP, no need to send notification" ) + } + return retValue; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::UnavailableIAPsL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::UnavailableIAPsL( + const RAvailableIAPList aAvailableIAPs, + RAvailableIAPList& aUnavailableIAPs ) + { + TInt err( KErrNone ); + + CCommsDatabase* commsDatabase = CCommsDatabase::NewL(); + CleanupStack::PushL(commsDatabase); + + // Make hidden records visible + // + commsDatabase->ShowHiddenRecords(); + + // Iterate the IAP table from CommsDat + CCommsDbTableView* table = NULL; + table = commsDatabase->OpenTableLC( TPtrC( IAP ) ); + + err = table->GotoFirstRecord(); + + while ( !err ) + { + TUint32 iapId( 0 ); + + // Read IAP's ID + // + table->ReadUintL( TPtrC( COMMDB_ID ), iapId ); + + if ( aAvailableIAPs.Find( iapId ) == KErrNotFound ) + { + aUnavailableIAPs.AppendL( iapId ); + } + + err = table->GotoNextRecord(); + } + + // Release memory + // + CleanupStack::PopAndDestroy( table ); + CleanupStack::PopAndDestroy( commsDatabase ); + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::RemoveUnavailableIap +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::RemoveUnavailableIap( TConnMonIapInfo& aIapInfo, + const TUint32 aIapId ) + { + TConnMonIapInfo iapInfo = aIapInfo; + TBool found( EFalse ); + + for ( TUint i( 0 );( ( i < iapInfo.Count() ) && !found ); i++ ) + { + if ( iapInfo.iIap[i].iIapId == aIapId ) + { + found = ETrue; + + MPMLOGSTRING2( "CMPMServerSession::RemoveUnavailableIap - IAP: %d", + iapInfo.iIap[i].iIapId ) + + // Since iapInfo.Remove( i ) is not supported + // + TUint k( 0 ); + for ( k = i; ( ( k + 1 ) < iapInfo.Count() ); k++ ) + { + iapInfo.iIap[k] = iapInfo.iIap[k+1]; + } + iapInfo.iIap[k].iIapId = 0; + iapInfo.iCount--; + } + } + + aIapInfo = iapInfo; + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::IsBackgroundApplication +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::IsBackgroundApplication( TUint32 aUid ) const + { + if( aUid == KUidSimApplicationToolkit || + aUid == KUidDVBH || + aUid == KUidAlwaysOnlineStarter) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ChooseIapComplete +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::ChooseIapComplete( + TInt aError, + const TMpmConnPref* aPolicyPref ) + { + MPMLOGSTRING2( "CMPMServerSession::ChooseIapComplete aError = %d", aError ) + + // Show error popup if it's allowed per client request + if ( !( iIapSelection->MpmConnPref().NoteBehaviour() & + TExtendedConnPref::ENoteBehaviourConnDisableNotes ) + && ( aError != KErrNone ) ) + { + CConnectionUiUtilities* connUiUtils = CConnectionUiUtilities::NewL(); + // Note: Below function shows the discreet popup only if the error code + // belongs to the set of errors that are shown to the user. + // Otherwise the popup is not shown. + connUiUtils->ConnectionErrorDiscreetPopup( aError ); + delete connUiUtils; + connUiUtils = NULL; + } + + // Try to write back arguments and complete message. + // + if ( !iChooseIapMessage.IsNull() ) + { + if ( aError == KErrNone && aPolicyPref ) + { + MPMLOGSTRING4( "CMPMServerSession::ChooseIapComplete \ +IAP Id = %d, SNAP Id = %d, Net Id = %d", + aPolicyPref->IapId(), + aPolicyPref->SnapId(), + aPolicyPref->NetId() ) + + TPolicyConnPref pref; + pref.SetIapId( aPolicyPref->IapId() ); + pref.SetNetId( aPolicyPref->NetId() ); + TInt serviceid(0); + + // Resolve the original serviceid for the application. + // + TRAPD( err, serviceid = GetServiceIdSettingL() ) + if ( err != KErrNone ) + { + MPMLOGSTRING2( "CMPMServerSession::ChooseIapComplete GetServiceIdSettingL Leaved %d", err ) + pref.SetServiceId( 0 ); + } + else + { + pref.SetServiceId( serviceid ); + } + MPMLOGSTRING4( "CMPMServerSession::ChooseIapComplete writing policy pref \ +iap %d net id %d service id %d", pref.IapId(), pref.NetId(), pref.ServiceId() ) + switch ( iChooseIapMessage.Function() ) + { + case EMPMServerChooseIap: + { + TRAP( aError, iChooseIapMessage.WriteL( KFourthArgument, pref ) ) + break; + } + case EMPMServerReselectIap: + { + TRAP( aError, iChooseIapMessage.WriteL( KSecondArgument, pref ) ) + break; + } + default: + { + MPMLOGSTRING2( "CMPMServerSession::ChooseIapComplete - Error \ +Inconsistent state %d", KErrGeneral ) + aError = KErrGeneral; + } + } + } + MPMLOGSTRING( "CMPMServerSession::ChooseIapComplete Message completed" ) + iChooseIapMessage.Complete( aError ); + } + } + + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ProcessErrorComplete +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::ProcessErrorComplete( TInt aError, + TInt* aErrorReturned, + TBMNeededAction* aNeededAction ) + { + MPMLOGSTRING2( "CMPMServerSession::ProcessErrorComplete aError = %d", aError ) + + delete iDisconnectDlg; + iDisconnectDlg = NULL; + + if ( !iProcessErrorMessage.IsNull() ) + { + // Try to write back arguments and complete message. + // Traps are not necesary here. If WriteL functions leave the + // message is still completed in ServiceError + // + if( aErrorReturned ) + { + MPMLOGSTRING2( "CMPMServerSession::ProcessErrorComplete returned error = %d", + *aErrorReturned ) + + TPtrC8 d( reinterpret_cast< TUint8* >( aErrorReturned ), + sizeof( aErrorReturned ) ); + TRAP_IGNORE( iProcessErrorMessage.WriteL( KFirstArgument, d ) ) + } + if( aNeededAction ) + { + MPMLOGSTRING2( "CMPMServerSession::ProcessErrorComplete needed action = %d", + *aNeededAction ) + TPtrC8 c( reinterpret_cast< TUint8* >( aNeededAction ), + sizeof( aNeededAction ) ); + TRAP_IGNORE( iProcessErrorMessage.WriteL( KThirdArgument, c ) ) + } + MPMLOGSTRING( "CMPMServerSession::ProcessErrorComplete completing message" ) + iProcessErrorMessage.Complete( aError ); + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::DisconnectDlgErrorCode +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::DisconnectDlgErrorCode( TInt aError ) const + { + if ( aError == KErrGprsInsufficientResources || // -4154 + aError == KErrPacketDataTsyMaxPdpContextsReached || // -6000 + aError == KErrUmtsMaxNumOfContextExceededByNetwork || // -4179 + aError == KErrUmtsMaxNumOfContextExceededByPhone ) // -4178 + { + MPMLOGSTRING2( "CMPMServerSession::DisconnectDlgErrorCode - \ +Error %d, is disconnect dlg error code", aError ) + return ETrue; + } + else + { + MPMLOGSTRING2( "CMPMServerSession::DisconnectDlgErrorCode - \ +Error %d, is not disconnect dlg error code", aError ) + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::GetPresumedIap +// ----------------------------------------------------------------------------- +// +TUint32 CMPMServerSession::GetPresumedIap() + { + TUint32 presumedIap( 0 ), realIap = iMyServer.GetBMIap( iConnId ); + if( realIap != 0 ) + { + presumedIap = iMyServer.Events()->PresumedIapId( iConnId, realIap ); + } + MPMLOGSTRING3( "CMPMServerSession::GetPresumedIap - \ +Real IAP %d, presumed Iap %d", realIap, presumedIap ) + return presumedIap; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::MigrateDoneL +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::MigrateDoneL( TInt aError ) + { + MPMLOGSTRING3( "CMPMServerSession<0x%x>::MigrateCompleteL: error %d", + iConnId, + aError ) + + if( aError == KErrNone ) + { + // Send a notification to BearerMan + // to start the Iap + // + TRAP_IGNORE( StartIAPNotificationL( iMigrateIap ) ) + } + iMigrateState = EMigrateNone; + iMigrateIap = 0; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::UseUserConnPref +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::UseUserConnPref() + { + if ((iAppUid != iMyServer.CsIdWatcher()->ConnectScreenId()) && + iMyServer.UserConnection()) + { + MPMLOGSTRING( "CMPMServerSession::UseUserConnPref - User connection active" ); + + // Check whether default connection will be used + if ( iIapSelection->MpmConnPref().ConnType() == TMpmConnPref::EConnTypeDefault ) + { + return ETrue; + } + else if ( ( iIapSelection->MpmConnPref().ConnType() == + TMpmConnPref::EConnTypeImplicit ) && + PrefsAllowWlan() ) + { + MPMLOGSTRING( "CMPMServerSession::UseUserConnPref -\ + Prompt from the user" ); + // Prompt from the user -> use user connection + return ETrue; + } + else + { + MPMLOGSTRING( "CMPMServerSession::UseUserConnPref -\ + Application preferencies" ); + TBool isInternetSnap = EFalse; + TInt error = KErrNone; + + // Check whether iap belongs to internet snap + TRAP( error, isInternetSnap = + iMyServer.CommsDatAccess()->IsInternetSnapL( + iIapSelection->MpmConnPref().IapId(), + iIapSelection->MpmConnPref().SnapId() ) ); + + if ( ( error == KErrNone ) && ( isInternetSnap ) && PrefsAllowWlan() ) + { + // Iap belongs to internet snap -> use user connection + return ETrue; + } + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::IsWlanOnlyL +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::IsWlanOnlyL( TBool& aNewWlansAllowed ) + { + TCmGenConnSettings genConnSettings; + + MPMLOGSTRING( "CMPMServerSession::IsWlanOnlyL") + + // Read global OCC seamlessness values from CommsDat's DefConn table + genConnSettings = iMyServer.CommsDatAccess()->ReadGenConnSettingsL(); + + // Find out if new wlans can be prompted + if ( genConnSettings.iUsageOfWlan == ECmUsageOfWlanKnownAndNew ) + { + aNewWlansAllowed = ETrue; + MPMLOGSTRING( "CMPMServerSession::IsWlanOnlyL: aNewWlansAllowed: True" ) + } + else + { + aNewWlansAllowed = EFalse; + MPMLOGSTRING( "CMPMServerSession::IsWlanOnlyL: aNewWlansAllowed: False" ) + } + + // Find out is only WLAN connection is allowed in current network + TUint32 currentSeamlessness( genConnSettings.iSeamlessnessHome ); + + if ( iMyServer.IsVisitorNetwork() ) + { + currentSeamlessness = genConnSettings.iSeamlessnessVisitor; + } + + if ( currentSeamlessness == ECmSeamlessnessDisabled ) + { + MPMLOGSTRING( "CMPMServerSession::IsWlanOnlyL: True" ) + return ETrue; + } + else + { + MPMLOGSTRING( "CMPMServerSession::IsWlanOnlyL: False" ) + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::ForcedRoaming() +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::ForcedRoaming() + { + TBool forcedRoaming( EFalse ); + if ( iIapSelection != NULL ) + { + forcedRoaming = iIapSelection->MpmConnPref().ForcedRoaming(); + } + return forcedRoaming; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::RemoveIapsAccordingToBearerSetL() +// ----------------------------------------------------------------------------- +// +void CMPMServerSession::RemoveIapsAccordingToBearerSetL( TConnMonIapInfo& aIapInfo ) + { + if (!iIapSelection) + { + // Iap selection hasn't done for this session -> just return + return; + } + + // Drop iaps not according to bearer set + if ( iIapSelection->MpmConnPref().BearerSet() != + TExtendedConnPref::EExtendedConnBearerUnknown ) + { + TInt index = 0; + + while ( index != aIapInfo.iCount ) + { + // Get bearer type + TMPMBearerType bearerType = EMPMBearerTypeOther; + bearerType = + iMyServer.CommsDatAccess()->GetBearerTypeL ( aIapInfo.iIap[index].iIapId ); + + if ( (( bearerType == EMPMBearerTypePacketData ) && + ( iIapSelection->MpmConnPref().BearerSet() & + TExtendedConnPref::EExtendedConnBearerCellular )) ) + { + // Don't remove this iap + index++; + continue; + } + else if ( (( bearerType == EMPMBearerTypeWlan ) && + ( iIapSelection->MpmConnPref().BearerSet() & + TExtendedConnPref::EExtendedConnBearerWLAN )) ) + { + // Don't remove this iap + index++; + continue; + } + else + { + // Remove this iap from the list + for ( TInt index2 = index; index2 < aIapInfo.iCount; index2++ ) + { + aIapInfo.iIap[index2].iIapId = aIapInfo.iIap[index2 + 1].iIapId; + } + + aIapInfo.iCount--; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::GetAvailableIAPs() +// ----------------------------------------------------------------------------- +// +TConnMonIapInfo CMPMServerSession::GetAvailableIAPs() + { + TConnMonIapInfo availableIAPs; + + availableIAPs = MyServer().Events()->GetAvailableIAPs(); + + // Remove iaps not according to bearer set + TRAP_IGNORE ( RemoveIapsAccordingToBearerSetL ( availableIAPs ) ); + + return availableIAPs; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::IsBearerAccepted() +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::IsBearerAccepted( TMPMBearerType aBearerType ) + { + TBool returnValue = EFalse; + + if ( !iIapSelection || + ( iIapSelection->MpmConnPref().BearerSet() == + TExtendedConnPref::EExtendedConnBearerUnknown ) ) + { + // Iap selection hasn't been done for this session or all bearers + // are accepted -> just return true + returnValue = ETrue; + } + else + { + switch ( aBearerType ) + { + case EMPMBearerTypeWlan: + if ( iIapSelection->MpmConnPref().BearerSet() & + TExtendedConnPref::EExtendedConnBearerWLAN ) + { + returnValue = ETrue; + } + break; + + case EMPMBearerTypePacketData: + if ( iIapSelection->MpmConnPref().BearerSet() & + TExtendedConnPref::EExtendedConnBearerCellular ) + { + returnValue = ETrue; + } + break; + + default: + break; + } + } + + return returnValue; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::IsMMSIap() +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::IsMMSIap( TUint32 aIap ) + { + // Check if IAP is reported by MMS + // + TBool isMMSIap = EFalse; + if( aIap != 0 ) + { + // get property if it's defined + TInt err( KErrNone ); + TInt mmsIap( 0 ); + err = RProperty::Get( KMPMCathegory, KMPMPropertyKeyMMS, mmsIap); + + // If successful compare IAPs + if( err == KErrNone ) + { + if( aIap == mmsIap ) + { + isMMSIap = ETrue; + } + } + } + MPMLOGSTRING2( "CMPMServerSession::IsMmsIap: Returning bool value: %d", + isMMSIap ) + return isMMSIap; + } + +// ----------------------------------------------------------------------------- +// CMPMServerSession::PrefsAllowWlan +// ----------------------------------------------------------------------------- +// +TBool CMPMServerSession::PrefsAllowWlan() + { + // WLAN connection can be used if application has not specified any bearerset + // or when bearerset has WLAN enabled. + // + if ( ( iIapSelection->MpmConnPref().BearerSet() == + TExtendedConnPref::EExtendedConnBearerUnknown ) + || + ( iIapSelection->MpmConnPref().BearerSet() & + TExtendedConnPref::EExtendedConnBearerWLAN ) ) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// TNetIap::TNetIap +// ----------------------------------------------------------------------------- +// +TNetIap::TNetIap() + : iSnap( 0 ), + iEmbeddedSnap( 0 ), + iIapId( 0 ), + iRanking( 0 ), + iGlobalPriority( 0 ) + { + } + + +// ----------------------------------------------------------------------------- +// TNetIap::CompareRanking +// ----------------------------------------------------------------------------- +// +TInt TNetIap::CompareRanking( const TNetIap& aFirst, + const TNetIap& aSecond ) + { + if ( aFirst.iRanking < aSecond.iRanking ) + { + return KSmaller; + } + else if ( aFirst.iRanking > aSecond.iRanking ) + { + return KBigger; + } + else + { + return KEqual; + } + } + +// ----------------------------------------------------------------------------- +// TNetIap::CompareGlobalAndLocalPriority +// ----------------------------------------------------------------------------- +// +TInt TNetIap::CompareGlobalAndLocalPriority( const TNetIap& aFirst, + const TNetIap& aSecond ) + { + if ( aFirst.iGlobalPriority < aSecond.iGlobalPriority ) + { + return KSmaller; + } + else if ( aFirst.iGlobalPriority > aSecond.iGlobalPriority ) + { + return KBigger; + } + else + { + // If global priorities are equal, + // order based on ranking + // + return TNetIap::CompareRanking( aFirst, aSecond ); + } + } +// ----------------------------------------------------------------------------- +// TStoredIapInfo::TStoredIapInfo +// ----------------------------------------------------------------------------- +// +TStoredIapInfo::TStoredIapInfo() + : iHoldPrefIapNotif( EFalse ), + iIapInfoWaiting( EFalse ), + iStoredIapInfo() + { + } + +// ----------------------------------------------------------------------------- +// TStoredIapInfo::HoldPrefIapNotif +// ----------------------------------------------------------------------------- +// +TBool TStoredIapInfo::HoldPrefIapNotif() const + { + MPMLOGSTRING2( "TStoredIapInfo::HoldPrefIapNotif value %d", iHoldPrefIapNotif ) + return iHoldPrefIapNotif; + } + +// ----------------------------------------------------------------------------- +// TStoredIapInfo::SetHoldPrefIapNotif +// ----------------------------------------------------------------------------- +// +void TStoredIapInfo::SetHoldPrefIapNotif() + { + MPMLOGSTRING( "TStoredIapInfo::SetHoldPrefIapNotif" ) + iHoldPrefIapNotif = ETrue; + } + +// ----------------------------------------------------------------------------- +// TStoredIapInfo::HandleIapInfoWaiting +// ----------------------------------------------------------------------------- +// +TBool TStoredIapInfo::HandleIapInfoWaiting( TConnMonIapInfo& aStoredIapInfo ) + { + if( iIapInfoWaiting ) + { + iHoldPrefIapNotif = EFalse; + aStoredIapInfo = iStoredIapInfo; + } + MPMLOGSTRING2( "TStoredIapInfo::HandleIapInfoWaiting value %d", iIapInfoWaiting ) + return iIapInfoWaiting; + } + +// ----------------------------------------------------------------------------- +// TStoredIapInfo::SetStoredIapInfo +// ----------------------------------------------------------------------------- +// +void TStoredIapInfo::SetStoredIapInfo( const TConnMonIapInfo& aStoredIapInfo ) + { + MPMLOGSTRING( "TStoredIapInfo::SetStoredIapInfo" ) + iIapInfoWaiting = ETrue; + iStoredIapInfo = aStoredIapInfo; + } + +// ----------------------------------------------------------------------------- +// TStoredIapInfo::ResetStoredIapInfo +// ----------------------------------------------------------------------------- +// +void TStoredIapInfo::ResetStoredIapInfo() + { + MPMLOGSTRING( "TStoredIapInfo::ResetStoredIapInfo" ) + iHoldPrefIapNotif = EFalse; + iIapInfoWaiting = EFalse; + } + + +// End of File