ximpfw/presence/srcpresencecache/presencecacheclient/presencecacheclient.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:54:49 +0200
changeset 0 e6b17d312c8b
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2007 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 <e32std.h>
#include <s32buf.h>

#include <presenceinfofieldcollection.h>
#include <presencebuddyinfo.h>
#include <ximpidentity.h>
#include <prescachewritehandler.h>
#include <prescachereadhandler.h>
#include <presencebuddyinfolist.h>
#include <personpresenceinfo.h>
#include <presenceinfofield.h>
#include <presenceinfo.h>

#include "presencecacheclient.h"
#include "presencecachedefs.h"
#include "ximpobjecthelpers.h"
#include "presenceinfoimp.h"
#include "personpresenceinfoimp.h"
#include "presenceinfofieldimp.h"
#include "ximpidentityimp.h"
#include "presencebuddyinfoimp.h"
#include "presencebuddyinfolistimp.h"
#include "presenceobjectfactoryimp.h"
#include "presencecacheclientnotification.h"


//Include Cache server namespace
using namespace NCacheSrv;


// ============================ 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 MPresenceCacheReader* CPresenceCacheClient::CreateReaderL()
    {
    return NewL();
    }
    
// ---------------------------------------------------------------------------
// CPresenceCacheClient::CreateWriterL()
// ---------------------------------------------------------------------------
//
EXPORT_C MPresenceCacheWriter* CPresenceCacheClient::CreateWriterL()
    {
    return NewL();
    }
    
// ---------------------------------------------------------------------------
// CPresenceCacheClient::~CPresenceCacheClient()
// ---------------------------------------------------------------------------
//
CPresenceCacheClient::~CPresenceCacheClient()
    {
    delete iNotifyHandler;    
    Cancel();
    RSessionBase::Close();
    delete iPresObjFactory;
    }
    
// ---------------------------------------------------------------------------
// CPresenceCacheClient::CPresenceCacheClient()
// ---------------------------------------------------------------------------
//
CPresenceCacheClient::CPresenceCacheClient(): CActive( EPriorityStandard ), 
                                            iWriteHandler(NULL),
                                            iReadHandler(NULL),
                                            iAsyncReq(NRequest::ENoRequestMade)
    {
        
    }

// ---------------------------------------------------------------------------
// CPresenceCacheClient::ConstructL()
// ---------------------------------------------------------------------------
//
void CPresenceCacheClient::ConstructL()
    {
    Connect();
    CActiveScheduler::Add( this );
    iPresObjFactory = CPresenceObjectFactoryImp::NewL();      
    }
    
// -----------------------------------------------------------------------------
// 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()
// ---------------------------------------------------------------------------
//    
MPresenceInfo* CPresenceCacheClient::PresenceInfoLC(const MXIMPIdentity& aIdentity)
    {
    CPresenceInfoImp* presInfo(NULL);
    
    if(!ValidateXspId(aIdentity.Identity()))
        return presInfo;
    
    TInt sizeOfPresInfo(0);
    TPckgBuf<TInt> sizePckg;
    
    HBufC8* myIdPack = PackIdentityLC(aIdentity);                
                      
    // Package message arguments before sending to the server
    TIpcArgs args;
    args.Set(1, myIdPack);
    args.Set(2, &sizePckg);    
        
    // We will get either size(+ve) or error code(+ve) after this call
    TInt err = SendReceive( NRequest::EPrepReadPresenceInfoSync, args );
    sizeOfPresInfo = sizePckg();
    
    CleanupStack::PopAndDestroy(myIdPack);
    
    if(sizeOfPresInfo && (err==KErrNone)) // If found
        {
        presInfo = CPresenceInfoImp::NewLC();    
        HBufC8* presInfoDes = HBufC8::NewLC(sizeOfPresInfo);                        
        TPtr8 ptrBuf( presInfoDes->Des() );                        
                               
        SendReceive( NRequest::EGetLastPreparedPacket, TIpcArgs(&ptrBuf) );
        
        TXIMPObjectPacker< CPresenceInfoImp >::UnPackL( *presInfo, *presInfoDes );
        CleanupStack::PopAndDestroy(presInfoDes);
        }
    
    return presInfo;
    }

