PECengine/PresenceServer2/ServerSrc/CPEngCSPSessManager.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PECengine/PresenceServer2/ServerSrc/CPEngCSPSessManager.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,1255 @@
+/*
+* Copyright (c) 2002 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:  One Session manager of the presence server
+* 				 Handles all management concerning one network session
+*  				 Opening, closing, ownership handling, updating
+*  				 of Session related data to network
+*
+*/
+
+
+
+// INCLUDE FILES
+#include	<e32std.h>
+#include    "CPEngCSPSessManager.h"
+
+#include	"CPEngAppAccessContainer.h"
+#include	"MPEngSubSession.h"
+
+#include	"MPEngRequestHandler.h"
+#include	"CPEngHandlerLogIn.h"
+#include	"CPEngHandlerLogOff.h"
+#include	"CPEngHandlerSendData.h"
+#include	"MPEngOutgoingTransactionHandler.h"
+#include	"CPEngIncomingDataHandler.h"
+
+
+#include	"TPEngServerMessages.h"
+#include	"MPEngServer.h"
+
+#include	"CPEngSessionSlotId.h"
+#include	"CPEngSessionSlotEvent.h"
+#include	"PEngWVServices2.h"
+#include	"RObjectArray.h"
+
+#include	"PEngTransferAdapter.h"
+
+
+// transaction factories
+#include	"MPEngTransactionFactory.h"
+#include	"PEngAttrLibFactory.h"
+#include	"PEngListLibraryFactory.h"
+
+// pure data handler
+#include	"MPEngPureDataHandler.h"
+#include	"MPEngAccessHandler.h"
+
+//	Own RMessage class wraper
+#include	"RPEngMessage.h"
+
+// Debug prints
+#include	"PresenceDebugPrint.h"
+
+
+
+// CONSTANTS
+const TInt KLastRefAccessCount = 1;
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::CPEngCSPSessManager
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CPEngCSPSessManager::CPEngCSPSessManager(
+    MPEngServer& aServer )
+        : iAccessCount( 1 ), // init access count to 1
+        iState( EPEngNWPresenceSessionClosed ),
+        iServer( aServer ),
+        iRequestHandlers( 2 ),	// not many requests at time
+        iTransFactories( 3 ) // there 3 three factories
+
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::CPEngCSPSessManager" ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::ConstructL(
+    const CPEngSessionSlotId& aSessId,
+    RPEngStorageAdminClient& aAdmin )
+    {
+    iSessionSlotId = aSessId.CloneL();
+
+    iAccessCounters = CObjectCon::NewL();
+    // we need to set Unique ID of the containers so they own their objects
+    iAccessCounters->iUniqueID = reinterpret_cast<TInt> ( this );
+
+    HBufC8* sessId = aSessId.PackLC();
+    User::LeaveIfError( iStoreAdmin.Connect( aAdmin, *sessId ) );
+    CleanupStack::PopAndDestroy( sessId ); // sessId
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CPEngCSPSessManager* CPEngCSPSessManager::NewLC(
+    MPEngServer& aServer,
+    const CPEngSessionSlotId& aSessId,
+    RPEngStorageAdminClient& aAdmin )
+    {
+    CPEngCSPSessManager* self = new( ELeave ) CPEngCSPSessManager( aServer );
+
+    CleanupClosePushL( *self );
+    self->ConstructL( aSessId, aAdmin );
+
+    return self;
+    }
+
+
+// Destructor
+CPEngCSPSessManager::~CPEngCSPSessManager()
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::~CPEngCSPSessManager" ) );
+
+    delete iSessionSlotId;
+    ResetAccessContainers();
+    delete iAccessCounters;
+
+    iRequestHandlers.ResetAndDestroy();
+    // set state to the Close, so all resources are sure deleted
+    iState = EPEngNWPresenceSessionClosed;
+    UnloadResources();
+
+    iIncomingHandlers.ResetAndDestroy();
+
+    iStoreAdmin.Close();
+    iServer.RemoveCSPSessManager( this );
+
+    iServSubSessions.Reset();
+
+
+#if _BullseyeCoverage
+    cov_write();
+#endif
+    }
+
+/////////////////////////////////////////////////////////////////////////////////
+// ========== Functions from MPEngRequestHandlerObserver ========================
+/////////////////////////////////////////////////////////////////////////////////
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::CompleteRequestHandler()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::CompleteRequestHandler(
+    MPEngRequestHandler* aRequestHandler )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::CompleteRequestHandler: %d" ),
+             ( TInt )aRequestHandler  );
+
+    TInt handlerIndex ( iRequestHandlers.Find( aRequestHandler ) );
+    if ( handlerIndex != KErrNotFound )
+        {
+        iRequestHandlers.Remove( handlerIndex );
+        }
+    // if we are offline and there is no more request handler, unload
+    // resources
+    if (
+        ( iState == EPEngNWPresenceSessionClosed )
+        &&
+        ( iRequestHandlers.Count() == 0 )
+    )
+        {
+        UnloadResources();
+        }
+    CheckReferenceAccessD();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::SetCSPSessionOpenedL()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::SetCSPSessionOpenedL()
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::SetCSPSessionOpenedL: %d" ) );
+
+    // Load resources
+    LoadResourcesL();
+    // set state to online
+    iState	= EPEngNWPresenceSessionOpen;
+    }
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// ========== Functions from MPEngRequestHandlerObserver ========================
+/////////////////////////////////////////////////////////////////////////////////
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::StatusChangedL()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::StatusChangedL(
+    TPEngNWSessionSlotState aNewState,
+    TPEngNWSessionSlotEvent aNewEvent )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::StatusChangedL: state:%d Event:%d" ),
+             aNewState,
+             aNewEvent );
+
+
+    // is tate different than holder is
+    if ( aNewState == iState )
+        {
+        // state is same, do nothing
+        return;
+        }
+    // update state and inform about it
+    iState = aNewState;
+    if ( iState == EPEngNWPresenceSessionClosed )
+        {
+        // we are closed, unload resources
+        UnloadResources();
+        TInt count( iAccessCounters->Count() );
+        for ( TInt x( 0 ) ; x < count ; ++x )
+            {
+            NotifyNewEventL( aNewEvent,
+                             static_cast<CPEngAppAccessContainer*>
+                             ( ( *iAccessCounters )[ x ] )->AppId(),
+                             EPEngNWPresenceSessionClosed );
+            }
+        // remove all access containers
+        ResetAccessContainers();
+        }
+    else if ( iState == EPEngNWPresenceSessionOpen )
+        {
+        LoadResourcesL();
+        // Do not notify, it will be done by LogIn Handler
+        }
+    }
+
+/////////////////////////////////////////////////////////////////////////////////
+//======================== New Functions of main class ==========================
+/////////////////////////////////////////////////////////////////////////////////
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::Open()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::Open()
+    {
+    iAccessCount++;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::Close()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::Close()
+    {
+    iAccessCount--;
+    CheckReferenceAccessD();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::OpenL()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::OpenL(
+    MPEngSubSession& aServSubSession )
+    {
+    iServSubSessions.AppendL( &aServSubSession );
+    iAccessCount++;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::Close()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::Close(
+    MPEngSubSession* aServSubSession )
+    {
+    TInt x( iServSubSessions.Find( aServSubSession ) );
+    if ( x != KErrNotFound )
+        {
+        iServSubSessions.Remove( x );
+        iAccessCount--;
+        }
+    CheckReferenceAccessD();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::AttachAppIdL()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::AttachAppIdL(
+    const TDesC& aAppId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::AttachAppIdL:%S" ), &aAppId );
+
+
+    // allow attaching of the App Id only if CSP is opened
+    LeaveIfNotConnectedL();
+
+    CPEngAppAccessContainer* accessCounter = AccessCounter( aAppId );
+    if ( accessCounter )
+        {
+        TInt val = accessCounter->Open(); // CSI: 65 #
+        return;
+        }
+    // does not exist, create and append
+    CPEngAppAccessContainer* newContainer =
+        CPEngAppAccessContainer::NewLC( aAppId );
+    iAccessCounters->AddL( newContainer );
+    // notify about new App Id logging
+    NotifyNewEventL( EPEngEventAppNWPresenceSessionOpened,
+                     aAppId,
+                     EPEngNWPresenceSessionOpen );
+    CleanupStack::Pop( newContainer ); // newContainer
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::DetachAppId()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::DetachAppId(
+    const TDesC& aAppId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::DetachAppId:%S " ), &aAppId );
+
+    CPEngAppAccessContainer* accessCounter = AccessCounter( aAppId );
+    TBool notify( EFalse );
+    if ( accessCounter )
+        {
+        notify = accessCounter->CloseAccess();
+        }
+    if ( iState == EPEngNWPresenceSessionClosed )
+        {
+        // no need to notify, it was already done
+        notify = EFalse;
+        }
+    // do we need to do Log Out from CSP?
+    else if ( !( iAccessCounters->Count() ) )
+        {
+        // quite brutal, but unload everything, we cannot do lot more
+        iRequestHandlers.ResetAndDestroy();
+        UnloadResources();
+        iState = EPEngNWPresenceSessionClosed;
+        notify = ETrue;
+        }
+    // notify event
+    if ( notify )
+        {
+        TRAP_IGNORE( NotifyNewEventL( EPEngEventAppNWPresenceSessionClosed,
+                                      aAppId,
+                                      EPEngNWPresenceSessionClosed ) );
+        }
+    CheckReferenceAccessD();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::AppIdActiveL()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::AppIdActiveL(
+    const TDesC& aAppId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::AppIdActiveL:%S" ), &aAppId );
+
+    CPEngAppAccessContainer* accessCounter = AccessCounter( aAppId );
+    if ( !accessCounter )
+        {
+        User::Leave( KErrNotReady );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::ReserveProcessL()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::ReserveProcessL(
+    const TDesC& aAppId,
+    const TDesC& aProcessId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::ReserveProcessL: %S : %S" ),
+             &aAppId,
+             &aProcessId );
+
+    CPEngAppAccessContainer* accessCounter = AccessCounter( aAppId );
+    if ( accessCounter )
+        {
+        accessCounter->ReserveProcessL( aProcessId );
+        return;
+        }
+    // does not exist, leave
+    User::Leave( KErrNotFound );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::ActivateProcessL()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::ActivateProcessL(
+    const TDesC& aAppId,
+    const TDesC& aProcessId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::ReserveProcessL: %S : %S" ),
+             &aAppId,
+             &aProcessId );
+
+    CPEngAppAccessContainer* accessCounter = AccessCounter( aAppId );
+    if ( accessCounter )
+        {
+        // it will leave if not find
+        accessCounter->ActivateProcessIdL( aProcessId );
+        return;
+        }
+
+    User::Leave( KErrNotReady );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::SessionId()
+// -----------------------------------------------------------------------------
+//
+const CPEngSessionSlotId& CPEngCSPSessManager::SessionId() const
+    {
+    return *iSessionSlotId;
+    }
+
+////////////////////////////////////////////////////////////////////////////////
+// =========== New Function for Request handling ===============================
+////////////////////////////////////////////////////////////////////////////////
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::HandleAsynchronousRequestL()
+// -----------------------------------------------------------------------------
+//
+void  CPEngCSPSessManager::HandleAsynchronousRequestL(
+    const RPEngMessage& aMessage,
+    MPEngSubSession& aServSubSession,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::HandleAsynchronousRequestL:%d" ),
+             aMessage.Function() );
+
+    TInt function( aMessage.Function() );
+    // first check that this kind of request is allowed
+    CheckRequestValidityL( function, aServSessionId, aServSubSessionId );
+    // request can be proceeded
+    switch ( function )
+        {
+        case ESubSessUpdateData:
+            {
+            HandleUpdateDataRequestL( aMessage,
+                                      aServSubSession,
+                                      aServSessionId,
+                                      aServSubSessionId );
+            break;
+            }
+
+        default:
+            {
+            User::Leave( KErrNotSupported );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::HandleSynchronousRequestL()
+// -----------------------------------------------------------------------------
+//
+void  CPEngCSPSessManager::HandleSynchronousRequestL(
+    const RPEngMessage& aMessage,
+    TInt32 /* aServSessionId */,
+    TInt /* aServSubSessionId */ )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::HandleSynchronousRequestL:%d" ),
+             aMessage.Function() );
+
+    // first check that this kind of request is allowed
+    TInt function( aMessage.Function() );
+    switch ( function )
+        {
+            // Get Session service tree
+        case ESubSessGetServiceTree:
+            {
+            LeaveIfNotConnectedL();
+            TPckgBuf<TPEngWVCspServicesTree2> serviceTree(
+                iAccessHandler->ServiceCapabilities() );
+            aMessage.WriteOneDescriptorL( KMessageSlot0, serviceTree );
+            break;
+            }
+
+        // get Session Log in data
+        case ESubSessGetLogInData:
+            {
+            LeaveIfNotConnectedL();
+            TInt err( aMessage.WriteOneDescriptor( KMessageSlot0,
+                                                   iAccessHandler->LogInData() ) );
+            if ( err == KErrOverflow )
+                {
+                User::Leave( iAccessHandler->LogInData().Length() );
+                }
+            User::LeaveIfError( err );
+            break;
+            }
+
+        default:
+            {
+            User::Leave( KErrNotSupported );
+            break;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::HandleLogInRequestL
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::HandleLogInRequestL(
+    const RPEngMessage& aMessage,
+    MPEngSubSession& aSubSession,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId  )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::HandleLogInRequestL:" ) );
+
+    // is CSP session active?
+    if ( iState == EPEngNWPresenceSessionOpen )
+        {
+        // verify password and leave if password is not correct
+        HBufC8*	loginData = aMessage.ReadOneDescriptor8LC( KMessageSlot0 );
+        iAccessHandler->AssertLoginDataL( *loginData );
+        CleanupStack::PopAndDestroy( loginData ); // loginData
+
+        // session is active, inform sub-session to Open Ref to the App Id
+        aSubSession.HandleLogInL();
+        // done
+        aMessage.Complete( KErrNone );
+        return;
+        }
+    // Open network connection, not logged
+    DoLogInL( aMessage, aSubSession, aServSessionId, aServSubSessionId );
+    // done here
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::HandleForceLogOutRequestL
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::HandleForceLogOutRequestL(
+    const RPEngMessage& aMessage,
+    MPEngSubSession& aSubSession,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::HandleForceLogOutRequestL:" ) );
+
+    // is CSP session active or does App id exists
+    CPEngAppAccessContainer* accessCounter = AccessCounter(
+                                                 aSubSession.AppId() );
+
+    if ( ( iState == EPEngNWPresenceSessionClosed )
+         ||
+         ( !accessCounter )
+       )
+        {
+        aSubSession.HandleLogOut();
+        // we are already closed
+        aMessage.Complete( KErrNotReady );
+        return;
+        }
+
+    // check how many active app ids we have
+    if ( iAccessCounters->Count() == KLastRefAccessCount )
+        {
+        // we need to do proper log out of whole CSP
+        DoLogOutL( aMessage,
+                   aSubSession,
+                   aServSessionId,
+                   aServSubSessionId );
+        return;
+        }
+
+    // just remove appId from active and inform sub-sessions
+    NotifyNewEventL( EPEngEventAppNWPresenceSessionClosed,
+                     aSubSession.AppId(),
+                     EPEngNWPresenceSessionClosed );
+    NotifyDisconnectedAppId( aSubSession.AppId() );
+    accessCounter->CloseContainer();
+    aSubSession.HandleLogOut();
+    aMessage.Complete( KErrNone );
+    CheckReferenceAccessD();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::HandleDetachAppIdL()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::HandleDetachAppIdL(
+    const RPEngMessage& aMessage,
+    MPEngSubSession& aSubSession,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::HandleDetachAppIdL:" ) );
+
+    CPEngAppAccessContainer* accessCounter = AccessCounter(
+                                                 aSubSession.AppId() );
+
+    if ( ( iState == EPEngNWPresenceSessionClosed )
+         ||
+         ( !accessCounter )
+       )
+        {
+        aSubSession.HandleLogOut();
+        // we are already closed
+        aMessage.Complete( KErrNone );
+        return;
+        }
+
+    // is this last connection holder
+    if (
+        ( KLastRefAccessCount == accessCounter->ActiveAccessCount() )
+        &&
+        ( KLastRefAccessCount == iAccessCounters->Count() )
+    )
+        {
+        // Issue log out of the CSP
+        DoLogOutL( aMessage,
+                   aSubSession,
+                   aServSessionId,
+                   aServSubSessionId );
+        return;
+        }
+    // remove session Id
+    TBool notify( accessCounter->CloseAccess() );
+    // Notify about close of the App Id
+    if ( notify )
+        {
+        NotifyNewEventL( EPEngEventAppNWPresenceSessionClosed,
+                         aSubSession.AppId(),
+                         EPEngNWPresenceSessionClosed );
+        NotifyDisconnectedAppId( aSubSession.AppId() );
+        aSubSession.HandleLogOut();
+        aMessage.Complete( KErrNone );
+        CheckReferenceAccessD();
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::CancelAsynchronousRequest()
+// -----------------------------------------------------------------------------
+//
+void  CPEngCSPSessManager::CancelAsynchronousRequest(
+    const RPEngMessage& aMessage,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::CancelAsynchronousRequest:%d" ),
+             aMessage.Int0() );
+
+    TInt function( aMessage.Int0() );
+    // there can be only one async request of each kind per each Sub session,
+    TInt fescue( FindRequestInSubSession(	function,
+                                          aServSessionId,
+                                          aServSubSessionId ) );
+    if ( fescue != KErrNotFound )
+        {
+        iRequestHandlers[ fescue ]->CancelRequestD();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::CancelAllSessionRequests()
+// -----------------------------------------------------------------------------
+//
+void  CPEngCSPSessManager::CancelAllSessionRequests(
+    TInt32 aServSessionId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::CancelAllSessionRequests:" ) );
+
+    for ( TInt fescue( iRequestHandlers.Count() - 1 );
+          fescue >= 0;
+          --fescue )
+        {
+        // check handlers only in case, handlerCount is smaller them
+        // real number of requests this is because,canceling
+        // of particular requests can complete other requests
+        if ( fescue < iRequestHandlers.Count() )
+            {
+            if ( iRequestHandlers[ fescue ]->SessionId() == aServSessionId )
+                {
+                iRequestHandlers[ fescue ]->CancelRequestD();
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::CancelAllSubSessionRquests()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::CancelAllSubSessionRquests(
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::CancelAllSubSessionRquests:" ) );
+
+    for ( TInt fescue( iRequestHandlers.Count() - 1 );
+          fescue >= 0;
+          --fescue )
+        {
+        // check handlers only in case, handlerCount is smaller them
+        // real number of requests this is because,canceling
+        // of particular requests can complete other requests
+        if (
+            ( fescue < iRequestHandlers.Count() )
+            &&
+            ( iRequestHandlers[ fescue ]->SessionId() == aServSessionId )
+            &&
+            ( iRequestHandlers[ fescue]->SubSessionId() == aServSubSessionId )
+        )
+            {
+            iRequestHandlers[ fescue ]->CancelRequestD();
+            }
+        }
+    }
+
+/////////////////////////////////////////////////////////////////////////////////
+//===================== Functions for resource handling =========================
+/////////////////////////////////////////////////////////////////////////////////
+// -----------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::LoadResourcesL()
+// Load Pure data handler
+// Load transaction factories
+// start listening of the incoming request from network
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::LoadResourcesL()
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::LoadResourcesL:" ) );
+
+    // load pure data handler
+    if ( !iPureDataHandler )
+        {
+        iPureDataHandler = PEngTransferAdapter::PureDataHandlerL(
+                               *iSessionSlotId );
+        }
+
+    if ( iTransFactories.Count() == 0 )
+        {
+        // load and initialize factories
+        // create List library transaction factory
+
+        MPEngTransactionFactory* transFactory =
+            PEngListLibraryFactory::AttributeListsTransactionManagerLC(
+                *iSessionSlotId );
+        iTransFactories.AppendL( transFactory );
+        CleanupStack::Pop(); // transFactory
+
+        // create attribute List Transaction factory
+        transFactory =
+            PEngListLibraryFactory::ContactListTransactionManagerLC(
+                *iSessionSlotId );
+        iTransFactories.AppendL( transFactory );
+        CleanupStack::Pop(); // transFactory
+
+        // create attribute library transaction factory
+        transFactory = PEngAttrLibFactory::AttributeTransFactoryInstanceLC(
+                           *iSessionSlotId );
+        iTransFactories.AppendL( transFactory );
+        CleanupStack::Pop(); // transFactory
+
+        // create autorization transaction factory
+        transFactory = PEngListLibraryFactory::AuthorizationTransactionManagerLC(
+                           *iSessionSlotId );
+        iTransFactories.AppendL( transFactory );
+        CleanupStack::Pop(); // transFactory
+
+        }
+
+    if ( iIncomingHandlers.Count() == 0 )
+        {
+        CPEngIncomingDataHandler* handler =
+            CPEngIncomingDataHandler::NewLC( *iPureDataHandler,
+                                             iTransFactories,
+                                             *this );
+        handler->StartListeningL();
+        iIncomingHandlers.AppendL( handler );
+        CleanupStack::Pop( handler ); // handler
+        }
+    if ( !iPluginsLoaded )
+        {
+        iServer.SessionOpened();
+        iPluginsLoaded = ETrue;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::UnloadResources()
+// Stop Incoming data listening and processing
+// close transaction factories
+// unload pure data handler
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::UnloadResources()
+    {
+    PENG_DP( D_PENG_LIT( "CPEngCSPSessManager::UnloadResources:" ) );
+
+    // Stop listening
+    iIncomingHandlers.ResetAndDestroy();
+    if ( !iRequestHandlers.Count() || iState == EPEngNWPresenceSessionClosed )
+        {
+        UnloadTransactionFactories();
+        if ( iPureDataHandler )
+            {
+            iPureDataHandler->Close();
+            iPureDataHandler = NULL;
+            }
+        if ( iAccessHandler )
+            {
+            iAccessHandler->UnregisterSessionObserver( *this );
+            iAccessHandler->Close();
+            iAccessHandler = NULL;
+            }
+        }
+    if ( iPluginsLoaded )
+        {
+        iServer.SessionClosed();
+        iPluginsLoaded = EFalse;
+        }
+    }
+
+/////////////////////////////////////////////////////////////////////////////////
+//================= Private Functions of request management =====================
+/////////////////////////////////////////////////////////////////////////////////
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::CheckRequestValidityL()
+// Check if request is allowed to be handled
+// If request is not allowed, function leaves, so request message is
+// completed by the framework
+// If not needed, server session and sub-session Ids are not obeyed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::CheckRequestValidityL(
+    TInt aRequestFunction,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    // according to the request function, check if there is already
+    // such a request pending and if yes, then if another is allowed
+    switch ( aRequestFunction )
+        {
+        case ESubSessLogIn:
+        case ESubSessForceLogOut:
+            {
+            // only one request of this kind per session manager
+            if ( KErrNotFound != FindRequest( aRequestFunction ) )
+                {
+                User::Leave( KErrAlreadyExists );
+                }
+            break;
+            }
+
+        case ESubSessUpdateData:
+            {
+            // only one request of this kind per session
+            if ( KErrNotFound != FindRequestInSubSession(
+                     aRequestFunction,
+                     aServSessionId,
+                     aServSubSessionId ) )
+                {
+                User::Leave( KErrAlreadyExists );
+                }
+            break;
+            }
+
+        default:
+            break;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::FindRequest()
+// Look for the particular request within all sessions
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CPEngCSPSessManager::FindRequest(
+    TInt aRequestFunction )
+    {
+    TInt handlerCount( iRequestHandlers.Count() );
+    for ( TInt x( 0 ) ; x < handlerCount ; x++ )
+        {
+        if ( iRequestHandlers[x]->RequestFunction() == aRequestFunction )
+            {
+            return x;
+            }
+        }
+    return KErrNotFound;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::FindRequestInSession()
+// Look for the particular request within the session
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CPEngCSPSessManager::FindRequestInSession(
+    TInt aRequestFunction,
+    TInt32 aServSessionId )
+    {
+    TInt handlerCount( iRequestHandlers.Count() );
+    for ( TInt x( 0 ) ; x < handlerCount ; x++ )
+        {
+        if (
+            ( iRequestHandlers[ x ]->SessionId() == aServSessionId )
+            &&
+            ( iRequestHandlers[ x ]->RequestFunction() == aRequestFunction )
+        )
+            {
+            return x;
+            }
+        }
+    return KErrNotFound;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::FindRequestInSubSession()
+// Look for the particular request within the session
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CPEngCSPSessManager::FindRequestInSubSession(
+    TInt aRequestFunction,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    TInt handlerCount( iRequestHandlers.Count() );
+    for ( TInt x( 0 ) ; x < handlerCount ; x++ )
+        {
+        if (
+            ( iRequestHandlers[ x ]->SessionId() == aServSessionId )
+            &&
+            ( iRequestHandlers[ x ]->SubSessionId() == aServSubSessionId )
+            &&
+            ( iRequestHandlers[ x ]->RequestFunction() == aRequestFunction )
+        )
+            {
+            return x;
+            }
+        }
+    return KErrNotFound;
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::HandleUpdateDataRequestL
+// Handle Send Attributes Request
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::HandleUpdateDataRequestL(
+    const RPEngMessage& aMessage,
+    MPEngSubSession& aServSubSession,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    // get factory and operation enumerations
+    TInt opId( aMessage.Int0() );
+
+    LeaveIfNotConnectedL();
+
+    // read data to be updated
+    HBufC* data = aMessage.ReadOneDescriptor16LC( KMessageSlot1 );
+    RObjectArray<MPEngOutgoingTransactionHandler> transactions;
+    CleanupClosePushL( transactions	);
+    TInt count( iTransFactories.Count() );
+    for ( TInt x( 0 ) ; x < count ; ++x )
+        {
+        iTransFactories[ x ]->OutgoingTransactionHandlerL( opId,
+                                                           *data,
+                                                           transactions );
+        }
+    if ( transactions.Count() == 0 )
+        {
+        // nothing to do, complete Message
+        aMessage.Complete( KErrNone );
+        CleanupStack::PopAndDestroy( 2 ); // transactions, data,
+        return;
+        }
+
+    CPEngHandlerSendData* newHandler = CPEngHandlerSendData::NewLC(
+                                           *this,
+                                           *iPureDataHandler,
+                                           aServSubSession,
+                                           aMessage,
+                                           transactions,
+                                           aServSessionId,
+                                           aServSubSessionId );
+
+    iRequestHandlers.AppendL( newHandler );
+    // keep handler in the clean up for Starting,
+    // so it is deleted when start fails
+    newHandler->StartHandlerL();
+    newHandler->SetMessage( aMessage );
+    CleanupStack::Pop( newHandler ); // newHandler
+    CleanupStack::PopAndDestroy( 2 ); // transactions, data,
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::DoLogInL
+// Do Log In to the CSP session
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::DoLogInL(
+    const RPEngMessage& aMessage,
+    MPEngSubSession& aServSubSession,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    // Load access handler and start listening
+    if ( !iAccessHandler )
+        {
+        iAccessHandler = PEngTransferAdapter::AccessHandlerL(
+                             *iSessionSlotId );
+        iAccessHandler->RegisterSessionObserverL( *this );
+        }
+    // create new handler
+    CPEngHandlerLogIn* newHandler = CPEngHandlerLogIn::NewLC(
+                                        *this,
+                                        *iAccessHandler,
+                                        aServSubSession,
+                                        aMessage,
+                                        aServSessionId,
+                                        aServSubSessionId );
+
+    // store new handler
+    iRequestHandlers.AppendL( newHandler );
+    // keep handler in the clean up for Starting,
+    // so it is deleted when start fails
+    newHandler->StartHandlerL( aMessage );
+    newHandler->SetMessage( aMessage );
+    CleanupStack::Pop( newHandler ); // newHandler
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::DoLogOutL
+// Do log out from the CSP session
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::DoLogOutL(
+    const RPEngMessage& aMessage,
+    MPEngSubSession& aServSubSession,
+    TInt32 aServSessionId,
+    TInt   aServSubSessionId )
+    {
+    // create new handler
+    CPEngHandlerLogOff* newHandler = CPEngHandlerLogOff::NewLC(
+                                         *this,
+                                         *iAccessHandler,
+                                         aServSubSession,
+                                         aMessage,
+                                         aServSessionId,
+                                         aServSubSessionId );
+
+    // store new handler
+    iRequestHandlers.AppendL( newHandler );
+    // keep handler in the clean up for Starting,
+    // so it is deleted when start fails
+    newHandler->StartHandlerL();
+    newHandler->SetMessage( aMessage );
+    CleanupStack::Pop( newHandler ); // newHandler
+    // we are done
+    }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// ================ New private Helping functions ==============================
+////////////////////////////////////////////////////////////////////////////////
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::AccessCounter
+// Find Access counter
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CPEngAppAccessContainer* CPEngCSPSessManager::AccessCounter(
+    const TDesC& aAppId )
+    {
+    // look for the access counter manually
+    TInt count( iAccessCounters->Count() );
+    for ( TInt x( 0 ) ; x < count ; ++x )
+        {
+        CPEngAppAccessContainer* accessContainer =
+            static_cast <CPEngAppAccessContainer*>
+            ( ( *iAccessCounters )[ x ] );
+
+        if ( KErrNone == accessContainer->AppId().Compare( aAppId ) )
+            {
+            return accessContainer;
+            }
+        }
+    return NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::CheckReferenceAccessD
+// Check TInt ref access and reference access by the application Ids
+// if all accesses are zero, it deletes itself
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::CheckReferenceAccessD()
+    {
+    if ( !iAccessCount && !iAccessCounters->Count() )
+        {
+        delete this;
+        return;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::UnloadTransactionFactories
+// Unload Transaction factories
+// Transaction factories are ref-counted singletons, so they should
+// be closed rather than destroyed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::UnloadTransactionFactories()
+    {
+    for ( TInt x( iTransFactories.Count() - 1 ) ; x >= 0  ; --x )
+        {
+        iTransFactories[ x ]->Close();
+        iTransFactories.Remove( x );
+        }
+    iTransFactories.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::ResetAccessContainers
+// Reset access Containers
+// Go through all access containers and close them
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::ResetAccessContainers()
+    {
+    for ( TInt x( iAccessCounters->Count() - 1 ) ; x >= 0  ; --x )
+        {
+        static_cast<CPEngAppAccessContainer*>(
+            ( *iAccessCounters )[ x ] )->CloseContainer();
+        }
+
+    // notify all connected sub-session to disattach their app ids
+    NotifyCPSClose();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::NotifyDisconnectedAppId
+// Inform sub-session about app Id disconnection
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::NotifyDisconnectedAppId(
+    const TDesC& aAppId )
+    {
+    for ( TInt x( iServSubSessions.Count() - 1 ) ; x >= 0 ; --x )
+        {
+        iServSubSessions[ x ]->DisconnectAppId( aAppId );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::NotifyCPSClose
+// Inform sub-sessions about CPS close state
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::NotifyCPSClose()
+    {
+    for ( TInt x( iServSubSessions.Count() - 1 ) ; x >= 0 ; --x )
+        {
+        iServSubSessions[ x ]->CSPSessionClosed();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::NotifyNewEventL
+// Inform sub-sessions about CPS close state
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::NotifyNewEventL(
+    TPEngNWSessionSlotEvent aEvent,
+    const TDesC& aAppId,
+    TPEngNWSessionSlotState aAppIdState )
+    {
+    CPEngSessionSlotEvent* newEvent = CPEngSessionSlotEvent::NewLC();
+    newEvent->SetSessionSlotId( iSessionSlotId, EFalse );
+    newEvent->SetGlobSessSltState( iState );
+    newEvent->SetSessSltEvent( aEvent );
+    if ( aAppId != KNullDesC )
+        {
+        newEvent->SetAppIdL( aAppId );
+        newEvent->SetAppSessSltState( aAppIdState );
+        }
+    HBufC8* eventBuff = newEvent->PackEventLC();
+    // ignore error from notify
+    iStoreAdmin.NotifyEvent( *eventBuff );
+    CleanupStack::PopAndDestroy( 2 ); // eventBuff, newEvent
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngCSPSessManager::LeaveIfNotConnectedL()
+// -----------------------------------------------------------------------------
+//
+void CPEngCSPSessManager::LeaveIfNotConnectedL() const
+    {
+    if ( iState != EPEngNWPresenceSessionOpen )
+        {
+        User::Leave( KErrNotReady );
+        }
+    }
+
+
+//  End of File
+