diff -r 000000000000 -r e686773b3f54 presencecache/presencecacheserver2/src/presencecachesession.cpp --- /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 + +#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; iServiceName()))) + { + 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 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 tempArray; + CleanupClosePushL( tempArray ); + + for (TInt i=0; iDes().CompareF( serviceStore->ServiceName()))) + { + presCount = serviceStore->PresenceCount(); + // if it has presences + if (presCount) + { + count = serviceStore->Count(); + for (TInt j=0; jGetObjectCollection()[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; iServiceName() ) == 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; iPresenceCount()); + } + + TPckgBuf 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; iDes().CompareF((iServer.iPresenceCache[i])->ServiceName()))) + { + count = ((iServer.iPresenceCache[i])->PresenceCount()); + err = KErrNone; + break; + } + } + + CleanupStack::PopAndDestroy(serviceName); + TPckgBuf 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; iServiceName()).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;iPresenceCount()) + iLastServiceCount++; + } + + TPckgBuf 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* services = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(services); + + for(TInt i=0; iPresenceCount()) + 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; iServiceName()))) + { + 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; iServiceName()))) + { + 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;iGetSubscribedSessions()[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;iRemoveSubscribedSession(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 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