diff -r 000000000000 -r e6b17d312c8b ximpfw/presence/srcpresencecache/presencecacheserver/presencecachesession.cpp --- /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 +#include +#include +#include +#include + +#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; iServiceName()) + { + 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 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; iDes() == 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; jGetObjectCollection()[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; iServiceName()) + { + 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; iPresenceCount()); + } + + TPckgBuf 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; iDes() == (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::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; iDes() == (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;jGetObjectCollection()[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; iServiceName()) == 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;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 ); + + 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; 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); + } + 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; iServiceName()) + { + 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 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;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 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* 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;iRemoveSubscribedSession(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