// ---------------------------------------------------------------------------
// CPresenceCacheClient::BuddyCountInAllServices()
// ---------------------------------------------------------------------------
//    
TInt CPresenceCacheClient::BuddyCountInAllServices()
    {
    TInt buddyCount(0);
    TPckgBuf<TInt> 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<TInt> 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<TInt> 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::ServicesLC()
// ---------------------------------------------------------------------------
//
/* Implementation is not updated because no one is using this functionality
CDesC16Array* CPresenceCacheClient::ServicesLC()
    {
    CDesC16Array* services(NULL); 
    
    // This call waits for the server to complete the request before
    // proceeding.
    TInt size = SendReceive( NRequest::EPrepGetAllServices);
    if(size>0)
    	{
        HBufC8* servicesDes = HBufC8::NewLC(size);                        
        TPtr8 ptrBuf( servicesDes->Des() );                        
                               
        SendReceive( NRequest::EGetAllServices, TIpcArgs(&ptrBuf) );
        
        services =  UnPackServicesLC(*servicesDes);
        CleanupStack::Pop(services);
        CleanupStack::PopAndDestroy(servicesDes);
        CleanupStack::PushL(services);
    	}
    return services;
    }*/                               
                                                
// ---------------------------------------------------------------------------
// CPresenceCacheClient::AllBuddiesPresenceInService()
// ---------------------------------------------------------------------------
//
TInt CPresenceCacheClient::AllBuddiesPresenceInService(const TDesC& aServiceName, 
                                            MPresCacheReadHandler* aHandler)
    {
    if (IsActive())
        return KErrNotReady;
    
    if(!aHandler || (aServiceName.Length()==NULL) )
        return KErrArgument;
    else
        iReadHandler = aHandler;
    
    // Package message arguments before sending to the server
    TIpcArgs args(&aServiceName);
        
    // This call is async
    SendReceive( NRequest::EPrepReadAllBuddiesPresenceInService, args, iStatus );
    
    iAsyncReq = NRequest::EPrepReadAllBuddiesPresenceInService;
    
    SetActive(); 
    
    return KErrNone;
        
    }
    
// ---------------------------------------------------------------------------
// CPresenceCacheClient::SubscribePresenceBuddyChangeL
// ---------------------------------------------------------------------------
//
TInt CPresenceCacheClient::SubscribePresenceBuddyChangeL(
                                                const MXIMPIdentity& aIdentity)
    {
    if(!ValidateXspId(aIdentity.Identity()))
        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 MXIMPIdentity& aIdentity)
    {
    if(!ValidateXspId(aIdentity.Identity()))
        return;
    
    if ( iNotifyHandler )
    	{
    	iNotifyHandler->UnsubscribePresenceBuddyChangeL( aIdentity);  	    	
    	} 
    }      
                                           
// ---------------------------------------------------------------------------
// CPresenceCacheClient::SetObserverForSubscribedNotifications
// ---------------------------------------------------------------------------
//
TInt CPresenceCacheClient::SetObserverForSubscribedNotifications(
    MPresCacheReadHandler* aHandler)
    {
    if ( !aHandler )
    	{
    	return KErrArgument;
    	}
    iNotifyClient = aHandler;
    return KErrNone;               
    }                                          
                                             
    
// ---------------------------------------------------------------------------
// CPresenceCacheClient::HandlePreparedAllBuddiesPresenceL()
// ---------------------------------------------------------------------------
//
void CPresenceCacheClient::HandlePreparedAllBuddiesPresenceL(TInt aError)
    {
    TInt status = aError; // size comes in status
    CPresenceBuddyInfoListImp* buddyInfoList(NULL);
    if(status>0) // if anything found
        {
        buddyInfoList = CPresenceBuddyInfoListImp::NewLC(KNullDesC);    
        HBufC8* buddyInfosDes = HBufC8::NewLC(status);                        
        TPtr8 ptrBuf( buddyInfosDes->Des() );                        
                               
        status = SendReceive( NRequest::EGetLastAsyncPreparedPacket, TIpcArgs(&ptrBuf) );
        
        TXIMPObjectPacker< CPresenceBuddyInfoListImp >::UnPackL( *buddyInfoList, *buddyInfosDes );
        CleanupStack::PopAndDestroy(buddyInfosDes);
        CleanupStack::Pop(buddyInfoList); // ownership will transfer to client
        }
    
    if(iReadHandler)
        iReadHandler->HandlePresenceReadL(status, buddyInfoList);
    else if(buddyInfoList) // if failed to transfer ownership and created object
        delete buddyInfoList; 
    }

// ---------------------------------------------------------------------------
// CPresenceCacheClient::WritePresenceL()
// ---------------------------------------------------------------------------
//
TInt CPresenceCacheClient::WritePresenceL(
                                const MPresenceBuddyInfo* aPresenceBuddyInfo)
    {
    if(!aPresenceBuddyInfo)
        return KErrArgument;
    
    if(!ValidateXspId(aPresenceBuddyInfo->BuddyId()->Identity()))
        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 MXIMPIdentity& aIdentity)
    {
    HBufC8* idPack = PackIdentityLC(aIdentity);
    
    // Package message arguments before sending to the server
    TIpcArgs args(idPack);
       
    // This call waits for the server to complete the request before
    // proceeding.
    TInt err = SendReceive( NRequest::EDeletePresence, args );
    
    CleanupStack::PopAndDestroy(idPack);    
    
    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::PresenceObjectFactory()
// ---------------------------------------------------------------------------
//
MPresenceObjectFactory& CPresenceCacheClient::PresenceObjectFactory() const
    {
    return *iPresObjFactory;
    }
    
// ---------------------------------------------------------------------------
// CPresenceCacheClient::NewIdentityLC()
// ---------------------------------------------------------------------------
//
MXIMPIdentity* CPresenceCacheClient::NewIdentityLC()
    {
    return CXIMPIdentityImp::NewLC();  
    }

// ---------------------------------------------------------------------------
// CPresenceCacheClient::NewPresenceInfoLC()
// ---------------------------------------------------------------------------
//    
MPresenceInfo* CPresenceCacheClient::NewPresenceInfoLC()
    {
    return CPresenceInfoImp::NewLC();    
    }

// ---------------------------------------------------------------------------
// CPresenceCacheClient::NewBuddyPresenceInfoLC()
// ---------------------------------------------------------------------------
//    
MPresenceBuddyInfo* CPresenceCacheClient::NewBuddyPresenceInfoLC()
    {
    return CPresenceBuddyInfoImp::NewLC();
    }

// ---------------------------------------------------------------------------
// CPresenceCacheClient::NewPresenceBuddyInfoListLC()
// ---------------------------------------------------------------------------
//    
MPresenceBuddyInfoList* CPresenceCacheClient::NewPresenceBuddyInfoListLC(
                                                        const TDesC& aServiceName)
    {
    return CPresenceBuddyInfoListImp::NewLC(aServiceName);
    }
                                                
// ---------------------------------------------------------------------------
// CPresenceCacheClient::WritePresenceL()
// ---------------------------------------------------------------------------
//
TInt CPresenceCacheClient::WritePresenceL(
                            const MPresenceBuddyInfoList* aPresenceBuddyInfos,
                                            MPresCacheWriteHandler* aHandler)
    {
    if (IsActive())
        return KErrNotReady;
    if(!aPresenceBuddyInfos)
        return KErrArgument;
    
    HBufC8* presInfoPack = PackPresenceBuddyListLC(aPresenceBuddyInfos);
    
    // Package message arguments before sending to the server
    TIpcArgs args(presInfoPack);
    args.Set(1,aPresenceBuddyInfos->Count());
                                                            
    // This is async call to server.
    SendReceive( NRequest::EWritePresenceInfoAsync, args, iStatus);
    
    iAsyncReq = NRequest::EWritePresenceInfoAsync;
    
    if(aHandler)
        iWriteHandler = aHandler;    
    
    CleanupStack::PopAndDestroy(presInfoPack);
    
    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);
    SendReceive( NRequest::ECancelWaitingForNotification);
    }
    
// ---------------------------------------------------------------------------
// CPresenceCacheClient::PackBuddyPresenceInfoLC()
// ---------------------------------------------------------------------------
//
HBufC8* CPresenceCacheClient::PackBuddyPresenceInfoLC(
                                    const MPresenceBuddyInfo* aBuddyPresInfo)
    {
    HBufC8* pack(NULL);
    if(aBuddyPresInfo)
        {
        const CPresenceBuddyInfoImp* pifImp = 
            TXIMPGetImpClassOrPanic< const CPresenceBuddyInfoImp >::From( *aBuddyPresInfo );    
        
        pack = TXIMPObjectPacker< const CPresenceBuddyInfoImp>::PackL( *pifImp );
        CleanupStack::PushL( pack );
        }

    return pack;
    }

// ---------------------------------------------------------------------------
// CPresenceCacheClient::PackPresenceBuddyListLC()
// ---------------------------------------------------------------------------
//
HBufC8* CPresenceCacheClient::PackPresenceBuddyListLC(const MPresenceBuddyInfoList* aList)
    {
    HBufC8* pack(NULL);
    if(aList)
        {
        const CPresenceBuddyInfoListImp* pifImp = 
            TXIMPGetImpClassOrPanic< const CPresenceBuddyInfoListImp >::From( *aList );    
        
        pack = TXIMPObjectPacker< CPresenceBuddyInfoListImp>::PackL(*pifImp);
        CleanupStack::PushL( pack );
        }
    return pack;
    }

// ---------------------------------------------------------------------------
// CPresenceCacheClient::PackIdentityLC()
// ---------------------------------------------------------------------------
//
HBufC8* CPresenceCacheClient::PackIdentityLC(const MXIMPIdentity& aIdentity)
    {
    HBufC8* pack(NULL);
    
    const CXIMPIdentityImp* pifImp = 
        TXIMPGetImpClassOrPanic< const CXIMPIdentityImp >::From(aIdentity);    
    
    pack = TXIMPObjectPacker< CXIMPIdentityImp>::PackL( *pifImp );
    CleanupStack::PushL( pack );

    return pack;
    }

// ---------------------------------------------------------------------------
// CPresenceCacheClient::UnPackServicesLC()
// ---------------------------------------------------------------------------
//
/*
CDesCArray* CPresenceCacheClient::UnPackServicesLC(TDesC8& aServicesBuffer)
	{
    CArrayFixFlat<TUid>* services = new (ELeave) CArrayFixFlat<TUid>(1);
    CleanupStack::PushL(services);
    
    RDesReadStream rs;
    CleanupClosePushL( rs );
    rs.Open( aServicesBuffer ); // CSI: 65 #

    // read the object count
    TInt objCount( rs.ReadInt32L() );
    TUid service;

	for ( TInt count = 0; count < objCount; count++ )
        {
        rs>>service;
		services->AppendL(service);
		}

    CleanupStack::PopAndDestroy(); // rs
    return services;
	}*/
    
// end of file