ximpfw/presence/srcpresencecache/presencecacheserver/presencecachesession.cpp
changeset 0 e6b17d312c8b
child 21 5872ac9a5671
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ximpfw/presence/srcpresencecache/presencecacheserver/presencecachesession.cpp	Thu Dec 17 08:54:49 2009 +0200
@@ -0,0 +1,1156 @@
+/*
+* Copyright (c) 2007, 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 <presenceobjectfactory.h>
+#include <personpresenceinfo.h>
+#include <presencebuddyinfo.h>
+#include <presencebuddyinfolist.h>
+#include <presenceinfofieldcollection.h>
+
+#include "presencecachesession.h"
+#include "presencecacheserver.h"
+#include "ximptrace.h"
+#include "ximpobjecthelpers.h"
+#include "presenceinfoimp.h"
+#include "presencebuddyinfolistimp.h"
+#include "presencebuddyinfoimp.h"
+#include "ximpidentityimp.h"
+
+#include "presencecacheservicestore.h"
+#include "presencecachebuddystore.h"
+
+//Include Cache server namespace
+using namespace NCacheSrv;
+
+
+// ---------------------------------------------------------------------------
+// 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;
+    if(iDataPackNotifier)
+        delete iDataPackNotifier;
+    if(iBuddypresInfoList)
+        delete iBuddypresInfoList;
+    if(iActiveHelper)
+        delete iActiveHelper;
+    iServer.DecrementSessions();
+    RemoveMySubscriptions(); // remove all subscriptions subscribed by this session
+    iSubscribedStores.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:
+            HandleBuddyCountInAllServices(aMessage);
+            break;
+            
+        case NRequest::EBuddyCountInService:
+            HandleBuddyCountInService(aMessage);
+            break;
+            
+        case NRequest::EGetServiceCount:
+            HandleGetServiceCount(aMessage);
+            break;
+            
+        case NRequest::EDeleteService:
+            HandleDeleteService(aMessage);
+            break;
+            
+        case NRequest::EDeletePresence:
+            HandleDeletePresence(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
+            HandleSubscribeBuddyPresenceChange(aMessage);
+            break;
+        
+        case NRequest::EUnSubscribeBuddyPresenceChange: // 0:aService.iUid, 1:myIdPack
+            HandleUnSubscribeBuddyPresenceChange(aMessage);
+            break;
+        
+        case NRequest::EGetLastNotifiedtPacket: // 0:&ptrBuf
+            HandleGetLastNotifiedtPacketL(aMessage);
+            break;
+        
+        case NRequest::EWaitingForNotification: // 0:&sizePckg
+            HandleWaitingForNotification(aMessage);
+            break;
+        
+        case NRequest::ECancelWaitingForNotification:
+            HandleCancelWaitingForNotification(aMessage);
+            break;
+
+        default:
+        	TRACE( _L("CPresenceCacheSession::ServiceL - default"));
+            aMessage.Complete(KErrArgument);
+            break;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandlePrepReadPresenceInfoSyncL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandlePrepReadPresenceInfoSyncL( const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandlePrepReadPresenceInfoSyncL - begin"));
+
+    TInt sizeOfReturnPacket(NULL);
+ 
+    // unpacking identity
+    const TInt pckSize = aMessage.GetDesLengthL(1);
+    HBufC8* idPack = HBufC8::NewLC( pckSize );
+    TPtr8 paramPckPtr = idPack->Des();
+    aMessage.ReadL( 1, paramPckPtr );
+    CXIMPIdentityImp* identity = CXIMPIdentityImp::NewLC();
+    TXIMPObjectPacker< CXIMPIdentityImp >::UnPackL(*identity, *idPack);
+    
+    TPtrC serviceName = GetServiceName(identity->Identity());
+    
+    // now processing
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    MPresenceBuddyInfo* buddyPresenceInfo(NULL);
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    
+    TRACE_1( _L("_______serviceCount[%d]"), serviceCount);
+    
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        if (serviceName == (iServer.iPresenceCache[i])->ServiceName())
+            {
+            buddyStore = (iServer.iPresenceCache[i])->FindAndGet(*identity);
+            if(buddyStore)
+                buddyPresenceInfo = buddyStore->PresenceBuddyInfo();
+            break;
+            }
+        }
+    
+    CleanupStack::PopAndDestroy(identity);
+    CleanupStack::PopAndDestroy(idPack);
+    
+    TInt err = KErrNotFound;
+    
+    TRACE_1( _L("_______buddyPresenceInfo[%d]"), buddyPresenceInfo);
+    if(buddyPresenceInfo) // if found
+        {
+        const CPresenceInfoImp* presInfo = 
+            TXIMPGetImpClassOrPanic< const CPresenceInfoImp >::From(*(buddyPresenceInfo->PresenceInfo()));
+        if(iDataPack)
+            delete iDataPack; iDataPack=NULL;
+        iDataPack = PackPresenceInfoLC(*presInfo);
+        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 );
+    
+    CPresenceBuddyInfoImp* buddypresenceInfo = CPresenceBuddyInfoImp::NewLC();
+   
+
+    TXIMPObjectPacker< CPresenceBuddyInfoImp >::UnPackL(*buddypresenceInfo, *iDataPack);
+    
+    err = TryWriteBuddyToCacheL(buddypresenceInfo);
+    
+    if(err==KErrNone) //ownership transferred    
+        CleanupStack::Pop(buddypresenceInfo);
+    else
+        CleanupStack::PopAndDestroy(buddypresenceInfo);    
+    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);
+    CPresenceBuddyInfoListImp* buddyPresenceInfoList(NULL);
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    MPresenceBuddyInfo* presBuddyInfo(NULL);
+    TInt presCount(0);
+    TInt count(0);
+    
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        serviceStore = iServer.iPresenceCache[i];
+        if (serviceName->Des() == serviceStore->ServiceName())
+            {
+            presCount = serviceStore->PresenceCount();
+            // if it has presences
+            if(presCount)
+                {
+                buddyPresenceInfoList = CPresenceBuddyInfoListImp::NewLC(*serviceName);
+                buddyPresenceInfoList->SetOwnObjects(EFalse);
+                count = serviceStore->Count();
+                for(TInt j=0; j<count; j++)
+                    {
+                    buddyStore = serviceStore->GetObjectCollection()[j];
+                    presBuddyInfo = buddyStore->PresenceBuddyInfo();
+                    if(presBuddyInfo)
+                        buddyPresenceInfoList->BlindAddL(presBuddyInfo);    
+                    }
+                }
+            break;
+            }
+        }
+    
+    TInt size(KErrNotFound); // this may also indicate error to client if negative
+    if(buddyPresenceInfoList) // if found
+        {
+        if(iDataPackAsync)
+            delete iDataPackAsync; iDataPackAsync = NULL;
+        iDataPackAsync = TXIMPObjectPacker< CPresenceBuddyInfoListImp>::PackL( *buddyPresenceInfoList);
+        size = (iDataPackAsync->Des()).Size();
+        CleanupStack::PopAndDestroy(buddyPresenceInfoList);
+        }
+    
+    CleanupStack::PopAndDestroy(serviceName);
+    iAsyncReq = NRequest::ENoRequestMade;
+    iMessage.Complete(size);
+    }
+    
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::TryWriteBuddyToCache()
+// ---------------------------------------------------------------------------
+//
+TInt CPresenceCacheSession::TryWriteBuddyToCacheL(MPresenceBuddyInfo* aBuddyPresInfo)
+    {
+    if(!aBuddyPresInfo)
+        return KErrArgument;
+    
+    TPtrC serviceName = GetServiceName(aBuddyPresInfo->BuddyId()->Identity());
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        if (serviceName == (iServer.iPresenceCache[i])->ServiceName())
+            {
+            buddyStore = (iServer.iPresenceCache[i])->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);
+        }
+        
+    if(buddyStore) //  inform to subscribers
+        NotifyAllSubscribersL(buddyStore);
+        
+    return buddyStore ? KErrNone : KErrGeneral;
+    }
+    
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleCancel()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleCancel(const RMessage2& aMessage )
+    {
+    if (iActiveHelper->IsActive())
+        iActiveHelper->Cancel(); //see also iActiveHelper->DoCancel()
+    aMessage.Complete(KErrNotFound);
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleBuddyCountInAllServices()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleBuddyCountInAllServices(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::HandleBuddyCountInService()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleBuddyCountInService(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() == (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::HandleDeleteService()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleDeleteService(const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleDeleteService - 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=0; i<serviceCount; i++)
+        {
+        if (serviceName->Des() == (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::HandleDeleteService - end"));
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleDeletePresence()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleDeletePresence(const RMessage2& aMessage )
+    {
+    const TInt pckSize = aMessage.GetDesLengthL(0);
+    HBufC8* idPack = HBufC8::NewLC( pckSize );
+    TPtr8 paramPckPtr = idPack->Des();
+    aMessage.ReadL( 0, paramPckPtr );
+    TInt err(KErrNotFound);
+    TInt buddyCount(NULL);
+    
+    CXIMPIdentityImp* identity = CXIMPIdentityImp::NewLC();
+    
+    TXIMPObjectPacker< CXIMPIdentityImp >::UnPackL(*identity, *idPack);
+    
+    TPtrC serviceName = GetServiceName(identity->Identity());
+    
+    TInt serviceCount = iServer.iPresenceCache.Count();
+    
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        if(((iServer.iPresenceCache[i])->ServiceName()) == 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(identity);
+    CleanupStack::PopAndDestroy(idPack);
+    aMessage.Complete(err);
+    
+    if(buddyStore) // if subscribers
+        NotifyAllSubscribersL(buddyStore);
+    }
+    
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleGetServiceCount()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleGetServiceCount(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 );
+    
+    if(iBuddypresInfoList)
+        delete iBuddypresInfoList; iBuddypresInfoList = NULL;
+    iBuddypresInfoList = CPresenceBuddyInfoListImp::NewLC(KNullDesC);
+    CleanupStack::Pop(iBuddypresInfoList);
+    
+    TXIMPObjectPacker< CPresenceBuddyInfoListImp >::UnPackL(*iBuddypresInfoList, *iDataPackAsync);
+    
+    iAsyncReq = NRequest::EWritePresenceInfoAsync;
+    iActiveHelper->Start();
+    return;
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::WritePresenceInfoAsyncL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::WritePresenceInfoAsyncL()
+    {
+    TInt err(KErrNone);
+    TInt thisTimeWrites(0);
+    if(!iBuddypresInfoList) // return if this function is wrongly called
+        return;
+    
+    // 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->GetObjectCollection())[0]);
+        if(err==KErrNone) // if no erroe then pop the object from list
+            (iBuddypresInfoList->GetObjectCollection()).Remove(0);
+        else
+            break; // break in case of error
+        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::HandleSubscribeBuddyPresenceChange()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleSubscribeBuddyPresenceChange
+                                                (const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleSubscribeBuddyPresenceChange - begin"));
+
+    // Extract info from message
+    const TInt pckSize = aMessage.GetDesLengthL(1);
+    HBufC8* idPack = HBufC8::NewLC( pckSize );
+    TPtr8 paramPckPtr = idPack->Des();
+    aMessage.ReadL( 1, paramPckPtr );
+    
+    CXIMPIdentityImp* identity = CXIMPIdentityImp::NewLC();
+    
+    TXIMPObjectPacker< CXIMPIdentityImp >::UnPackL(*identity, *idPack);
+    
+    TPtrC serviceName = GetServiceName(identity->Identity());
+    
+    CPresenceCacheBuddyStore* buddyStore(NULL);
+    CPresenceCacheServiceStore* serviceStore(NULL);
+    
+    TInt err(KErrGeneral); // there must not be error in this handler
+                           // but just for debug purpose
+    
+    
+    // now processing
+    TInt serviceCount = iServer.iPresenceCache.Count();
+
+    
+    TRACE_1( _L("_______serviceCount[%d]"), serviceCount);
+    
+    for(TInt i=0; i<serviceCount; i++)
+        {
+        if (serviceName == (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);  
+            }
+        buddyStore = CPresenceCacheBuddyStore::NewLC(serviceStore,identity);
+        err = serviceStore->AddBlind(buddyStore); //ownership transferred
+        CleanupStack::Pop(buddyStore);
+        CleanupStack::Pop(identity);
+        } 
+    else
+        CleanupStack::PopAndDestroy(identity); // since in this case ownership wasnt tranferred
+    
+    CleanupStack::PopAndDestroy(idPack);
+    
+    TRACE_1( _L("buddyStore[%d]"), buddyStore);
+    if(buddyStore) // must be there, just for double check
+        {
+        buddyStore->AddSubscribedSession(this);
+        if(iSubscribedStores.Find(buddyStore) < 0) //if session not already there
+            iSubscribedStores.Append(buddyStore);
+        err = KErrNone;
+        }
+    
+    aMessage.Complete(err); // there shouldnt be any errors
+    TRACE( _L("CPresenceCacheSession::HandleSubscribeBuddyPresenceChange - end"));
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleUnSubscribeBuddyPresenceChange()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleUnSubscribeBuddyPresenceChange
+                                                (const RMessage2& aMessage )
+    {
+    TRACE( _L("CPresenceCacheSession::HandleUnSubscribeBuddyPresenceChange - begin"));
+
+    // Extract info from message
+    const TInt pckSize = aMessage.GetDesLengthL(1);
+    HBufC8* idPack = HBufC8::NewLC( pckSize );
+    TPtr8 paramPckPtr = idPack->Des();
+    aMessage.ReadL( 1, paramPckPtr );
+    TInt err(KErrNotFound);
+    
+    CXIMPIdentityImp* identity = CXIMPIdentityImp::NewLC();
+    
+    TXIMPObjectPacker< CXIMPIdentityImp >::UnPackL(*identity, *idPack);
+    
+    TPtrC serviceName = GetServiceName(identity->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 == (iServer.iPresenceCache[i])->ServiceName())
+            {
+            buddyStore = (iServer.iPresenceCache[i])->FindAndGet(*identity);
+            break;
+            }
+        }
+    
+    CleanupStack::PopAndDestroy(identity);
+    CleanupStack::PopAndDestroy(idPack);
+    
+    TRACE_1( _L("buddyStore[%d]"), buddyStore);
+    if(buddyStore) // if found
+        {
+        buddyStore->RemoveSubscribedSession(this);
+        iSubscribedStores.Remove(iSubscribedStores.Find(buddyStore));
+        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"));
+    if(iDataPackNotifier)
+        aMessage.WriteL(0, *(iDataPackNotifier));
+    aMessage.Complete(KErrNone);
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleWaitingForNotification()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleWaitingForNotification(const RMessage2& aMessage )
+    {
+    iMessageForNoti = aMessage;
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::HandleCancelWaitingForNotification()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::HandleCancelWaitingForNotification
+                                                    (const RMessage2& aMessage )
+    {
+    aMessage.Complete(KErrNone);
+    if(!iMessageForNoti.IsNull())
+        iMessageForNoti.Complete(KErrCancel);
+    }
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::NotifyPresenceChangeL()
+// ---------------------------------------------------------------------------
+//
+void CPresenceCacheSession::NotifyPresenceChangeL(
+                               const CPresenceBuddyInfoImp* aPresenceBuddyInfo)
+    {
+    TRACE( _L("CPresenceCacheSession::NotifyPresenceChangeL() - begin"));
+    TInt sizeOfReturnPacket(NULL);
+    if(aPresenceBuddyInfo && (!iMessageForNoti.IsNull())) // if pointers are valid
+        {
+        if(iDataPackNotifier)
+            delete iDataPackNotifier; iDataPackNotifier=NULL;
+        iDataPackNotifier = PackBuddyPresenceInfoLC(aPresenceBuddyInfo);
+        CleanupStack::Pop(iDataPackNotifier);
+        sizeOfReturnPacket = (iDataPackNotifier->Des()).Size();
+        TPckgBuf<TInt> p(sizeOfReturnPacket);
+        iMessageForNoti.WriteL(0,p);            
+        iMessageForNoti.Complete(KErrNone);
+        TRACE( _L("_______message was valid"));
+        }
+    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 CPresenceBuddyInfoImp* 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()))
+            {
+            CPresenceBuddyInfoImp* buddyInfoTemp = CPresenceBuddyInfoImp::NewLC();
+            MXIMPIdentity* id = CXIMPIdentityImp::NewLC(aBuddyStore->BuddyId()->Identity());
+            buddyInfoTemp->SetBuddyId(id);
+            CleanupStack::Pop(1); //id
+            ownBuddyInfo = ETrue;
+            buddyInfo = buddyInfoTemp;
+            }
+        else
+            {
+            buddyInfo = 
+                TXIMPGetImpClassOrPanic< const CPresenceBuddyInfoImp >::From( *(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 MPresenceInfo& aPresInfo)
+    {
+    const CPresenceInfoImp* tmp =
+        TXIMPGetImpClassOrPanic< const CPresenceInfoImp >::From(aPresInfo);
+    HBufC8* pack = TXIMPObjectPacker< CPresenceInfoImp>::PackL( *tmp);
+    CleanupStack::PushL( pack );
+
+    return pack;
+    }
+    
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::PackBuddyPresenceInfoLC()
+// ---------------------------------------------------------------------------
+//
+HBufC8* CPresenceCacheSession::PackBuddyPresenceInfoLC(
+                                    const CPresenceBuddyInfoImp* aBuddyPresInfo)
+    {
+    HBufC8* pack(NULL);
+    if(aBuddyPresInfo)
+        {
+        //const CPresenceBuddyInfoImp* pifImp = 
+        //    TXIMPGetImpClassOrPanic< const CPresenceBuddyInfoImp >::From( *aBuddyPresInfo );    
+        
+        pack = TXIMPObjectPacker< const CPresenceBuddyInfoImp>::PackL( *aBuddyPresInfo );
+        CleanupStack::PushL( pack );
+        }
+
+    return pack;
+    }
+    
+
+// ---------------------------------------------------------------------------
+// CPresenceCacheSession::PackServicesL()
+// ---------------------------------------------------------------------------
+//
+/*
+HBufC8* CPresenceCacheSession::PackServicesL(CArrayFixFlat<TUid>* aArray )
+	{
+    CBufFlat* packBuf = CBufFlat::NewL( NConstants::KGranularity );
+    CleanupStack::PushL( packBuf );
+
+    RBufWriteStream ws;
+    ws.Open( *packBuf ); // CSI: 65 #
+    CleanupClosePushL( ws );
+
+    // Get count of objects
+    TInt objCount = aArray->Count();
+    // write the count
+    ws.WriteInt32L( objCount );
+    // objects
+    for ( TInt count(0); count < objCount; count++ )
+        {
+        ws<<(aArray->At(count));
+        }
+
+    ws.CommitL();
+    CleanupStack::PopAndDestroy(); //ws
+
+    HBufC8* packBufDesc = packBuf->Ptr(0).AllocL();
+    CleanupStack::PopAndDestroy( packBuf );
+
+    return packBufDesc;
+	}*/
+
+// ---------------------------------------------------------------------------
+// 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);
+        }
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// 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);
+    }
+
+
+// End of File