--- /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