diff -r 000000000000 -r 094583676ce7 wvuing/IMPSConnectionUI/OperationStepSrc/CCnUiAALoginCntrlStep.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvuing/IMPSConnectionUI/OperationStepSrc/CCnUiAALoginCntrlStep.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,445 @@ +/* +* Copyright (c) 2004 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: AA login control. +* +*/ + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CCnUiAALoginCntrlStep.h" +#include "CCnUiConnOpener.h" +#include "CCnUiConnCloser.h" + +#include "MCnUiBaseControlContext.h" +#include "MCnUiConnectionHandler.h" +#include "MCnUiSignaller.h" +#include "MCnUiGlobalNotificationUiFacade.h" + +#include "CnUiErrors.h" + +#include "CnUiClientId.h" + + +// ================= MEMBER FUNCTIONS ======================= +// Two-phased constructor. +CCnUiAALoginCntrlStep* CCnUiAALoginCntrlStep::NewLC( MCnUiBaseControlContext& aCCntxt, + CIMPSSAPSettings& aLoginSap, + TBool aShowDetailedError, + CPEngNWSessionSlotID2& aNWSessionSlotID ) + { + CCnUiAALoginCntrlStep* self = new ( ELeave ) CCnUiAALoginCntrlStep( aCCntxt, aLoginSap, + aShowDetailedError, aNWSessionSlotID ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +// Destructor +CCnUiAALoginCntrlStep::~CCnUiAALoginCntrlStep() + { + delete iConnOpener; + delete iConnCloser; + delete iLogoutPlugin; + } + + +// C++ default constructor can NOT contain any code, that +// might leave. +// +CCnUiAALoginCntrlStep::CCnUiAALoginCntrlStep( MCnUiBaseControlContext& aCCntxt, + CIMPSSAPSettings& aLoginSap, + TBool aShowDetailedError, + CPEngNWSessionSlotID2& aNWSessionSlotID ) + : iCCntxt( aCCntxt ), + iLoginSap( aLoginSap ), + iShowDetailedError( aShowDetailedError ), + iNWSessionSlotID( aNWSessionSlotID ) + { + } + + +// Symbian OS default constructor can leave. +void CCnUiAALoginCntrlStep::ConstructL() + { + iConnOpener = CCnUiConnOpener::NewL(); + iConnCloser = CCnUiConnCloser::NewL(); + } + + +// ----------------------------------------------------------------------------- +// CCnUiAALoginCntrlStep::RunStepL() +// ----------------------------------------------------------------------------- +// +TInt CCnUiAALoginCntrlStep::RunStepL() + { + TInt mappedError = KErrNone; + TInt errorDetail = KErrNone; + + switch ( DoRunStepL() ) + { + case KErrNone: // Login succeeded + { + //this is returned as is + mappedError = KErrNone; + break; + } + + case KCnUiErrorClientAlreadyConnected: + { + //Current client is already logged in. (Thus not a real error.) + mappedError = KErrAlreadyExists; + break; + } + + + case KErrAccessDenied: + case KCnUiErrorNetworkConnectionNotAllowed: // //network access denied + { + mappedError = KErrAccessDenied; + errorDetail = R_QTN_CHAT_LOGIN_CONERROR_NOTE; + break; + } + + + case KCnUiErrorSapMissingCompulsoryFields: + case KCnUiErrorNoProperDefaultSap: + { + //Missing the whole default SAP + //or it was missing some required fields. + mappedError = KErrNotFound; + errorDetail = R_QTN_CHAT_SETT_COMP_MISS; + break; + } + + + case KPEngNwErrInvalidPassword: + case KPEngNwErrUnknownUser: + case KPEngNwErrInvalidOrUnSupportedUserProperties: + case KPEngNwErrUnauthorized: + { + //wrong username / password + //free first plug-in dynamic resources + TIMPSConnectionClient clientId = iCCntxt.ControlledClient(); + iCCntxt.ClientPluginL( clientId, iNWSessionSlotID ).ReleaseDynamicResources(); + + iCCntxt.GlobalNotificationUiL().ShowLoginUserDataErrorL( iLoginSap.SAPName() ); + mappedError = KErrArgument; + break; + } + + case KCnUiErrorAlreadyConnectedToAnotherSap: + { + // user declined disconnect from manually logged in sap + mappedError = KErrCouldNotDisconnect; + break; + } + + case KPEngNwErrForbidden:// 403 + { + errorDetail = R_QTN_CHAT_LOGIN_ACCOUNT_LOST; + mappedError = KErrAccessDenied; + break; + } + + //flow through + case KPEngNwErrServiceNotSupported: // 405 + case KPEngNwErrServiceNotAgreed: // 506 + { + mappedError = KErrNotSupported; + errorDetail = R_QTN_CHAT_ERROR_SERVICE_ERR; + break; + } + + // flow through + case KPEngNwErrServiceUnavailable: // 503 + case KPEngNwErrMessageQueueIsFull: // 507 + { + mappedError = KErrCouldNotConnect; + errorDetail = R_QTN_CHAT_ERROR_SERV_BUSY; + break; + } + + case KPEngNwErrVersionNotSupported: // 505 + { + mappedError = KErrGeneral; + errorDetail = R_QTN_CHAT_ERROR_GEN_ERROR; + break; + } + + // flow through + case KPEngNwErrSessionExpired: // 600 + case KErrTimedOut: + case KErrCouldNotConnect: + case KImpsErrorBearerSuspended: + { + mappedError = KErrCouldNotConnect; + errorDetail = R_QTN_CHAT_LOGIN_CONERROR_NOTE; + break; + } + + default: + { + //General failure during login (no connection to network, etc..) + mappedError = KErrGeneral; + errorDetail = R_QTN_CHAT_LOGIN_CONERROR_NOTE; + break; + } + } + + // if there was some other error than login data error, we must + // show a detailed error note if aa plugin requested so + if ( ( mappedError != KErrNone ) && ( mappedError != KErrArgument ) && ( iShowDetailedError ) ) + { + //free first plug-in dynamic resources + TIMPSConnectionClient clientId = iCCntxt.ControlledClient(); + iCCntxt.ClientPluginL( clientId, iNWSessionSlotID ).ReleaseDynamicResources(); + + iCCntxt.GlobalNotificationUiL().ShowLoginDetailedErrorL( iLoginSap.SAPName(), errorDetail ); + } + + return mappedError; + } + + +// ----------------------------------------------------------------------------- +// CCnUiAALoginCntrlStep::DoRunStepL() +// ----------------------------------------------------------------------------- +// +TInt CCnUiAALoginCntrlStep::DoRunStepL() + { + TIMPSConnectionClient clientId = iCCntxt.ControlledClient(); + + //First make sure that there isn't already another login + //operation running (if there is, then no need to select SAP...) + if ( iCCntxt.Signaller().OperationRunning() ) + { + return KCnUiErrorLoginOperationAlreadyInUse; + } + + // Check if client is already logged to DEFAULT server + CIMPSSAPSettings* defaultSap = CIMPSSAPSettings::NewLC(); + LoadDefaultSapL( *defaultSap ); + TCnUiSapCnStatus status = iCCntxt.ConnHandler().SapConnectionStatusL( *defaultSap, clientId ); + CleanupStack::PopAndDestroy( defaultSap ); + + if ( status == ECnUiSCS_SapConnected ) + { + // connected to the same server. otherwise logout + // + // or different server) + return KCnUiErrorClientAlreadyConnected; + } + + //load SAP & handle its errors + TInt loadStatus = LoadDefaultSapL( iLoginSap ); + if ( loadStatus != KErrNone ) + { + iLoginSap.Reset(); + return loadStatus; + } + + //Signal to other clients that login operation is started. + if ( iCCntxt.Signaller().SignalOperationL( iLoginSap.SAPName() ) == KErrInUse ) + { + //some other client has started the login during SAP load... + return KCnUiErrorLoginOperationAlreadyInUse; + } + + if ( iLoginSap.ClientId().Length() == 0 ) + { + iLoginSap.SetClientIdL( KClientId() ); + } + + + // set the network session slot ID + iNWSessionSlotID.SetServiceAddressL( iLoginSap.SAPAddress() ); + iNWSessionSlotID.SetUserIdL( iLoginSap.SAPUserId() ); + + if ( clientId == EIMPSConnClientIM ) + { + iNWSessionSlotID.SetAppIdL( KPEngAppIdIM() ); + } + else + { + iNWSessionSlotID.SetAppIdL( KPEngAppIdPEC() ); + } + + // create a network session slot to PEC engine + CPEngNWSessionSlotManager2* slotManager = CPEngNWSessionSlotManager2::NewLC(); + + TInt err = slotManager->CreateNWSessionSlot( iNWSessionSlotID ); + // we can ignore KErrAlreadyExist, since if the error is that + // we can just start using the slot + if ( ( err != KErrNone ) && ( err != KErrAlreadyExists ) ) + { + User::Leave( err ); + } + CleanupStack::PopAndDestroy( slotManager ); + //ok to try login + TInt loginTrieStatus = iConnOpener->MakeLoginForClient( + clientId, + iLoginSap, + iCCntxt.ClientPluginL( clientId, iNWSessionSlotID ), + iCCntxt.ConnHandler(), + NULL, + iNWSessionSlotID ); + + + if ( loginTrieStatus == KCnUiErrorAlreadyConnectedToAnotherSap ) + { + // we are already connected to another sap, so we need to logout first + + // create global notification ui facade for sending channel message + MCnUiGlobalNotificationUiFacade* uiFacade = &( iCCntxt.GlobalNotificationUiL() ); + + RArray loggedInClients; + CleanupClosePushL( loggedInClients ); + iCCntxt.ConnHandler().GetLoggedInClientsL( loggedInClients ); + + // ask a confirmation from the user + if ( uiFacade->CGQActiveConnectionSuppressForScheduledConnectionL( + iLoginSap.SAPName(), + loggedInClients.Array() ) ) + { + loginTrieStatus = KErrNone; + + // user accepted logout of query timed out -> do the logout + CIMPSSAPSettings* logoutSap = CIMPSSAPSettings::NewLC(); + //get SAP from where logging out.. + iCCntxt.ConnHandler().GetLoggedInSapL( *logoutSap, clientId ); + + CPEngNWSessionSlotID2* logoutID = NULL; + logoutID = iCCntxt.GetActiveNWSessionSlotIDL( clientId ); + CleanupStack::PushL( logoutID ); + TInt logoutStatus( KErrNone ); + + delete iLogoutPlugin; + iLogoutPlugin = NULL; + iLogoutPlugin = CreateClientPluginL( clientId, *logoutID ); + + for ( TInt index = 0; index < loggedInClients.Count(); index++ ) + { + //close the client connection using the connection closer + logoutStatus = iConnCloser->MakeLogoutForClient( loggedInClients.Array()[ index ], + *logoutSap, + *iLogoutPlugin, + iCCntxt.ConnHandler(), + NULL, + *logoutID ); + if ( logoutStatus != KErrNone ) + { + // logout did not succeed, exit the loop + loginTrieStatus = logoutStatus; + break; + } + } + + if ( loginTrieStatus == KErrNone ) + { + // logout(s) successful -> do the login + loginTrieStatus = iConnOpener->MakeLoginForClient( clientId, + iLoginSap, + iCCntxt.ClientPluginL( clientId, iNWSessionSlotID ), + iCCntxt.ConnHandler(), + NULL, + iNWSessionSlotID ); + } + delete iLogoutPlugin; + iLogoutPlugin = NULL; + CleanupStack::PopAndDestroy( logoutID ); + CleanupStack::PopAndDestroy( logoutSap ); + } + CleanupStack::PopAndDestroy(); // loggedInClients + } + + return loginTrieStatus; + } + + + +// ----------------------------------------------------------------------------- +// CCnUiAALoginCntrlStep::HandleCompleteL() +// ----------------------------------------------------------------------------- +// +TCnUiHandleCompleteStatus CCnUiAALoginCntrlStep::HandleCompleteL() + { + iCCntxt.Signaller().CancelOperationSignal(); + return ECnUiStepContinueTeardown; + } + + +// ----------------------------------------------------------------------------- +// CCnUiAALoginCntrlStep::HandleCompleteL() +// ----------------------------------------------------------------------------- +// +void CCnUiAALoginCntrlStep::UndoStepL() + { + iCCntxt.Signaller().CancelOperationSignal(); + } + + +// ----------------------------------------------------------------------------- +// CCnUiAALoginCntrlStep::LoadDefaultSapL() +// ----------------------------------------------------------------------------- +// +TInt CCnUiAALoginCntrlStep::LoadDefaultSapL( CIMPSSAPSettings& aSap ) + { + CIMPSSAPSettingsStore& sapStore = iCCntxt.SapStoreL(); + + TIMPSConnectionClient client( ConnectionClient() ); + TIMPSAccessGroup accessGroup; + if ( client == EIMPSConnClientIM ) + { + accessGroup = EIMPSIMAccessGroup; + } + else + { + accessGroup = EIMPSPECAccessGroup; + } + + + //SAP store might not have any SAP => get default leaves + TRAPD( err, sapStore.GetDefaultL( &aSap, accessGroup ) ); + if ( err == KErrNotFound ) + { + //handle not found error by returning it + return KCnUiErrorNoProperDefaultSap; + } + + //and others by leaving + User::LeaveIfError( err ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CCnUiAALoginCntrlStep::DoShowLogoutOkNoteL() +// ----------------------------------------------------------------------------- +// +TIMPSConnectionClient CCnUiAALoginCntrlStep::ConnectionClient() + { + // rvct does not support casting from TAny* to enumeration value + TInt returnValue = ( TInt )Dll::Tls(); + return ( TIMPSConnectionClient )returnValue; + } +// End of File