presencecache/presencecacheserver2/src/presencecachesession.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/presencecache/presencecacheserver2/src/presencecachesession.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1206 @@
+/*
+* Copyright (c) 2008 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:  Impementation for Presence Cache Server session
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <mpresencebuddyinfo2.h>
+
+#include "presenceobjecthelpers.h"
+#include "presencecachesession.h"
+#include "presencecacheserver.h"
+#include "presencetrace.h"
+#include "cacheobjecthelpers.h"
+#include "presencecacheservicestore.h"
+#include "presencecachebuddystore.h"
+#include "presencecacheevent.h"
+
+//Include Cache server namespace
+using namespace NCacheSrv2;
+
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::NewL()
+// ---------------------------------------------------------------------------
+//
+CPresenceCacheSession* CPresenceCacheSession::NewL( CPresenceCacheServer& aServer )
+    {
+    CPresenceCacheSession* self = CPresenceCacheSession::NewLC( aServer );
+    CleanupStack::Pop(self);
+    return self;    
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::NewLC()
+// ---------------------------------------------------------------------------
+//
+CPresenceCacheSession* CPresenceCacheSession::NewLC( CPresenceCacheServer& aServer )
+    {
+    CPresenceCacheSession* self = new ( ELeave ) CPresenceCacheSession( aServer );
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;    
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::~CPresenceCacheSession()
+// ---------------------------------------------------------------------------
+//
+CPresenceCacheSession::~CPresenceCacheSession()
+    {
+    if(iDataPack)
+        delete iDataPack;
+    if(iDataPackAsync)
+        delete iDataPackAsync;
+    iBuddypresInfoList.ResetAndDestroy();
+    iBuddypresInfoList.Close();
+        
+    if(iActiveHelper)
+        delete iActiveHelper;
+    iServer.DecrementSessions();
+    RemoveMySubscriptions(); // remove all subscriptions subscribed by this session
+    iSubscribedStores.Close();
+    
+    EmptyNotificationQueue();
+    
+    iNotifyEvents.Close();
+    
+    TRACE_1( _L("CPresenceCacheSession[%d]::~CPresenceCacheSession()"), this );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::ServiceL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::ServiceL( const RMessage2& aMessage )
+    {
+    switch ( aMessage.Function() )
+        {
+        case NRequest::EPrepReadPresenceInfoSync:
+            HandlePrepReadPresenceInfoSyncL(aMessage);
+            break;
+            
+        case NRequest::EGetLastPreparedPacket:
+            HandleGetLastPreparedPacketL(aMessage);
+            break;
+            
+        case NRequest::EGetLastAsyncPreparedPacket:
+            HandleGetLastPreparedAsyncPacketL(aMessage);
+            break;
+            
+        case NRequest::EBuddyCountInAllServices:
+            HandleBuddyCountInAllServicesL(aMessage);
+            break;
+            
+        case NRequest::EBuddyCountInService:
+            HandleBuddyCountInServiceL(aMessage);
+            break;
+            
+        case NRequest::EGetServiceCount:
+            HandleGetServiceCountL(aMessage);
+            break;
+            
+        case NRequest::EDeleteService:
+            HandleDeleteServiceL(aMessage);
+            break;
+            
+        case NRequest::EDeletePresence:
+            HandleDeletePresenceL(aMessage);
+            break;
+            
+        case NRequest::ECancelAsyncOperation:
+            HandleCancel(aMessage);
+            break;
+
+        case NRequest::EWritePresenceInfoSync:
+            HandleWritePresenceInfoSyncL(aMessage);
+            break;
+
+        case NRequest::EWritePresenceInfoAsync:
+            HandleWritePresenceInfoAsyncL(aMessage);
+            break;
+            
+        case NRequest::EPrepReadAllBuddiesPresenceInService:
+            HandlePrepReadAllBuddiesPresenceInService(aMessage);
+            break;
+            
+        case NRequest::ESubscribeBuddyPresenceChange:// 0:aService.iUid, 1:myIdPack
+            HandleSubscribeBuddyPresenceChangeL(aMessage);
+            break;
+        
+        case NRequest::EUnSubscribeBuddyPresenceChange: // 0:aService.iUid, 1:myIdPack
+            HandleUnSubscribeBuddyPresenceChangeL(aMessage);
+            break;
+        
+        case NRequest::EGetLastNotifiedtPacket: // 0:&ptrBuf
+            HandleGetLastNotifiedtPacketL(aMessage);
+            break;
+        
+        case NRequest::EWaitingForNotification: // 0:&sizePckg
+            HandleWaitingForNotificationL(aMessage);
+            break;
+        
+        case NRequest::ECancelWaitingForNotification:
+            HandleCancelWaitingForNotification(aMessage);
+            break;
+
+        default:
+        	TRACE( _L("CPresenceCacheSession::ServiceL - default"));
+            aMessage.Complete(KErrArgument);
+            break;
+        }
+    iServer.StartExpiryCheck();
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandlePrepReadPresenceInfoSyncL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandlePrepReadPresenceInfoSyncL( const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandlePrepReadPresenceInfoSyncL - begin"));
+
+    TInt sizeOfReturnPacket(NULL);
+ 
+    // unpacking identity
+    const TInt pckSize = aMessage.GetDesLengthL(1);
+    HBufC* idPack = HBufC::NewLC( pckSize );
+    TPtr paramPckPtr = idPack->Des();    
+    aMessage.ReadL( 1, paramPckPtr );
+    
+    TPtrC serviceName = GetServiceName( paramPckPtr );  
+    TPtrC identity( paramPckPtr ); 
+    
+    // now processing
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    MPresenceBuddyInfo2* buddyPresenceInfo(NULL);
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    
+    TRACE_1( _L("_______serviceCount[%d]"), serviceCount);
+    
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        if (!(serviceName.CompareF( (iServer.iPresenceCache[i])->ServiceName())))
+            {
+            buddyStore = (iServer.iPresenceCache[i])->FindAndGet(identity);
+            if(buddyStore)
+                buddyPresenceInfo = buddyStore->PresenceBuddyInfo();
+            break;
+            }
+        }
+    
+    CleanupStack::PopAndDestroy(idPack);
+    
+    TInt err = KErrNotFound;
+    
+    TRACE_1( _L("_______buddyPresenceInfo[%d]"), buddyPresenceInfo);
+    if (buddyPresenceInfo) // if found
+        {
+        if(iDataPack)
+            delete iDataPack; iDataPack=NULL;
+        iDataPack = PackPresenceInfoLC(*buddyPresenceInfo);
+        CleanupStack::Pop(iDataPack);
+        sizeOfReturnPacket = (iDataPack->Des()).Size();
+        err = KErrNone;
+        }
+    
+    TPckgBuf<TInt> p(sizeOfReturnPacket);
+    aMessage.WriteL(2,p);            
+    aMessage.Complete(err);
+    TRACE( _L("CPresenceCacheSession::HandlePrepReadPresenceInfoSyncL - end"));
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleGetLastPreparedPacketL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleGetLastPreparedPacketL( const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleGetLastPreparedPacketL() - begin"));
+    if(iDataPack)
+        aMessage.WriteL(0, *(iDataPack));
+    aMessage.Complete(KErrNone);   
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleGetLastPreparedAsyncPacketL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleGetLastPreparedAsyncPacketL( const RMessage2& aMessage )
+    {
+    if(iDataPackAsync)
+        aMessage.WriteL(0, *(iDataPackAsync));
+    aMessage.Complete(KErrNone);   
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleWritePresenceInfoSyncL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleWritePresenceInfoSyncL(const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleWritePresenceInfoSyncL - begin"));
+    TInt err(KErrNone);
+    const TInt pckSize = aMessage.GetDesLengthL(0);
+    if(iDataPack)
+        delete iDataPack; iDataPack=NULL;
+    iDataPack = HBufC8::NewL( pckSize );
+    TPtr8 paramPckPtr = iDataPack->Des();
+    aMessage.ReadL( 0, paramPckPtr );
+    
+    MPresenceBuddyInfo2* buddypresenceInfo = MPresenceBuddyInfo2::NewLC();          
+    TCacheObjectPacker< MPresenceBuddyInfo2 >::UnPackL(*buddypresenceInfo, *iDataPack);        
+    err = TryWriteBuddyToCacheL(buddypresenceInfo);
+    
+    if(err==KErrNone || err == KErrNoMemory)  //ownership  transferred
+        {
+        CleanupStack::Pop();       //buddypresenceInfo
+        }
+    else       //KErrGeneral, ownership not transferred
+        {
+        CleanupStack::PopAndDestroy();
+        }
+    aMessage.Complete(err);
+    TRACE( _L("CPresenceCacheSession::HandleWritePresenceInfoSyncL - end"));
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandlePrepReadAllBuddiesPresenceInService()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandlePrepReadAllBuddiesPresenceInService
+                                                        (const RMessage2& aMessage )
+    {
+    if(iActiveHelper->IsActive())
+        aMessage.Complete(KErrServerBusy);
+    else
+        {
+        iMessage = aMessage;
+        
+        iAsyncReq = NRequest::EPrepReadAllBuddiesPresenceInService;
+        iActiveHelper->Start();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::ReadAllBuddiesPresenceInServiceL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::ReadAllBuddiesPresenceInServiceL()
+    {
+    const TInt pckSize = iMessage.GetDesLengthL(0);
+    HBufC* serviceName = HBufC16::NewLC( pckSize );
+    TPtr16 paramPckPtr = serviceName->Des();
+    iMessage.ReadL( 0, paramPckPtr );
+    
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    CPresenceCacheServiceStore* serviceStore(NULL);
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    MPresenceBuddyInfo2* presBuddyInfo(NULL);
+    TInt presCount(0);
+    TInt count(0);
+    
+    RPointerArray<MPresenceBuddyInfo2> tempArray;
+    CleanupClosePushL( tempArray );
+        
+    for (TInt i=0; i<serviceCount; i++)
+        {
+        serviceStore = iServer.iPresenceCache[i];
+        if (!(serviceName->Des().CompareF( serviceStore->ServiceName())))
+            {
+            presCount = serviceStore->PresenceCount();
+            // if it has presences
+            if (presCount)
+                {
+                count = serviceStore->Count();
+                for (TInt j=0; j<count; j++)
+                    {
+                    buddyStore = serviceStore->GetObjectCollection()[j];
+                    presBuddyInfo = buddyStore->PresenceBuddyInfo();
+                    if (presBuddyInfo)
+                        {
+                        tempArray.AppendL( presBuddyInfo );
+                        }
+                    }                  
+                }
+            break;
+            }
+        }
+        
+    TInt size(KErrNotFound); // this may also indicate error to client if negative
+    if ( tempArray.Count() ) // if found
+        {
+        if(iDataPackAsync)
+            delete iDataPackAsync; iDataPackAsync = NULL;
+        iDataPackAsync = TPresenceArrayPacker::PackArrayL( tempArray );    
+        size = (iDataPackAsync->Des()).Size();
+        }
+    
+    CleanupStack::PopAndDestroy( ); // tempArray    
+    CleanupStack::PopAndDestroy(serviceName);
+    iAsyncReq = NRequest::ENoRequestMade;
+    iMessage.Complete(size);    
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::TryWriteBuddyToCache()
+// ---------------------------------------------------------------------------
+//
+TInt CPresenceCacheSession::TryWriteBuddyToCacheL(MPresenceBuddyInfo2* aBuddyPresInfo)
+    {
+    if (!aBuddyPresInfo)
+        return KErrArgument;
+    
+    TPtrC serviceName = GetServiceName( aBuddyPresInfo->BuddyId() );
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    
+    for (TInt i=0; i<serviceCount; i++)
+        {
+        CPresenceCacheServiceStore* serviceStore = iServer.iPresenceCache[i];
+        if ( serviceName.CompareF( serviceStore->ServiceName() ) == 0)
+            {
+            buddyStore = serviceStore->AddOrReplacePresenceL(aBuddyPresInfo);
+            break;
+            }
+        }
+    if (!buddyStore) // if not written
+        {
+        CPresenceCacheServiceStore* newServiceStore = CPresenceCacheServiceStore::NewLC();
+        newServiceStore->SetServiceNameL(serviceName);
+        buddyStore = newServiceStore->AddOrReplacePresenceL(aBuddyPresInfo);
+        (iServer.iPresenceCache).Append(newServiceStore); //ownership transferred
+        CleanupStack::Pop(newServiceStore);
+        }
+        
+    TInt err = KErrGeneral;
+    if (buddyStore)
+        {
+        TRAP( err, NotifyAllSubscribersL(buddyStore) );
+        if (err != KErrNone && err != KErrNoMemory)
+            {
+            User::LeaveIfError(err);
+            }
+        
+        // reset expiry time stamp
+        PresenceCacheBuddyUtils::ResetBuddyInfoTimeStamp( *aBuddyPresInfo );
+        }
+    return err;
+    }
+    
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleCancel()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleCancel(const RMessage2& aMessage )
+    {
+    if (iActiveHelper->IsActive())
+        iActiveHelper->Cancel(); //see also iActiveHelper->DoCancel()
+    aMessage.Complete(KErrNotFound);
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleBuddyCountInAllServicesL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleBuddyCountInAllServicesL(const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleBuddyCountInAllServices - begin"));
+    TInt count(NULL);
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        count = (count) + ((iServer.iPresenceCache[i])->PresenceCount());
+        }
+    
+    TPckgBuf<TInt> p(count);
+    aMessage.WriteL(0,p);               
+    aMessage.Complete(KErrNone);
+    TRACE( _L("CPresenceCacheSession::HandleBuddyCountInAllServices - end"));
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleBuddyCountInServiceL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleBuddyCountInServiceL(const RMessage2& aMessage )
+    {
+    TInt count(NULL);
+    
+    const TInt pckSize = aMessage.GetDesLengthL(1);
+    HBufC* serviceName = HBufC16::NewLC( pckSize );
+    TPtr16 paramPckPtr = serviceName->Des();
+    aMessage.ReadL( 1, paramPckPtr );
+    
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    TInt err(KErrNotFound);
+    
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        if (!(serviceName->Des().CompareF((iServer.iPresenceCache[i])->ServiceName())))
+            {
+            count = ((iServer.iPresenceCache[i])->PresenceCount());
+            err = KErrNone;
+            break;
+            }
+        }
+    
+    CleanupStack::PopAndDestroy(serviceName);
+    TPckgBuf<TInt> p(count);
+    aMessage.WriteL(0,p);
+    aMessage.Complete(err);    
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleDeleteServiceL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleDeleteServiceL(const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleDeleteServiceL - begin"));
+    TInt err(KErrNotFound);
+        
+    const TInt pckSize = aMessage.GetDesLengthL(0);
+    HBufC* serviceName = HBufC16::NewLC( pckSize );
+    TPtr16 paramPckPtr = serviceName->Des();
+    aMessage.ReadL( 0, paramPckPtr );
+    
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    TInt buddyCount(NULL);
+    
+    TRACE_1( _L("_______serviceCount[%d]"), serviceCount);
+    for(TInt i=serviceCount-1; i >= 0; i--)
+        {
+        if (!(serviceName->Des().CompareF((iServer.iPresenceCache[i])->ServiceName())))
+            {
+            (iServer.iPresenceCache[i])->RemoveAllPresences();
+            buddyCount = (iServer.iPresenceCache[i])->GetObjectCollection().Count();
+            TRACE_1( _L("_______buddyCountAfter[%d]"), buddyCount);
+            
+            //if there are no buddies left in this service delete this whole service
+            if (buddyCount == 0)
+                {
+                delete iServer.iPresenceCache[i];
+                iServer.iPresenceCache.Remove(i);
+                }
+                
+            //inform all subscribers
+            for(TInt j=0; j < buddyCount; j++)
+                {
+                NotifyAllSubscribersL((iServer.iPresenceCache[i])->GetObjectCollection()[j]);
+                }
+            err = KErrNone;
+            // break;
+            }
+        }
+    CleanupStack::PopAndDestroy(serviceName);
+    aMessage.Complete(err);
+    TRACE( _L("CPresenceCacheSession::HandleDeleteServiceL - end"));
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleDeletePresenceL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleDeletePresenceL(const RMessage2& aMessage )
+    {
+    const TInt pckSize = aMessage.GetDesLengthL(0);
+    HBufC* idPack = HBufC::NewLC( pckSize );
+    TPtr paramPckPtr = idPack->Des();
+    aMessage.ReadL( 0, paramPckPtr );
+    TInt err(KErrNotFound);
+    TInt buddyCount(NULL);
+        
+    TPtrC serviceName = GetServiceName( paramPckPtr );  
+    TPtrC identity( paramPckPtr );     
+            
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        if( !((iServer.iPresenceCache[i])->ServiceName()).CompareF(serviceName) )
+            {
+            buddyStore = (iServer.iPresenceCache[i])->FindAndRemove( identity,err);
+            
+            buddyCount = (iServer.iPresenceCache[i])->GetObjectCollection().Count();
+            TRACE_1( _L("_______buddyCountAfter[%d]"), buddyCount);
+            
+            //if there are no buddies left in this service delete this whole service
+            if(buddyCount==0)
+                {
+                delete iServer.iPresenceCache[i];
+                iServer.iPresenceCache.Remove(i);
+                }
+            break;
+            }
+        }
+
+    CleanupStack::PopAndDestroy(idPack);
+    aMessage.Complete(err);
+    
+    if(buddyStore) // if subscribers
+        NotifyAllSubscribersL(buddyStore);
+    }
+    
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleGetServiceCountL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleGetServiceCountL(const RMessage2& aMessage )
+    {
+    // iLastServiceCount is also used for mem aloc by client before calling
+    // GetAllServices
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    iLastServiceCount = 0;
+    TRACE_1( _L("CPresenceCacheSession::HandleGetServiceCount realcount[%d]- end"),serviceCount);
+    for(TInt i=0;i<serviceCount;i++)
+        {
+        if((iServer.iPresenceCache[i])->PresenceCount())
+            iLastServiceCount++;
+        }
+
+    TPckgBuf<TInt> p(iLastServiceCount);
+    aMessage.WriteL(0,p);
+    aMessage.Complete(KErrNone);
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleGetAllServicesL()
+// ---------------------------------------------------------------------------
+//
+/*
+void CPresenceCacheSession::HandleGetAllServicesL(const RMessage2& aMessage )   
+    {
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    TInt size(NULL);
+    
+    if(serviceCount)
+    	{
+        CArrayFixFlat<TUid>* services = new (ELeave) CArrayFixFlat<TUid>(1);
+        CleanupStack::PushL(services);
+    	
+    	for(TInt i=0; i<serviceCount; i++)
+	        {
+	        if((iServer.iPresenceCache[i])->PresenceCount())
+	            services->AppendL((iServer.iPresenceCache[i])->Service());
+	        }
+	    
+	    if (iDataPack)
+	        {
+	        delete iDataPack; iDataPack = NULL;
+	        }
+	    iDataPack = PackServicesL(services);
+	    CleanupStack::PopAndDestroy(services);
+	    size = (iDataPack->Des()).Size();
+    	}
+    aMessage.Complete(size);
+    }*/
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleWritePresenceInfoAsyncL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleWritePresenceInfoAsyncL(const RMessage2& aMessage )
+    {
+    if(iActiveHelper->IsActive())
+        {
+        aMessage.Complete(KErrServerBusy);
+        return;        
+        }
+    iMessage = aMessage;
+           
+    const TInt pckSize = aMessage.GetDesLengthL(0);
+    if(iDataPackAsync)
+        delete iDataPackAsync; iDataPackAsync = NULL;
+    iDataPackAsync = HBufC8::NewL( pckSize );
+    TPtr8 paramPckPtr = iDataPackAsync->Des();
+    aMessage.ReadL( 0, paramPckPtr );  
+    
+    TPresenceArrayPacker::UnPackArrayL( iBuddypresInfoList,*iDataPackAsync  );
+        
+    iAsyncReq = NRequest::EWritePresenceInfoAsync;
+    iActiveHelper->Start();
+    return;          
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::WritePresenceInfoAsyncL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::WritePresenceInfoAsyncL()
+    {
+    TInt err(KErrNone);
+    TInt thisTimeWrites(0);
+    
+    // This routine reads data from iBuddypresInfoList and tries to write 
+    // data to cache on each runl cycle. It writes either KMaxWriteEachCycle 
+    // times, or upto data is finnished. After data is written KMaxWriteEachCycle
+    // times and still more data is left, it makes this class active so that this
+    // function is again called on next RunL.
+    
+    while (iBuddypresInfoList.Count())
+        {
+        err = TryWriteBuddyToCacheL( iBuddypresInfoList[0]);        
+        if (err == KErrNone || err == KErrNoMemory)       // ownership transferred
+            {
+            iBuddypresInfoList.Remove( 0 );            
+            }
+        else        
+            {
+            iBuddypresInfoList.ResetAndDestroy();            
+            break; 
+            }
+        thisTimeWrites++;    
+        if(thisTimeWrites == NConstants::KMaxWriteEachCycle) // this times writes are over
+            {
+            if(iActiveHelper->IsActive())// unusual condition
+                {
+                err = KErrGeneral;
+                break;
+                }
+            iActiveHelper->Start();
+            return; // set for next time writing.
+            }
+       }
+              
+    // if we able to come out of while loop either writing is complete or
+    // there was some error while writing, in both cases finnish writing
+    iAsyncReq = NRequest::ENoRequestMade;
+    iMessage.Complete(err);
+    return;
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleSubscribeBuddyPresenceChangeL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleSubscribeBuddyPresenceChangeL
+                                                (const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleSubscribeBuddyPresenceChange - begin"));
+
+    // Extract info from message
+    const TInt pckSize = aMessage.GetDesLengthL(1);
+    HBufC* idPack = HBufC::NewLC( pckSize );
+    TPtr paramPckPtr = idPack->Des();
+    aMessage.ReadL( 1, paramPckPtr );
+    
+    TPtrC identity = paramPckPtr;
+    TPtrC serviceName = GetServiceName( identity );
+    
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    CPresenceCacheServiceStore* serviceStore(NULL);
+    
+    TInt err(KErrNone);
+    
+    // now processing
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    
+    TRACE_1( _L("_______serviceCount[%d]"), serviceCount);
+    
+    for (TInt i=0; i<serviceCount; i++)
+        {
+        if (!(serviceName.CompareF((iServer.iPresenceCache[i])->ServiceName())))
+            {
+            serviceStore = iServer.iPresenceCache[i];
+            buddyStore = (iServer.iPresenceCache[i])->FindAndGet(identity);
+            break;
+            }
+        }
+        
+    if (!buddyStore) // if buddy was not found, create and add it
+        {
+        if (!serviceStore) //if service was also not found, create it
+            {
+            serviceStore = CPresenceCacheServiceStore::NewLC();
+            serviceStore->SetServiceNameL(serviceName);
+            (iServer.iPresenceCache).Append(serviceStore); //ownership transferred
+            CleanupStack::Pop(serviceStore);  
+            }
+        else
+            {            
+            }
+        buddyStore = CPresenceCacheBuddyStore::NewLC(serviceStore,identity);
+        err = serviceStore->AddBlind(buddyStore); //ownership transferred
+        CleanupStack::Pop(buddyStore);
+        } 
+    else
+        {
+        }
+    
+    CleanupStack::PopAndDestroy(idPack);
+    
+    TRACE_1( _L("buddyStore[%d]"), buddyStore);
+
+    buddyStore->AddSubscribedSession(this);
+    if (iSubscribedStores.Find(buddyStore) < 0) //if session not already there
+        iSubscribedStores.Append(buddyStore);
+    
+    aMessage.Complete(err); // there shouldnt be any errors
+    TRACE( _L("CPresenceCacheSession::HandleSubscribeBuddyPresenceChange - end"));
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleUnSubscribeBuddyPresenceChangeL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleUnSubscribeBuddyPresenceChangeL
+                                                (const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleUnSubscribeBuddyPresenceChange - begin"));
+
+    // Extract info from message
+    const TInt pckSize = aMessage.GetDesLengthL(1);
+    HBufC* idPack = HBufC::NewLC( pckSize );
+    TPtr paramPckPtr = idPack->Des();
+    aMessage.ReadL( 1, paramPckPtr );
+    TInt err(KErrNotFound);
+    TPtrC identity = paramPckPtr;        
+    TPtrC serviceName = GetServiceName(identity);
+        
+    // now processing
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    
+    TRACE_1( _L("_______serviceCount[%d]"), serviceCount);
+    
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        if (!(serviceName.CompareF((iServer.iPresenceCache[i])->ServiceName())))
+            {
+            buddyStore = (iServer.iPresenceCache[i])->FindAndGet(identity);
+            break;
+            }
+        }
+    
+    CleanupStack::PopAndDestroy(idPack);
+    
+    TRACE_1( _L("buddyStore[%d]"), buddyStore);
+    if(buddyStore) // if found
+        {
+        buddyStore->RemoveSubscribedSession(this);
+		
+        const TInt buddyStoreIndex = iSubscribedStores.Find(buddyStore);
+        if ( KErrNotFound != buddyStoreIndex )
+            {
+            iSubscribedStores.Remove(buddyStoreIndex);
+            }
+        err = KErrNone;
+        }
+    
+    aMessage.Complete(err);
+    TRACE_1( _L("CPresenceCacheSession::HandleUnSubscribeBuddyPresenceChange (%d) - end"),err);
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleGetLastNotifiedtPacketL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleGetLastNotifiedtPacketL(const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleGetLastNotifiedtPacketL() - begin"));
+    
+    SendNextEventL( aMessage );
+    
+    aMessage.Complete(KErrNone); 
+    
+    SendNextEventNotificationL();
+        
+    TRACE( _L("CPresenceCacheSession::HandleGetLastNotifiedtPacketL() - end"));    
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleWaitingForNotificationL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleWaitingForNotificationL(const RMessage2& aMessage )
+    {
+    iMessageForNoti = aMessage;
+    SendNextEventNotificationL( );
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleCancelWaitingForNotification()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleCancelWaitingForNotification
+                                                    (const RMessage2& aMessage )
+    {
+    aMessage.Complete(KErrNone);
+    if(!iMessageForNoti.IsNull())
+        iMessageForNoti.Complete(KErrCancel);
+    EmptyNotificationQueue();    
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::NotifyPresenceChangeL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::NotifyPresenceChangeL(
+    const MPresenceBuddyInfo2* aPresenceBuddyInfo )  
+    {
+    TRACE( _L("CPresenceCacheSession::NotifyPresenceChangeL() - begin"));
+    TInt sizeOfReturnPacket(NULL);
+    
+    if ( !aPresenceBuddyInfo)
+        {        
+        return;
+        }
+
+    HBufC8* msg = PackBuddyPresenceInfoLC(aPresenceBuddyInfo);        
+    AddIntoQueueL( msg );
+    // ownership is taken
+    CleanupStack::Pop( msg );
+        
+    SendNextEventNotificationL( );
+    
+    TRACE( _L("CPresenceCacheSession::NotifyPresenceChangeL - end"));
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::NotifyAllSubscribersL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::NotifyAllSubscribersL
+                                        (CPresenceCacheBuddyStore* aBuddyStore)
+    {
+    TRACE( _L("CPresenceCacheSession::NotifyAllSubscribers() - begin"));
+    if (!aBuddyStore)
+        return;
+    TInt subsCount = aBuddyStore->GetSubscribedSessions().Count();
+    TRACE_1( _L("_______total subscribed sessions[%d]"), subsCount);
+    TBool ownBuddyInfo(EFalse);
+    const MPresenceBuddyInfo2* buddyInfo;
+    
+    if (subsCount) // start processing if there are subscribers
+        {
+        //if presence has been deleted we need to identity and service id in the packed
+        //which will be sent to clients
+        if (!(aBuddyStore->PresenceBuddyInfo()))
+            {           
+            MPresenceBuddyInfo2* buddyInfoTemp =  MPresenceBuddyInfo2::NewLC();
+            buddyInfoTemp->SetIdentityL( aBuddyStore->BuddyId() );
+            ownBuddyInfo = ETrue;
+            buddyInfo = buddyInfoTemp;
+            }
+        else
+            {
+            buddyInfo = aBuddyStore->PresenceBuddyInfo();  
+            }
+            
+        CPresenceCacheSession* session(NULL);
+        for (TInt i=0;i<subsCount;i++)
+            {
+            session = aBuddyStore->GetSubscribedSessions()[i];
+            if (iServer.SessionExists(session))
+                {
+                TRACE_1( _L("_______valid session notified[%d]"), session);
+                session->NotifyPresenceChangeL(buddyInfo);
+                }
+            else
+                {
+                aBuddyStore->RemoveSubscribedSession(session);
+                subsCount--;//substract this removed session from total count
+                i--;
+                TRACE_1( _L("_______invalid session removed[%d]"), session);
+                }    
+            }
+        }
+        
+    if (ownBuddyInfo)
+        CleanupStack::PopAndDestroy(1); //buddyInfoTemp
+    TRACE( _L("CPresenceCacheSession::NotifyAllSubscribers() - end"));
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::GetServiceName()
+// ---------------------------------------------------------------------------
+//
+TPtrC CPresenceCacheSession::GetServiceName(const TDesC& aXspId)
+    {
+    _LIT(KColon, ":");
+    TInt pos = aXspId.Find(KColon);
+    TPtrC serviceName;
+    if(pos>0) // if colon found and there is something before colon, i.e. xsp id
+        {
+        serviceName.Set(aXspId.Left(pos));
+        }
+    else
+        serviceName.Set(TPtrC());
+    return serviceName;
+    }
+        
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::Cancel()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::Cancel()
+    {
+    if (iAsyncReq != NRequest::ENoRequestMade)
+        {
+        iMessage.Complete(KErrCancel);
+        iAsyncReq = NRequest::ENoRequestMade;
+        }
+    return;   
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::PackPresenceDocLC()
+// ---------------------------------------------------------------------------
+//
+HBufC8* CPresenceCacheSession::PackPresenceInfoLC(const MPresenceBuddyInfo2& aPresInfo)
+    {
+    HBufC8* pack = TCacheObjectPacker< MPresenceBuddyInfo2 >::PackL( aPresInfo );    
+    CleanupStack::PushL( pack );
+    return pack;
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::PackBuddyPresenceInfoLC()
+// ---------------------------------------------------------------------------
+//
+HBufC8* CPresenceCacheSession::PackBuddyPresenceInfoLC(
+    const MPresenceBuddyInfo2* aBuddyPresInfo )
+    {
+    HBufC8* pack(NULL);
+    if ( aBuddyPresInfo )
+        {
+        pack = TCacheObjectPacker< const MPresenceBuddyInfo2>::PackL( *aBuddyPresInfo );
+        CleanupStack::PushL( pack );
+        }
+
+    return pack;
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::CPresenceCacheSession()
+// ---------------------------------------------------------------------------
+//
+CPresenceCacheSession::CPresenceCacheSession( CPresenceCacheServer& aServer )
+                                                        : iServer( aServer ),
+                                                        iLastServiceCount(0)
+    {
+    TRACE( _L("CPresenceCacheSession::CPresenceCacheSession()"));
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::ConstructL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::ConstructL()
+    {
+    iActiveHelper = CCacheSessionActiveHelper::NewL(this);    
+    iServer.IncrementSessions();
+    return;
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::RemoveMySubscriptions()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::RemoveMySubscriptions()
+    {
+    TInt count = iSubscribedStores.Count();
+    for(TInt i=0;i<count;i++)
+        {
+        // it can be assumed that store is alive, since it won't be deleted
+        // until there is any session subscribed to it
+        (iSubscribedStores[i])->RemoveSubscribedSession(this);
+        }
+    }
+
+// ----------------------------------------------------
+// 
+void CPresenceCacheSession::EmptyNotificationQueue()
+    {
+    const TInt count = iNotifyEvents.Count();
+    for( TInt i = 0;i < count;i++ )
+        {
+        CPresenceCacheEvent* event( iNotifyEvents[0] );
+        iNotifyEvents.Remove( 0 );
+        delete event;
+        event = NULL;
+        }
+    }
+
+// ----------------------------------------------------
+// 
+void CPresenceCacheSession::AddIntoQueueL( HBufC8* aMsg )
+    {
+    TRACE( _L("CPresenceCacheSession::AddIntoQueueL() - begin"));    
+    CPresenceCacheEvent* event = CPresenceCacheEvent::NewL( aMsg );
+    CleanupStack::PushL( event );
+    User::LeaveIfError( iNotifyEvents.Append( event ) );
+    CleanupStack::Pop();  //event
+    TRACE( _L("CPresenceCacheSession::AddIntoQueueL() - end"));    
+    }
+
+// ----------------------------------------------------
+// 
+void CPresenceCacheSession::SendNextEventL( const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::SendNextEventL() - begin"));    
+    
+    if ( iNotifyEvents.Count() > 0 )
+        {
+        CPresenceCacheEvent* event( iNotifyEvents[0] );
+        aMessage.WriteL(0, event->Message());            
+        // aMessage.Complete(KErrNone);       
+        iNotifyEvents.Remove( 0 );
+        delete event;
+        event = NULL;
+        }
+    else
+        {        
+        }
+    
+    TRACE( _L("CPresenceCacheSession::SendNextEventL() - end"));
+    
+    return;
+    }
+
+// ----------------------------------------------------
+// 
+void CPresenceCacheSession::SendNextEventNotificationL( )
+    {
+    TRACE( _L("CPresenceCacheSession::SendNextEventNotificationL() - begin"));
+    
+    TInt sizeOfReturnPacket(NULL);    
+    
+    if ( iNotifyEvents.Count() > 0 && (!iMessageForNoti.IsNull()))
+        {
+        CPresenceCacheEvent* event( iNotifyEvents[0] );
+        if ( !event->NotifySent() )
+            {
+            event->SetNotifySent();              
+            sizeOfReturnPacket = event->Message().Size();
+            TPckgBuf<TInt> p(sizeOfReturnPacket);          
+            iMessageForNoti.WriteL(0,p);            
+            iMessageForNoti.Complete(KErrNone); 
+            }
+        else
+            {
+            // Do not sent twice the same, 
+            // client first refresh notification request and after that gets the last notification packet.
+            }
+        }
+    else
+        {        
+        }
+    
+    TRACE( _L("CPresenceCacheSession::SendNextEventNotificationL() - end"));
+    
+    return;
+    }
+    
+// ---------------------------------------------------------------------------
+// CCacheSessionActiveHelper::NewL()
+// ---------------------------------------------------------------------------
+//
+CCacheSessionActiveHelper* CCacheSessionActiveHelper::NewL
+                                            (CPresenceCacheSession* aSession )
+    {
+    CCacheSessionActiveHelper* self = new(ELeave) CCacheSessionActiveHelper(aSession);
+    CleanupStack::PushL( self );
+    self->ConstructL( );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CCacheSessionActiveHelper::~CCacheSessionActiveHelper()
+// ---------------------------------------------------------------------------
+//
+CCacheSessionActiveHelper::~CCacheSessionActiveHelper( )
+    {
+    Cancel();   
+    }
+
+// ---------------------------------------------------------------------------
+// CCacheSessionActiveHelper::Start()
+// ---------------------------------------------------------------------------
+//
+void CCacheSessionActiveHelper::Start()
+    {
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete(status,KErrNone);
+    SetActive();
+    }
+
+// ---------------------------------------------------------------------------
+// CCacheSessionActiveHelper::CCacheSessionActiveHelper()
+// ---------------------------------------------------------------------------
+//
+CCacheSessionActiveHelper::CCacheSessionActiveHelper(CPresenceCacheSession* aSession ) 
+                                                    : CActive(EPriorityStandard)
+    {
+    iCacheSession = aSession;
+    }
+
+// ---------------------------------------------------------------------------
+// CCacheSessionActiveHelper::RunL()
+// ---------------------------------------------------------------------------
+//
+void CCacheSessionActiveHelper::RunL()
+    {
+    switch (iCacheSession->iAsyncReq)
+        {
+        case NRequest::EWritePresenceInfoAsync:
+            iCacheSession->WritePresenceInfoAsyncL();
+            break;
+
+        case NRequest::EPrepReadAllBuddiesPresenceInService:
+            iCacheSession->ReadAllBuddiesPresenceInServiceL();
+            break;
+
+        case NRequest::ENoRequestMade:
+        default:
+            break;
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+// CCacheSessionActiveHelper::DoCancel()
+// ---------------------------------------------------------------------------
+//
+void CCacheSessionActiveHelper::DoCancel()
+    {
+    iCacheSession->Cancel();
+    }
+
+// ---------------------------------------------------------------------------
+// CCacheSessionActiveHelper::ConstructL()
+// ---------------------------------------------------------------------------
+//
+void CCacheSessionActiveHelper::ConstructL()
+    {
+	CActiveScheduler::Add(this);
+    }
+
+TInt CCacheSessionActiveHelper::RunError(TInt /*aError*/)
+    {
+    iCacheSession->Cancel();    
+    return KErrNone;
+    }
+
+
+// End of File