wvuing/IMPSConnectionUI/ServiceSrc/CCnUiConnectionHandler.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wvuing/IMPSConnectionUI/ServiceSrc/CCnUiConnectionHandler.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,607 @@
+/*
+* 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:  Connection handler implementation.
+*
+*/
+
+// INCLUDE FILES
+#include "CCnUiConnectionHandler.h"
+#include "CCnUiSapStoreProxy.h"
+
+#include "MCnUiClientStatusHandler.h"
+#include "CnUiErrors.h"
+#include "IMPSCommonUiDebugPrint.h"
+
+#include <e32std.h>
+
+#include <CIMPSSAPSettings.h>
+#include <CIMPSSAPSettingsStore.h>
+#include <CPEngNWSessionSlot2.h>
+#include <CPEngNWSessionSlotID2.h>
+#include <CPEngNWSessionSlotManager2.h>
+
+
+
+/**
+ * WV protocol prefix.
+ */
+_LIT( KWVIdPrefix, "wv:" );
+
+
+/**
+ * Domain separator @.
+ */
+_LIT( KDomainSeparatorAt, "@" );
+
+/**
+ * Length of WV protocol prefix.
+ */
+const TInt KWVIdPrefixLength = 3;
+
+
+// ================= GLOBAL FUNCTIONS ====================
+// -----------------------------------------------------------------------------
+// CreateConnHandlerL()
+// -----------------------------------------------------------------------------
+//
+GLREF_C MCnUiConnectionHandler* CreateConnHandlerL( CCnUiSapStoreProxy& aSapProxy )
+    {
+    return CCnUiConnectionHandler::NewL( aSapProxy );
+    }
+
+
+// ================= LOCAL FUNCTIONS ====================
+
+// -----------------------------------------------------------------------------
+// StripWVSchemaPrefix()
+// -----------------------------------------------------------------------------
+//
+LOCAL_D TPtrC StripWVSchemaPrefix( const TDesC& aFullPresenceId )
+    {
+    TPtrC prefix( aFullPresenceId.Left( KWVIdPrefixLength ) );
+    if ( prefix.CompareF( KWVIdPrefix ) == 0 )
+        {
+        //has prefix
+        return aFullPresenceId.Mid( KWVIdPrefixLength );
+        }
+    return aFullPresenceId;
+    }
+
+
+// -----------------------------------------------------------------------------
+// StripDomainPart()
+// -----------------------------------------------------------------------------
+//
+LOCAL_D TPtrC StripDomainPart( const TDesC& aFullPresenceId )
+    {
+    TInt domainStartPos = aFullPresenceId.Find( KDomainSeparatorAt );
+    if ( domainStartPos == KErrNotFound )
+        {
+        return aFullPresenceId;
+        }
+    return aFullPresenceId.Left( domainStartPos );
+    }
+
+
+
+// ================= MEMBER FUNCTIONS =======================
+// Two-phased constructor.
+CCnUiConnectionHandler* CCnUiConnectionHandler::NewL( CCnUiSapStoreProxy& aSapProxy )
+    {
+    CCnUiConnectionHandler* self = new ( ELeave ) CCnUiConnectionHandler( aSapProxy );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// Destructor
+CCnUiConnectionHandler::~CCnUiConnectionHandler()
+    {
+    if ( iNWSessionSlotID )
+        {
+        CancelSapConnectionOpen( *iNWSessionSlotID );
+        CancelSapConnectionClose( *iNWSessionSlotID );
+        delete iNWSessionSlotID;
+        }
+
+    delete iClientStatusHandler;
+    delete iNWSessionSlot;
+    }
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CCnUiConnectionHandler::CCnUiConnectionHandler( CCnUiSapStoreProxy& aSapProxy )
+        : iSapProxy( aSapProxy )
+    {
+    }
+
+
+// Symbian OS default constructor can leave.
+void CCnUiConnectionHandler::ConstructL()
+    {
+    iClientStatusHandler = CreateClientStatusHandlerLC();
+    CleanupStack::Pop(); //iClientStatusHandler
+
+
+    CPEngNWSessionSlotID2* slotID = CPEngNWSessionSlotID2::NewLC();
+    slotID->SetServiceAddressMatchAnyL();
+    slotID->SetUserIdMatchAnyL();
+    slotID->SetAppIdL( KPEngAppIdIM() );
+
+    //Clear logged in flags if there doesn't exist a connection
+    if ( !( NwConnectionActiveL( *slotID ) ) )
+        {
+        iClientStatusHandler->SetClientLoggedOutL( EIMPSConnClientIM );
+        }
+
+    CleanupStack::PopAndDestroy( slotID );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::OpenSapConnectionL()
+//
+// -----------------------------------------------------------------------------
+//
+void CCnUiConnectionHandler::OpenSapConnectionL(
+    const CIMPSSAPSettings& aSapToLogin,
+    CPEngNWSessionSlotID2& aNWSessionSlotID,
+    MPEngNWSessionOperationObserver2& aSlotOperationObserver )
+    {
+    if ( !NwConnectionActiveL( aNWSessionSlotID ) )
+        {
+        //initially there isn't any logged in clients
+        TIMPSConnectionClient client;
+        if ( 0 == aNWSessionSlotID.AppId().Compare( KPEngAppIdPEC() ) )
+            {
+            client = EIMPSConnClientPEC;
+            }
+        else
+            {
+            client = EIMPSConnClientIM;
+            }
+        iClientStatusHandler->SetClientLoggedOutL( client );
+        }
+
+
+    CPEngNWSessionSlot2* sessionSlot = CPEngNWSessionSlot2::NewL( aNWSessionSlotID );
+    delete iNWSessionSlot;
+    iNWSessionSlot = sessionSlot;
+
+    TInt err ( iNWSessionSlot->OpenNWPresenceSession( aSapToLogin,
+                                                      aSlotOperationObserver ) );
+
+    if ( err == KErrInUse )
+        {
+        // this error suggests, that we have a session open already going on from
+        // this same object. This should not happen, but if it does we can ignore it
+        // since we are already doing what we should start doing here
+        err = KErrNone;
+        }
+
+    //handle connection manager errors
+    if ( err == KErrAccessDenied )
+        {
+        //network operations not allowed due offline profile
+        User::Leave( KCnUiErrorNetworkConnectionNotAllowed );
+        }
+    User::LeaveIfError( err );
+
+    delete iNWSessionSlotID;
+    iNWSessionSlotID = NULL;
+    iNWSessionSlotID = aNWSessionSlotID.CloneL();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::CancelSapConnectionOpen()
+// -----------------------------------------------------------------------------
+//
+void CCnUiConnectionHandler::CancelSapConnectionOpen( CPEngNWSessionSlotID2& /* aNWSessionSlotID */ )
+    {
+    if ( iNWSessionSlot )
+        {
+        iNWSessionSlot->CancelOpenNWPresenceSession();
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::CloseSapConnectionL()
+// -----------------------------------------------------------------------------
+//
+void CCnUiConnectionHandler::CloseSapConnectionL(
+    CPEngNWSessionSlotID2& aNWSessionSlotID,
+    MPEngNWSessionOperationObserver2& aSlotOperationObserver )
+    {
+    // if we already have the same slot id as in the parameter, we are in sync
+    // and slot is also good. in that case we must NOT delete the slot id - if we
+    // do, then PEC Engine CSP session gets closed and OpenNWPresenceSessionOwnership
+    // will leave with -18.
+    CPEngNWSessionSlotID2* tempSlot = aNWSessionSlotID.CloneL();
+    delete iNWSessionSlotID;
+    iNWSessionSlotID = tempSlot;
+
+    CPEngNWSessionSlotID2* bSlot = NULL;
+    if ( !iNWSessionSlot )
+        {
+        CPEngNWSessionSlot2* sessionSlot = CPEngNWSessionSlot2::NewL( *iNWSessionSlotID );
+        delete iNWSessionSlot;
+        iNWSessionSlot = sessionSlot;
+        }
+    else
+        {
+        bSlot = CPEngNWSessionSlotID2::NewLC();
+        iNWSessionSlot->GetNWSessionSlotID( *bSlot );
+        if ( aNWSessionSlotID.MatchBasePart( *bSlot ) != KErrNone )
+            {
+            CPEngNWSessionSlot2* sessionSlot = CPEngNWSessionSlot2::NewL( *iNWSessionSlotID );
+            delete iNWSessionSlot;
+            iNWSessionSlot = sessionSlot;
+            }
+        CleanupStack::PopAndDestroy( bSlot );
+        }
+
+    TInt err( KErrNone );
+
+    err = iNWSessionSlot->OpenNWPresenceSessionOwnership();
+
+    // we can ignore KErrAlreadyExists
+    if ( err != KErrNone && err != KErrAlreadyExists )
+        {
+        User::Leave( err );
+        }
+
+    err = iNWSessionSlot->ForceCloseNWPresenceSession( aSlotOperationObserver );
+
+    if ( err == KErrInUse )
+        {
+        // this error suggests, that we have a session close already going on from
+        // this same object. This should not happen, but if it does we can ignore it
+        // since we are already doing what we should start doing here
+        err = KErrNone;
+        }
+    User::LeaveIfError( err );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::CancelSapConnectionClose()
+// -----------------------------------------------------------------------------
+//
+void CCnUiConnectionHandler::CancelSapConnectionClose( CPEngNWSessionSlotID2& aNWSessionSlotID )
+    {
+    CPEngNWSessionSlot2* slot = NULL;
+    // we can ignore the error, since if we don't find the slot
+    // there's not really much else we can do here
+    TInt ignore;
+    TRAP( ignore, slot = NetworkSessionSlotForIDL( aNWSessionSlotID ) );
+    if ( slot )
+        {
+        slot->CancelCloseNWPresenceSession();
+        delete slot;
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::LoginTheClientL()
+// Client login handler
+// -----------------------------------------------------------------------------
+//
+void CCnUiConnectionHandler::LoginTheClientL( TIMPSConnectionClient aClient )
+    {
+    if ( iClientStatusHandler )
+        {
+        iClientStatusHandler->SetClientLoggedInL( aClient );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::LogoutTheClientL()
+// Client login handler
+// -----------------------------------------------------------------------------
+//
+void CCnUiConnectionHandler::LogoutTheClientL( TIMPSConnectionClient aClient )
+    {
+    //remove client from among the logged in ones
+    iClientStatusHandler->SetClientLoggedOutL( aClient );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::TheClientLoggedInL()
+// Status getter
+// -----------------------------------------------------------------------------
+//
+TBool CCnUiConnectionHandler::TheClientLoggedInL( TIMPSConnectionClient aClient )
+    {
+
+    CPEngNWSessionSlotID2* slotID = CPEngNWSessionSlotID2::NewLC();
+    slotID->SetServiceAddressMatchAnyL();
+    slotID->SetUserIdMatchAnyL();
+    if ( aClient == EIMPSConnClientPEC )
+        {
+        slotID->SetAppIdL( KPEngAppIdPEC() );
+        }
+    else
+        {
+        slotID->SetAppIdL( KPEngAppIdIM() );
+        }
+
+    //Clear logged in flags if there doesn't exist a connection
+    if ( !NwConnectionActiveL( *slotID ) )
+        {
+        iClientStatusHandler->SetClientLoggedOutL( aClient );
+        IMPSCUI_DP( D_IMPSCUI_LIT( "CCnUiConnectionHandler::TheClientLoggedInL( %d ) - [%d] (no nw)" ), aClient, EFalse );
+        CleanupStack::PopAndDestroy( slotID );
+        return EFalse;
+        }
+
+    CleanupStack::PopAndDestroy( slotID );
+    //active connection so client is in
+    return ETrue;
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::GetLoggedInSapL()
+// Status getter
+// -----------------------------------------------------------------------------
+//
+TBool CCnUiConnectionHandler::GetLoggedInSapL(
+    CIMPSSAPSettings& aSap,
+    TIMPSConnectionClient aClient )
+    {
+
+    aSap.Reset();
+
+    CPEngNWSessionSlotManager2* slotManager = CPEngNWSessionSlotManager2::NewLC();
+
+    CPEngNWSessionSlotID2* pattern = CPEngNWSessionSlotID2::NewLC();
+    pattern->SetServiceAddressMatchAnyL();
+    pattern->SetUserIdMatchAnyL();
+    if ( aClient == EIMPSConnClientPEC )
+        {
+        pattern->SetAppIdL( KPEngAppIdPEC );
+        }
+    else
+        {
+        pattern->SetAppIdL( KPEngAppIdIM );
+        }
+
+    RPointerArray< CPEngNWSessionSlotID2 > array;
+    TInt err( slotManager->GetNWSessionSlots( array, *pattern, EPEngNWPresenceSessionOpen ) );
+    CleanupStack::PopAndDestroy( 2, slotManager ); // slotManager, pattern
+
+    CleanupStack::PushL( TCleanupItem( DestroyCloseModelArray, &array ) );
+    if ( err == KErrNotFound )
+        {
+        CleanupStack::PopAndDestroy(); //array
+        return EFalse;
+        }
+    else
+        {
+        User::LeaveIfError( err );
+        }
+
+    if ( array.Count() > 0 )
+        {
+        CPEngNWSessionSlot2* tempSlot = NULL;
+        TRAPD( error, tempSlot = NetworkSessionSlotForIDL( *array[0] ) );
+        if ( error == KErrNotFound )
+            {
+            CleanupStack::PopAndDestroy(); //array
+            return EFalse;
+            }
+        else
+            {
+            User::LeaveIfError( error );
+            }
+        if ( tempSlot )
+            {
+            tempSlot->OpenNWPresenceSessionOwnership();
+            TInt err = tempSlot->GetNWPresenceSessionSap( aSap );
+            delete tempSlot;
+            if ( err == KErrNone )
+                {
+                // this slot was active and SAP is now filled
+                CleanupStack::PopAndDestroy(); //array
+                return ETrue;
+                }
+            }
+        }
+    CleanupStack::PopAndDestroy(); //array
+    return EFalse;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::SapConnectionStatusL()
+// Status getter
+// -----------------------------------------------------------------------------
+//
+TCnUiSapCnStatus CCnUiConnectionHandler::SapConnectionStatusL( const CIMPSSAPSettings& aSap,
+                                                               TIMPSConnectionClient aClient )
+    {
+    CIMPSSAPSettings* loggedinSAP = CIMPSSAPSettings::NewLC();
+    TBool nwConnectionActive = GetLoggedInSapL( *loggedinSAP, aClient );
+
+    //verify connection settings (address & user id)
+    TBool sapAddressMatch = ( loggedinSAP->SAPAddress().Compare( aSap.SAPAddress() ) == 0 );
+
+    TPtrC loggedInPlainUserId(
+        StripWVSchemaPrefix( StripDomainPart( loggedinSAP->SAPUserId() ) ) );
+    TPtrC loginPlainUserId( StripWVSchemaPrefix( StripDomainPart( aSap.SAPUserId() ) ) );
+    TBool userIdsMatch = ( loggedInPlainUserId.Compare( loginPlainUserId ) == 0 );
+
+
+    //verify passwords
+    TBool pwdsMatch = EFalse;
+    if ( loggedinSAP->SAPUserPassword().Compare( aSap.SAPUserPassword() ) == 0 )
+        {
+        pwdsMatch = ETrue;
+        }
+    CleanupStack::PopAndDestroy( loggedinSAP ); //loggedinSAP
+
+
+    if ( !nwConnectionActive )
+        {
+        //no active NW connection
+        return ECnUiSCS_NotConnected;
+        }
+
+
+    //there is a some network connection, what its state is ?
+    if ( sapAddressMatch && userIdsMatch )
+        {
+        //session to similar SAP than gived one exist already
+        if ( pwdsMatch )
+            {
+            //exactly same SAP connected
+            return ECnUiSCS_SapConnected;
+            }
+        //similar SAP but with different password connected
+        return ECnUiSCS_SapConnected_PwdMissMatch;
+        }
+
+    else
+        {
+        //session to some other SAP exist
+
+        //is there known clients logged in to this session ?
+        if ( iClientStatusHandler->AnyClientLoggedIn() )
+            {
+            return ECnUiSCS_AnotherSapConnected;
+            }
+        return ECnUiSCS_AnotherSapConnected_ClientsNotKnown;
+        }
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::GetLoggedInClientsL()
+// Status getter
+// -----------------------------------------------------------------------------
+//
+void CCnUiConnectionHandler::GetLoggedInClientsL( RArray< TIMPSConnectionClient >& aClients )
+    {
+    aClients.Reset();
+    if ( iClientStatusHandler->ClientLoggedIn( EIMPSConnClientPEC ) )
+        {
+        User::LeaveIfError( aClients.Append( EIMPSConnClientPEC ) );
+        }
+
+    if ( iClientStatusHandler->ClientLoggedIn( EIMPSConnClientIM ) )
+        {
+        User::LeaveIfError( aClients.Append( EIMPSConnClientIM ) );
+        }
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::NwConnectionActiveL()
+// Status getter
+// -----------------------------------------------------------------------------
+//
+TBool CCnUiConnectionHandler::NwConnectionActiveL( CPEngNWSessionSlotID2& aIdToMatch )
+    {
+    //check do we have a connection or not
+
+    // assume that if both service address and userid are given it's a full ID
+    // if either is wildcard then assume that only appID is wanted to be matched
+    TBool fullID ( !aIdToMatch.IsServiceAddressWild() | !aIdToMatch.IsUserIdWild() );
+
+    CPEngNWSessionSlotManager2* slotManager = CPEngNWSessionSlotManager2::NewLC();
+
+    RPointerArray< CPEngNWSessionSlotID2 > array;
+    TInt error( slotManager->GetNWSessionSlots( array, aIdToMatch,
+                                                EPEngNWPresenceSessionOpen ) );
+    if ( error != KErrNone )
+        {
+        array.ResetAndDestroy();
+        User::Leave( error );
+        }
+    CleanupStack::PopAndDestroy( slotManager ); // slotManager
+
+    TBool returnValue( EFalse );
+    if ( array.Count() > 0 )
+        {
+        returnValue = ETrue;
+        }
+
+    array.ResetAndDestroy();
+    return returnValue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::ServiceStatusL()
+// Status getter
+// -----------------------------------------------------------------------------
+//
+TPEngNWSessionSlotState CCnUiConnectionHandler::ServiceStatusL(
+    const CPEngNWSessionSlotID2& aNWSessionSlotID )
+    {
+    TPEngNWSessionSlotState slotState ( EPEngNWPresenceSessionClosed );
+
+    CPEngNWSessionSlot2* slot = NetworkSessionSlotForIDL( aNWSessionSlotID );
+    slot->GetNWSessionSlotState( slotState );
+    delete slot;
+
+    return slotState;
+    }
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::ServiceStatusL()
+// Status getter
+// -----------------------------------------------------------------------------
+//
+CPEngNWSessionSlot2* CCnUiConnectionHandler::NetworkSessionSlotForIDL(
+    const CPEngNWSessionSlotID2& aNWSessionSlotID )
+    {
+    return CPEngNWSessionSlot2::NewL( aNWSessionSlotID );
+    }
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::SetSessionSlotL()
+// Status getter
+// -----------------------------------------------------------------------------
+//
+void CCnUiConnectionHandler::SetSessionSlotL( CPEngNWSessionSlot2* aSlot )
+    {
+    delete iNWSessionSlot;
+    iNWSessionSlot = aSlot;
+    }
+
+// -----------------------------------------------------------------------------
+// CCnUiConnectionHandler::DestroyCloseModelArray()
+//
+// -----------------------------------------------------------------------------
+//
+void CCnUiConnectionHandler::DestroyCloseModelArray( TAny* aObject )
+    {
+    reinterpret_cast< RPointerArray< CPEngNWSessionSlotID2 >* >( aObject )->ResetAndDestroy();
+    }
+//  End of File
+
+