diff -r d4f567ce2e7c -r 5b6f26637ad3 presencecache/presencecachesymbian/presencecacheclient2/src/presencecacheclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/presencecache/presencecachesymbian/presencecacheclient2/src/presencecacheclient.cpp Tue Aug 31 15:05:21 2010 +0300 @@ -0,0 +1,619 @@ +/* +* 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: Implementation for presence cache client. +* +*/ + +#include +#include + +#include +#include +#include + +#include "presenceobjecthelpers.h" +#include "presencecachedefs2.h" +#include "cacheobjecthelpers.h" +#include "presencecacheclientnotification.h" +#include "presencecacheclient.h" + +//Include Cache server namespace +using namespace NCacheSrv2; + + +// ============================ MEMBER FUNCTIONS ============================= + + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::NewL() +// --------------------------------------------------------------------------- +// +EXPORT_C CPresenceCacheClient* CPresenceCacheClient::NewL() + { + CPresenceCacheClient* self = new( ELeave ) CPresenceCacheClient(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::CreateReaderL() +// --------------------------------------------------------------------------- +// +EXPORT_C MPresenceCacheReader2* MPresenceCacheReader2::CreateReaderL() + { + return CPresenceCacheClient::NewL(); + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::CreateWriterL() +// --------------------------------------------------------------------------- +// +EXPORT_C MPresenceCacheWriter2* MPresenceCacheWriter2::CreateWriterL() + { + return CPresenceCacheClient::NewL(); + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::~CPresenceCacheClient() +// --------------------------------------------------------------------------- +// +CPresenceCacheClient::~CPresenceCacheClient() + { + delete iPresInfoPack; + delete iPresInfoPack16; + delete iNotifyHandler; + Cancel(); + RSessionBase::Close(); + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::CPresenceCacheClient() +// --------------------------------------------------------------------------- +// +CPresenceCacheClient::CPresenceCacheClient(): CActive( EPriorityStandard ), + iWriteHandler(NULL), + iReadHandler(NULL), + iAsyncReq(NRequest::ENoRequestMade) + { + + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::ConstructL() +// --------------------------------------------------------------------------- +// +void CPresenceCacheClient::ConstructL() + { + User::LeaveIfError( Connect() ); + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CPresenceCacheClient::Connect() +// Connects to the server and create a session. +// ----------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::Connect() + { + TInt error = StartServer(); + + if ( KErrNone == error ) + { + error = CreateSession( NName::KSymbianServer, + Version(), + NRequest::KMsgSlotCount ); + } + return error; + } + +// ---------------------------------------------------- +// CPresenceCacheClient::StartServer +// +// ---------------------------------------------------- +// +TInt CPresenceCacheClient::StartServer() + { + TInt result; + TRequestStatus status = KRequestPending; + + TFindServer findCacheServer( NName::KSymbianServer ); + TFullName name; + + result = findCacheServer.Next( name ); + if ( result == KErrNone ) + { + // Server already running + return KErrNone; + } + + RProcess server; + result = server.Create( NName::KExecutable, KNullDesC ); + if( result != KErrNone ) + return result; + server.Rendezvous( status ); + status != KRequestPending ? server.Kill( 0 ) : server.Resume(); + //Wait for start or death + User::WaitForRequest( status ); + result = server.ExitType() == EExitPanic ? KErrGeneral : status.Int(); + server.Close(); + + return result; + } + +// ----------------------------------------------------------------------------- +// CPresenceCacheClient::Version() +// Gets the version number. +// ----------------------------------------------------------------------------- +// +TVersion CPresenceCacheClient::Version() const + { + return( TVersion( NVersion::KMajor, + NVersion::KMinor, + NVersion::KBuild ) ); + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::PresenceInfoLC() +// --------------------------------------------------------------------------- +// +MPresenceBuddyInfo2* CPresenceCacheClient::PresenceInfoLC(const TDesC& aIdentity) + { + MPresenceBuddyInfo2* presInfo(NULL); + + if ( !ValidateXspId( aIdentity ) ) + return presInfo; + + TInt sizeOfPresInfo(0); + TPckgBuf sizePckg; + + // Package message arguments before sending to the server + TIpcArgs args; + args.Set(1, &aIdentity); + args.Set(2, &sizePckg); + + // We will get either size(+ve) or error code(+ve) after this call + TInt err = SendReceive( NRequest::EPrepReadPresenceInfoSync, args ); + + if ( err != KErrNone && err != KErrNotFound ) + { + User::Leave( err ); + } + sizeOfPresInfo = sizePckg(); + + if ( sizeOfPresInfo && (err==KErrNone) ) // If found + { + presInfo = MPresenceBuddyInfo2::NewLC(); + HBufC8* presInfoDes = HBufC8::NewLC(sizeOfPresInfo); + TPtr8 ptrBuf( presInfoDes->Des() ); + + SendReceive( NRequest::EGetLastPreparedPacket, TIpcArgs(&ptrBuf) ); + + TCacheObjectPacker< MPresenceBuddyInfo2 >::UnPackL( *presInfo, *presInfoDes ); + CleanupStack::PopAndDestroy(presInfoDes); + } + + return presInfo; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::BuddyCountInAllServices() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::BuddyCountInAllServices() + { + TInt buddyCount(0); + TPckgBuf buddyCountPckg; + + // Package message arguments before sending to the server + TIpcArgs args(&buddyCountPckg); + + // This call waits for the server to complete the request before + // proceeding. + TInt err = SendReceive( NRequest::EBuddyCountInAllServices, args ); + buddyCount = buddyCountPckg(); + + return (err<0) ? err : buddyCount; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::BuddyCountInService() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::BuddyCountInService(const TDesC& aServiceName) + { + TInt buddyCount(0); + TPckgBuf buddyCountPckg; + + // Package message arguments before sending to the server + TIpcArgs args(&buddyCountPckg); + args.Set(1, &aServiceName); + + // This call waits for the server to complete the request before + // proceeding. + TInt err = SendReceive( NRequest::EBuddyCountInService, args ); + buddyCount = buddyCountPckg(); + + return (err<0) ? err : buddyCount; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::ServicesCount() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::ServicesCount() + { + TInt serviceCount(0); + TPckgBuf serviceCountPckg; + + // Package message arguments before sending to the server + TIpcArgs args(&serviceCountPckg); + + // This call waits for the server to complete the request before + // proceeding. + TInt err = SendReceive( NRequest::EGetServiceCount, args ); + serviceCount = serviceCountPckg(); + + return (err<0) ? err : serviceCount; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::AllBuddiesPresenceInService() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::AllBuddiesPresenceInService( + const TDesC& aServiceName, + MPresenceCacheReadHandler2* aHandler) + { + if (IsActive()) + return KErrNotReady; + + if (!aHandler || (aServiceName.Length()==NULL) ) + return KErrArgument; + else + iReadHandler = aHandler; + + delete iPresInfoPack16; + iPresInfoPack16 = NULL; + TRAPD( err, iPresInfoPack16 = aServiceName.AllocL()); + if ( err ) + { + return err; + } + + // Package message arguments before sending to the server + TIpcArgs args(iPresInfoPack16); + + // This call is async + SendReceive( NRequest::EPrepReadAllBuddiesPresenceInService, args, iStatus ); + + iAsyncReq = NRequest::EPrepReadAllBuddiesPresenceInService; + + SetActive(); + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::SubscribePresenceBuddyChangeL +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::SubscribePresenceBuddyChangeL( + const TDesC& aIdentity) + { + if ( !ValidateXspId(aIdentity )) + return KErrArgument; + + if ( !iNotifyClient ) + { + return KErrNotReady; + } + + if ( !iNotifyHandler ) + { + iNotifyHandler = CPresenceCacheClientNotification::NewL( *this ); + } + + TInt ret = iNotifyHandler->SubscribePresenceBuddyChangeL( aIdentity ); + return ret; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::UnSubscribePresenceBuddyChangeL +// --------------------------------------------------------------------------- +// +void CPresenceCacheClient::UnSubscribePresenceBuddyChangeL( + const TDesC& aIdentity) + { + if (!ValidateXspId( aIdentity )) + return; + + if ( iNotifyHandler ) + { + iNotifyHandler->UnsubscribePresenceBuddyChangeL( aIdentity); + } + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::SetObserverForSubscribedNotifications +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::SetObserverForSubscribedNotifications( + MPresenceCacheReadHandler2* aHandler) + { + if ( !aHandler ) + { + return KErrArgument; + } + iNotifyClient = aHandler; + return KErrNone; + } + + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::HandlePreparedAllBuddiesPresenceL() +// --------------------------------------------------------------------------- +// +void CPresenceCacheClient::HandlePreparedAllBuddiesPresenceL(TInt aError) + { + TInt status = aError; // size comes in status + + if (!iReadHandler) + { + // this is possible in cancel situation + return; + } + + RPointerArray tempArray; + CleanupClosePushL( tempArray ); + + if (status>0) // if anything found + { + HBufC8* buddyInfosDes = HBufC8::NewLC(status); + TPtr8 ptrBuf( buddyInfosDes->Des() ); + + status = SendReceive( NRequest::EGetLastAsyncPreparedPacket, TIpcArgs(&ptrBuf) ); + + TRAPD( err, TPresenceArrayPacker::UnPackArrayL( tempArray, ptrBuf )); + if ( err ) + { + tempArray.ResetAndDestroy(); + } + CleanupStack::PopAndDestroy(buddyInfosDes); + } + + // Thos takes ownership of the elements in the array + iReadHandler->HandlePresenceReadL(status, tempArray); + CleanupStack::PopAndDestroy( &tempArray ); // Close the array + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::WritePresenceL() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::WritePresenceL( + const MPresenceBuddyInfo2* aPresenceBuddyInfo) + { + if (!aPresenceBuddyInfo) + return KErrArgument; + + if (!ValidateXspId( aPresenceBuddyInfo->BuddyId() )) + return KErrArgument; + + HBufC8* presInfoPack = PackBuddyPresenceInfoLC( aPresenceBuddyInfo ); + + // Package message arguments before sending to the server + TIpcArgs args(presInfoPack); + + + // This call waits for the server to complete the request before + // proceeding. + TInt err = SendReceive( NRequest::EWritePresenceInfoSync, args ); + + CleanupStack::PopAndDestroy(presInfoPack); + + return err; + + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::DeletePresenceL() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::DeletePresenceL( const TDesC& aIdentity) + { + // Package message arguments before sending to the server + TIpcArgs args( &aIdentity ); + + // This call waits for the server to complete the request before + // proceeding. + TInt err = SendReceive( NRequest::EDeletePresence, args ); + + return err; + } + + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::CancelWrite() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::CancelWrite() + { + TInt ret(KErrNotFound); + if(IsActive()) + { + Cancel(); + ret = KErrNone; + } + return ret; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::CancelRead() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::CancelRead() + { + TInt ret(KErrNotFound); + if(IsActive()) + { + Cancel(); + ret = KErrNone; + } + return ret; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::DeleteService() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::DeleteService(const TDesC& aServiceName) + { + return SendReceive( NRequest::EDeleteService, TIpcArgs(&aServiceName) ); + } + + + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::NewBuddyPresenceInfoLC() +// --------------------------------------------------------------------------- +// + +MPresenceBuddyInfo2* CPresenceCacheClient::NewBuddyPresenceInfoLC() + { + return MPresenceBuddyInfo2::NewLC(); + } + + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::WritePresenceL() +// --------------------------------------------------------------------------- +// +TInt CPresenceCacheClient::WriteMultiplePresenceL( + const RPointerArray& aPresenceBuddyInfos, + MPresenceCacheWriteHandler2* aHandler) + { + if (IsActive()) + return KErrNotReady; + + delete iPresInfoPack; + iPresInfoPack = NULL; + iPresInfoPack = PackPresenceBuddyListLC(aPresenceBuddyInfos); + CleanupStack::Pop(iPresInfoPack); + + // Package message arguments before sending to the server + TIpcArgs args(iPresInfoPack); + args.Set(1,aPresenceBuddyInfos.Count()); + + // This is async call to server. + SendReceive( NRequest::EWritePresenceInfoAsync, args, iStatus); + + iAsyncReq = NRequest::EWritePresenceInfoAsync; + if (aHandler) + { + iWriteHandler = aHandler; + } + SetActive(); + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::ValidateXspId() +// --------------------------------------------------------------------------- +// +TBool CPresenceCacheClient::ValidateXspId(const TDesC& aXspId) + { + TBool ret(EFalse); + _LIT(KColon, ":"); + TInt pos = aXspId.Find(KColon); + if(pos>0) // if colon found and there is something before colon, i.e. xsp id + { + ret = ETrue; + } + return ret; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::RunL() +// --------------------------------------------------------------------------- +// +void CPresenceCacheClient::RunL() + { + + TInt origStatus = iStatus.Int(); + switch (iAsyncReq) + { + case NRequest::EWritePresenceInfoAsync: + if(iWriteHandler) // if client had requested the call back + iWriteHandler->HandlePresenceWriteL(origStatus); + iAsyncReq = NRequest::ENoRequestMade; + break; + + case NRequest::EPrepReadAllBuddiesPresenceInService: + HandlePreparedAllBuddiesPresenceL(origStatus); + iAsyncReq = NRequest::ENoRequestMade; + break; + + case NRequest::ENoRequestMade: + default: + break; + } + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::DoCancel() +// --------------------------------------------------------------------------- +// +void CPresenceCacheClient::DoCancel() + { + iAsyncReq = NRequest::ENoRequestMade; + iReadHandler = NULL; + iWriteHandler = NULL; + SendReceive( NRequest::ECancelAsyncOperation); + // in CPresenceCacheClientNotification SendReceive( NRequest::ECancelWaitingForNotification) + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::PackBuddyPresenceInfoLC() +// --------------------------------------------------------------------------- +// +HBufC8* CPresenceCacheClient::PackBuddyPresenceInfoLC( + const MPresenceBuddyInfo2* aBuddyPresInfo) + { + HBufC8* pack(NULL); + + if ( aBuddyPresInfo ) + { + pack = TCacheObjectPacker< const MPresenceBuddyInfo2>::PackL( *aBuddyPresInfo ); + CleanupStack::PushL( pack ); + } + + return pack; + } + +// --------------------------------------------------------------------------- +// CPresenceCacheClient::PackPresenceBuddyListLC() +// --------------------------------------------------------------------------- +// +HBufC8* CPresenceCacheClient::PackPresenceBuddyListLC(const RPointerArray& aList) + { + HBufC8* pack(NULL); + pack = TPresenceArrayPacker::PackArrayL( aList ); + CleanupStack::PushL( pack ); + return pack; + } + +// end of file