presencefwsimpleadpt/src/simplepluginpublisher.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Feb 2010 23:13:07 +0200
branchRCL_3
changeset 3 ca392eff7152
parent 0 c8caa15ef882
permissions -rw-r--r--
Revision: 201003 Kit: 201007

/*
* Copyright (c) 2006 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:    SIMPLE Protocol implementation for Presence Framework
*
*/




#include <e32std.h>
#include <utf.h>

#include <personpresenceinfo.h>
#include <presenceinfo.h>
#include <presenceinfofield.h>
#include <presenceinfofieldcollection.h>
#include <presenceinfofieldvaluetext.h>
#include <presenceinfofieldvalueenum.h>
#include <presenceinfofieldvaluebinary.h>
#include <presenceobjectfactory.h>
#include <presencewatcherinfo.h>
#include <presenceerrors.hrh>

#include <servicepresenceinfo.h>
#include <devicepresenceinfo.h>

#include <protocolpresencedatahost.h>
#include <protocolpresencepublishingdatahost.h>

#include <ximpdatasubscriptionstate.h>
#include <ximperrors.hrh>
#include <ximpidentity.h>
#include <ximpobjectcollection.h>
#include <ximpobjectfactory.h>
#include <ximpprotocolconnectionhost.h>
#include <ximpstatus.h>

#include <simplefactory.h>

#include <msimplewinfo.h>
#include <msimplepublisher.h>
#include <msimplewatcher.h>
#include <msimpledocument.h>
#include <msimpleelement.h>
#include <msimplecontent.h>

#include "simpleplugincommon.h"
#include "simplepluginpublisher.h"
#include "simpleplugindebugutils.h"
#include "simpleutils.h"
#include "simplepluginwinfo.h"
#include "simpleplugindata.h"
#include "simplepluginxdmutils.h"
#include "simplepluginconnection.h"


// ======== MEMBER FUNCTIONS ========


// -----------------------------------------------------------------------------
// CSimplePluginWatcherInfo::CSimplePluginWatcherInfo
// -----------------------------------------------------------------------------
CSimplePluginWatcherInfo::CSimplePluginWatcherInfo( )
        {}

// -----------------------------------------------------------------------------
// CSimplePluginWatcherInfo::~CSimplePluginWatcherInfo
// -----------------------------------------------------------------------------
CSimplePluginWatcherInfo::~CSimplePluginWatcherInfo()
    {
    delete iId;
    delete iSipId;
    }

// ----------------------------------------------------------
// CSimplePluginWatcherInfo::NewL
// ----------------------------------------------------------
//
CSimplePluginWatcherInfo* CSimplePluginWatcherInfo::NewL(
   const TDesC8& aId, const TDesC& aSipId )
    {
    CSimplePluginWatcherInfo* self = new (ELeave) CSimplePluginWatcherInfo( );
    CleanupStack::PushL( self );
    self->ConstructL( aId, aSipId );
    CleanupStack::Pop( self );
    return self;
    }

// ----------------------------------------------------------
// CSimplePluginWatcherInfo::ConstructL
// ----------------------------------------------------------
//
void CSimplePluginWatcherInfo::ConstructL(
    const TDesC8& aId, const TDesC& aSipId  )
    {
    iId = aId.AllocL();
    iSipId = aSipId.AllocL();
    }

// -----------------------------------------------------------------------------
// CSimplePluginWatcherInfo::Destroy
// -----------------------------------------------------------------------------
void CSimplePluginWatcherInfo::Destroy()
    {
    iLink.Deque();
    delete this;
    }

// -----------------------------------------------------------------------------
// CSimplePluginWatcherInfo::Match
// -----------------------------------------------------------------------------
TBool CSimplePluginWatcherInfo::Match( const TDesC8& aId, const TDesC& aSipId )
    {
    if ( (!iId->Des().CompareF( aId )) && (!iSipId->Des().CompareF( aSipId)) )
        {
        return ETrue;
        }
    else
        {
        return EFalse;
        }
    }

// -----------------------------------------------------------------------------
// CSimplePluginWatcherInfo::SipId
// -----------------------------------------------------------------------------
TPtrC CSimplePluginWatcherInfo::SipId( )
    {
    return iSipId ? iSipId->Des() : TPtrC();
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::CSimplePluginPublisher
// ---------------------------------------------------------------------------
//
CSimplePluginPublisher::CSimplePluginPublisher(
    MSimplePluginSettings& aConnSets,
    MSimplePluginConnectionObs& aObs,
    MSimpleConnection& aConn )
: CActive( CActive::EPriorityStandard ),
  iConnObs(aObs), iConnSets( aConnSets), iConnection(aConn),
  iSubscribed(EFalse), iSubscribedOwn(EFalse), iPublished(EFalse),
  iWatcherList( CSimplePluginWatcherInfo::LinkOffset())
    {
    CActiveScheduler::Add(this);
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::ConstructL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::ConstructL( )
    {
    iPublisher = TSimpleFactory::NewPublisherL( iConnection, *this );
    iWatcher = TSimpleFactory::NewWatcherL( iConnection, *this );
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::NewL
// ---------------------------------------------------------------------------
//
CSimplePluginPublisher* CSimplePluginPublisher::NewL(
    MSimplePluginSettings& aConnSets,
    MSimplePluginConnectionObs& aObs,
    MSimpleConnection& aConn )
    {
    CSimplePluginPublisher* self =
        new( ELeave ) CSimplePluginPublisher( aConnSets, aObs, aConn );
    CleanupStack::PushL( self );
    self->ConstructL(  );
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::~CSimplePluginPublisher
// ---------------------------------------------------------------------------
//
CSimplePluginPublisher::~CSimplePluginPublisher()
    {
    if ( iDocument )
        {
        iDocument->Close();
        }

    if ( iPublisher )
        {
        iPublisher->Close();
        }

    if ( iWatcher )
        {
        iWatcher->Close();
        }

    // delete iWatchers;
    DeleteWatchers();

    }

// -----------------------------------------------------------------------------
// CSimplePluginPublisher::DeleteWatchers
// -----------------------------------------------------------------------------
void CSimplePluginPublisher::DeleteWatchers()
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: DeleteWatchers" ) );
#endif
    // Delete all buffered transaction requests
    TDblQueIter<CSimplePluginWatcherInfo> rIter( iWatcherList );
    rIter.SetToFirst();

    while ( rIter )
        {
        CSimplePluginWatcherInfo* w = rIter;
        rIter++;
        // delete wathcer info
        w->Destroy();
        }
    }

// -----------------------------------------------------------------------------
// CSimplePluginPublisher::AddWatcherIfNotExistsL
// -----------------------------------------------------------------------------
void CSimplePluginPublisher::AddWatcherIfNotExistsL( const TDesC8& aId, const TDesC& aSipId )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: AddWatcherIfNotExistsL" ) );
#endif
    TDblQueIter<CSimplePluginWatcherInfo> rIter( iWatcherList );
    rIter.SetToFirst();

    TBool found(EFalse);

    while ( rIter )
        {
        CSimplePluginWatcherInfo* w = rIter;
        rIter++;
        found = w->Match( aId, aSipId );
        if ( found )
            {
            break;
            }
        else
            {
            // continue searching
            }
        }
    if ( !found )
        {
#ifdef _DEBUG
        PluginLogger::Log(_L("PluginPublisher: AddWatcherIfNotExistsL adds a watcher" ) );
#endif
        CSimplePluginWatcherInfo* w = CSimplePluginWatcherInfo::NewL( aId, aSipId );
        iWatcherList.AddLast( *w );
        }
    }

// -----------------------------------------------------------------------------
// CSimplePluginPublisher::RemoveWatcherIfExistsL
// -----------------------------------------------------------------------------
void CSimplePluginPublisher::RemoveWatcherIfExistsL( const TDesC8& aId, const TDesC& aSipId )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: RemoveWatcherIfExistsL" ) );
#endif
    TDblQueIter<CSimplePluginWatcherInfo> rIter( iWatcherList );
    rIter.SetToFirst();

    TBool found(EFalse);

    while ( rIter )
        {
        CSimplePluginWatcherInfo* w = rIter;
        rIter++;
        // delete wathcer info
        found = w->Match( aId, aSipId );
        if ( found )
            {
#ifdef _DEBUG
            PluginLogger::Log(_L("PluginPublisher: RemoveWatcherIfExistsL removes a watcher" ) );
#endif
            w->Destroy();
            break;
            }
        else
            {
            // continue searching
            }
        }
    }
// -----------------------------------------------------------------------------
// CSimplePluginPublisher::MakeCurrentWatcherListLC
// -----------------------------------------------------------------------------
CDesCArrayFlat* CSimplePluginPublisher::MakeCurrentWatcherListLC()
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: MakeCurrentWatcherListL" ) );
#endif
    // No one should be added more than once
    const TInt KMyGran = 10;
    CDesCArrayFlat* watchers = new (ELeave) CDesCArrayFlat( KMyGran );
    CleanupStack::PushL( watchers );      // << watchers

    // add user only once here.
    TDblQueIter<CSimplePluginWatcherInfo> rIter( iWatcherList );
    rIter.SetToFirst();

    while ( rIter )
        {
        CSimplePluginWatcherInfo* w = rIter;
        rIter++;

        TInt dummy = 0;
        if ( watchers->Find( w->SipId(), dummy ))
            {
            watchers->AppendL( w->SipId() );
            }
        else
            {
            // continue searching
            }
        }

    return watchers;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::DoPublishOwnPresenceL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::DoPublishOwnPresenceL(
    const MPresenceInfo& aOwnPresence,
    TXIMPRequestId aReqId )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: DoPublishOwnPresenceL"));
#endif

    const MPersonPresenceInfo* persInfo = aOwnPresence.PersonPresence();

    // convert data format from PrFW to internal
    if ( !persInfo )
        {
        // Notice: error codes
        CompletePrFwReq( KErrArgument );
        return;
        }
    InitializeSimpleDocumentL( );
    AddSimpleDocumentPersL( persInfo );

    TInt myCount = aOwnPresence.ServicePresenceCount();
    for ( TInt i=0; i < myCount; i++ )
        {
        const MServicePresenceInfo& servInfo = aOwnPresence.ServicePresenceAt(i);
        AddSimpleDocumentServiceL( servInfo );
        }
    myCount = aOwnPresence.DevicePresenceCount();
    for ( TInt i=0; i < myCount; i++ )
        {
        const MDevicePresenceInfo& devInfo = aOwnPresence.DevicePresenceAt(i);
        AddSimpleDocumentDeviceL( devInfo );
        }

    // Ensure that XDM rules exists, the show continues in RunL
    StartXdmOperationL(aReqId );
    iOperation = EPublishOwn;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::DoSubscribeOwnPresenceL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::DoSubscribeOwnPresenceL(
    const MPresenceInfoFilter& /*aPif*/,   // notice: aPif filter not supported
    TXIMPRequestId aReqId )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: DoSubscribeOwnPresenceL"));
#endif

    StartXdmOperationL( aReqId );

    iOperation = ESubscribeOwn;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::DoUpdateOwnPresenceSubscriptionPifL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::DoUpdateOwnPresenceSubscriptionPifL(
    const MPresenceInfoFilter& /*aPif*/,
    TXIMPRequestId /*aReqId*/ )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: DoUpdateOwnPresenceSubscriptionPifL"));
#endif
    // Notice: aPif filter not supported
    User::Leave( KErrNotSupported );
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::DoUnsubscribeOwnPresenceL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::DoUnsubscribeOwnPresenceL(
    TXIMPRequestId aReqId )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: DoUnsubscribeOwnPresenceL"));
#endif
    iSubscribedOwn = EFalse;
    TRAPD( err, iSimpleId = iWatcher->UnsubscribeL());
    if ( err )
        {
        User::Leave( CSimplePluginConnection::HarmonizeErrorCode( err ));
        }
    iPrFwId = aReqId;
    iOperation = EUnsubscribeOwn;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::DoSubscribePresenceWatcherListL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::DoSubscribePresenceWatcherListL(
    TXIMPRequestId aReqId )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: DoSubscribePresenceWatcherListL"));
#endif

    if ( !iSubscribed )
        {
        TRAPD( err, iConnObs.WinfoHandlerL()->SubscribeWinfoListL( aReqId ));
        if ( err )
            {
            User::Leave( CSimplePluginConnection::HarmonizeErrorCode( err ));
            }
        iSubscribed = ETrue;
        iPrFwId = aReqId;
        iOperation = ESubscribeWinfo;
        }
    else
        {
        iPrFwId = aReqId;
        CompletePrFwReq( KErrNone );
        }
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::DoUnsubscribePresenceWatcherListL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::DoUnsubscribePresenceWatcherListL(
    TXIMPRequestId aReqId )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: DoUnsubscribePresenceWatcherListL"));
#endif
    if ( iSubscribed )
        {
        TRAPD( err, iConnObs.WinfoHandlerL()->UnsubscribeWinfoListL( aReqId ));
        if ( err )
            {
            User::Leave( CSimplePluginConnection::HarmonizeErrorCode( err ));
            }
        iSubscribed = EFalse;
        iPrFwId = aReqId;
        iOperation = EUnsubscribeWinfo;
        }
    else
        {
        iPrFwId = aReqId;
        CompletePrFwReq( KErrNone );
        }
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::PublishReqCompleteL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::PublishReqCompleteL( TInt /*aOpid*/, TInt aStatus )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: PublishReqCompleteL("));
#endif
    if ( !aStatus )
        {
        iPublished = ETrue;
        }
    else
        {
        }

    CompletePrFwReq( aStatus );
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::PublishTerminatedL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::PublishTerminatedL( TInt /*aOpid*/ )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: PublishTerminatedL"));
#endif
    // Notice: nothing to do now in Host APi.
    iPublished = EFalse;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::WatcherReqCompleteL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::WatcherReqCompleteL( TInt /*aOpid*/, TInt aStatus )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: WatcherReqCompleteL"));
#endif
    if ( !aStatus )
        {
        iSubscribedOwn = ETrue;
        }
    else
        {
        }
    CompletePrFwReq( aStatus );
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::WatcherNotificationL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::WatcherNotificationL( MSimpleDocument& aDocument )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: WatcherNotificationL"));
#endif

    // Notice: Do not need to check the expiration here since WatcherTerminatedL
    // is called then too.

    MProtocolPresencePublishingDataHost& publishHost =
        iConnObs.Host()->ProtocolPresenceDataHost().PublishingDataHost();
    MPresenceInfo* prInfo = iConnObs.PresenceObjectFactory().NewPresenceInfoLC();  // << prInfo
    CSimplePluginData::NotifyToPrInfoL( iConnObs.PresenceObjectFactory(), aDocument, *prInfo );

#ifdef _DEBUG
    // ---------------------------------------------------------
    const MPersonPresenceInfo* pers_debug = prInfo->PersonPresence();
    const MPresenceInfoFieldCollection& coll_debug = pers_debug->Fields();
    TInt count_debug = coll_debug.FieldCount();
    PluginLogger::Log(_L("PluginPublisher: nbr of fields received =%d"), count_debug );
    // ---------------------------------------------------------
#endif

    // PrFw Host API callbacks

#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: callback HandleSubscribedOwnPresenceL"));
#endif
    publishHost.HandleSubscribedOwnPresenceL( prInfo );
    CleanupStack::Pop();  // >> prInfo

    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::WatcherListNotificationL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::WatcherListNotificationL( MSimplePresenceList& /*aList*/ )
    {
    // Notice: not needed.
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::WatcherTerminatedL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::WatcherTerminatedL(
    TInt /*aOpId*/, TInt /*aReason*/ )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: WatcherTerminatedL"));
#endif
    iSubscribedOwn = EFalse;

    MProtocolPresencePublishingDataHost& publishHost =
        iConnObs.Host()->ProtocolPresenceDataHost().PublishingDataHost();
    MXIMPDataSubscriptionState *state = iConnObs.ObjectFactory().NewDataSubscriptionStateLC();
    MXIMPStatus* status = iConnObs.ObjectFactory().NewStatusLC();
    state->SetSubscriptionStateL( MXIMPDataSubscriptionState::ESubscriptionInactive );
    status->SetResultCode( KErrCompletion );
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: callback SetOwnPresenceDataSubscriptionStateL"));
#endif
    publishHost.SetOwnPresenceDataSubscriptionStateL( state, status );
    CleanupStack::Pop( 2 ); // status, state
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::CompletePrFwReq
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::CompletePrFwReq( TInt aStatus )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: CompletePrFwReq status=%d"), aStatus );
#endif
    if ( iOperation != ENoOperation )
        {
        iOperation = ENoOperation;
        iConnObs.CompleteReq( iPrFwId, aStatus );
        iPrFwId = TXIMPRequestId();
        }
    else
        {
        }
    return;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::DoCancel
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::DoCancel(  )
    {
    iXdmUtils->Cancel();
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::RunL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::RunL(  )
    {

    TInt status = iStatus.Int();

#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: RunL %d"), status );
#endif

    if ( !status )
        {
        if ( iOperation == ESubscribeOwn )
            {
            iSimpleId = iWatcher->SubscribeL(
                iConnSets.CurrentSipPresentity8(),
                NULL,  // aFilter <-> aPif
                ETrue, EFalse );
            }
        else
            {
            MakePublishReqL();
            }
        }
    else
        {
        CompletePrFwReq( status );
        }
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::RunError
// ---------------------------------------------------------------------------
//
TInt CSimplePluginPublisher::RunError( TInt aError )
    {
    CompletePrFwReq( aError );
    return KErrNone;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::GetInterface
// ---------------------------------------------------------------------------
//
TAny* CSimplePluginPublisher::GetInterface(
        TInt32 aInterfaceId,
        TIfGetOps aOptions )
    {
    if ( aInterfaceId == GetInterfaceId() )
        {
        // caller wants this interface
        MProtocolPresencePublishing* myIf = this;
        return myIf;
        }
    else if ( aOptions == MXIMPBase::EPanicIfUnknown )
        {
        User::Panic( _L("CSimplePlugin"), KErrExtensionNotSupported );
        }
    return NULL;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::GetInterface
// ---------------------------------------------------------------------------
//
const TAny* CSimplePluginPublisher::GetInterface(
    TInt32 aInterfaceId,
    TIfGetOps aOptions ) const
    {
    if ( aInterfaceId == GetInterfaceId() )
        {
        // caller wants this interface
        const MProtocolPresencePublishing* myIf = this;
        return myIf;
        }
    else if ( aOptions == MXIMPBase::EPanicIfUnknown )
        {
        User::Panic( _L("CSimplePlugin"), KErrExtensionNotSupported );
        }
    return NULL;
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::GetInterfaceId
// ---------------------------------------------------------------------------
//
TInt32 CSimplePluginPublisher::GetInterfaceId() const
    {
    return MProtocolPresencePublishing::KInterfaceId;
    }


// ---------------------------------------------------------------------------
// CSimplePluginPublisher::InitializeSimpleDocumentL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::InitializeSimpleDocumentL( )
    {
    if ( iDocument )
        {
        iDocument->Close();
        iDocument = NULL;
        }
    iDocument = TSimpleFactory::NewDocumentL();
    iDocument->AddNamespaceL( KSimplePDM, KSimpleNsPDM );
    iDocument->AddNamespaceL( KSimpleRPID, KSimpleNsRPID );
    iDocument->AddNamespaceL( KSimpleOP, KSimpleNsOP );
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::AddSimpleDocumentPersL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::AddSimpleDocumentPersL(
    const MPersonPresenceInfo* aInfo )
    {
    CSimplePluginData::AddPrPersToSimpleDocumentL(
        aInfo, *iDocument, iConnSets.CurrentSipPresentity8() );
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::AddSimpleDocumentServiceL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::AddSimpleDocumentServiceL(
    const MServicePresenceInfo& aInfo )
    {
    if ( aInfo.Fields().FieldCount() > 0 || aInfo.ServiceType().Length() )
        {
        // Notice: currently all the fields in the namespace are supported,
        // but this ensures that if namespace is extended later, it is
        // handled right way in the adaptation
        User::Leave( KPresenceErrPresenceInfoFieldTypeNotSupported );
        }
    else
        {
        }
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::AddSimpleDocumentDeviceL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::AddSimpleDocumentDeviceL(
    const MDevicePresenceInfo& aInfo )
    {
    if ( aInfo.Fields().FieldCount() > 0 || aInfo.DeviceName().Length() )
        {
        // Notice: currently all the fields in the namespace are supported,
        // but this ensures that if namespace is extended later, it is
        // handled right way in the adaptation
        User::Leave( KPresenceErrPresenceInfoFieldTypeNotSupported );
        }
    else
        {
        }
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::MakePublishReqL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::MakePublishReqL( )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: -> MakePublishReqL"));
#endif
    // Send the iDocument
    if ( !iPublished )
        {
        iSimpleId = iPublisher->StartPublishL( *iDocument, ETrue );
        }
    else
        {
        iSimpleId = iPublisher->ModifyPublishL( *iDocument);
        }
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::StartXdmOperationL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::StartXdmOperationL(
    TXIMPRequestId aReqId )
    {
    TRAPD( err, DoStartXdmOperationL( aReqId ));
    if ( err )
        {
        User::Leave( CSimplePluginConnection::HarmonizeErrorCode( err ));
        }
    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::DoStartXdmOperationL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::DoStartXdmOperationL(
    TXIMPRequestId aReqId )
    {
    __ASSERT_DEBUG( !IsActive(), User::Leave( KErrCorrupt ) );
    iPrFwId = aReqId;
    if ( !iXdmUtils )
        {
        iXdmUtils = iConnObs.XdmUtilsL();
        }
    iXdmUtils->InitializeXdmL( iStatus );
    SetActive();
    }



// ---------------------------------------------------------------------------
// CSimplePluginPublisher::WinfoNotificationL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::WinfoNotificationL(
    MSimpleWinfo& aWinfo )
    {
    // ignore if not subscribed
    if ( !iSubscribed )
        {
        return;
        }

#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: WinfoNotificationL"));
#endif

    // Handle full-state and partial state notifications
    // - If terminated -> remove from iWatcherList
    // - If active -> add into iWatcherList if does not already exist
    // WinfoTerminatedL handles termination of subscription.

    // Notice: CSimplePluginWinfo has completed the open request if needed before this.


    /* example:

    // active/pending/terminated

   <?xml version="1.0"?>
     <watcherinfo xmlns="urn:ietf:params:xml:ns:watcherinfo"
   version="0" state="full">
     <watcher-list resource="sip:presentity@example.com"
                   package="presence">
         <watcher status="active"
            id="sr8fdsj"
            duration-subscribed="509"
            expiration="20"
            event="approved">sip:watcherA@example.com"
          </watcher>
     */

    RPointerArray<MSimpleElement> elems;
    CleanupClosePushL( elems );         // << elems
    TInt err = aWinfo.SimpleElementsL( elems );
    User::LeaveIfError( err );
    TInt count = elems.Count();

    __ASSERT_DEBUG( count == 1, User::Leave( KErrCorrupt ) );

    using namespace NSimplePlugin::NSimpleOma;

    const TDesC8* stateVal = aWinfo.AttrValue( KSimpleState8 );
    if ( stateVal && !stateVal->CompareF( KSimpleFull8 ))
        {
#ifdef _DEBUG
        PluginLogger::Log(_L("PluginPublisher: fullstate = TRUE") );
#endif
        // full winfo-list is received
        DeleteWatchers();
        }
  else
        {
#ifdef _DEBUG
        PluginLogger::Log(_L("PluginPublisher: fullstate = FALSE") );
#endif
    }

    MSimpleElement* elem = elems[0];
    TPtrC8 p8 = elem->LocalName();
    err = p8.CompareF( KSimpleWatcherList8 );
    User::LeaveIfError( err );

    err = elem->SimpleElementsL( elems );
    User::LeaveIfError( err );

    // Collect the active watchers only.
    UpdateActiveWatchersListL( elems );

    CDesCArrayFlat* watchers = MakeCurrentWatcherListLC();  // << watchers
    MXIMPObjectCollection *actives =
        iConnObs.ObjectFactory().NewObjectCollectionLC();                  // << actives

    // Create MPresenceWatcherInfo entities for
    // all active watchers and add to actives.
    TInt wCount = watchers->MdcaCount();
    for ( TInt j = 0; j < wCount; j++ )
        {
        // create MPresenceWatcherInfo object
        MPresenceWatcherInfo* wInfo =
            iConnObs.PresenceObjectFactory().NewPresenceWatcherInfoLC();           // << wInfo

        MXIMPIdentity* identity = iConnObs.ObjectFactory().NewIdentityLC();  // << identity
#ifdef _DEBUG
        TBuf<200> debug_buffer;
        debug_buffer = watchers->MdcaPoint( j );
        PluginLogger::Log(_L("PluginPublisher: add watcher into collection: %S"), &debug_buffer);
#endif
        identity->SetIdentityL( watchers->MdcaPoint( j ) );
        wInfo->SetWatcherIdL( identity );
        CleanupStack::Pop( );                               // >> identity

        wInfo->SetWatcherDisplayNameL( watchers->MdcaPoint( j ) );
        wInfo->SetWatcherTypeL( MPresenceWatcherInfo::EPresenceSubscriber );

        actives->AddObjectL( wInfo );
        CleanupStack::Pop( );                           // >> wInfo
        }

    MProtocolPresencePublishingDataHost& publishHost =
        iConnObs.Host()->ProtocolPresenceDataHost().PublishingDataHost();

#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: callback HandlePresenceWatcherListL"));
#endif
    publishHost.HandlePresenceWatcherListL( actives );
    CleanupStack::Pop();                            // >> actives
    CleanupStack::PopAndDestroy( watchers );        // >> watchers
    CleanupStack::PopAndDestroy( &elems );          // >> elems

    }

// ---------------------------------------------------------------------------
// CSimplePluginPublisher::WinfoTerminatedL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::WinfoTerminatedL( TInt /*aReason*/ )
    {
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: WinfoTerminatedL") );
#endif

    if ( !iSubscribed )
        {
        return;
        }

    // call SetPresenceWatcherListDataSubscriptionStateL
    iSubscribed = EFalse;

    MProtocolPresencePublishingDataHost& publishHost =
        iConnObs.Host()->ProtocolPresenceDataHost().PublishingDataHost();
    MXIMPDataSubscriptionState *state = iConnObs.ObjectFactory().NewDataSubscriptionStateLC();
    MXIMPStatus* status = iConnObs.ObjectFactory().NewStatusLC();
    state->SetSubscriptionStateL( MXIMPDataSubscriptionState::ESubscriptionInactive );
    state->SetDataStateL( MXIMPDataSubscriptionState::EDataUnavailable );
    status->SetResultCode( KErrCompletion );
#ifdef _DEBUG
    PluginLogger::Log(_L("PluginPublisher: callback SetPresenceWatcherListDataSubscriptionStateL"));
#endif
    publishHost.SetPresenceWatcherListDataSubscriptionStateL( state, status );
    CleanupStack::Pop( 2 ); // status, state
    }


// ---------------------------------------------------------------------------
// CSimplePluginPublisher::UpdateActiveWatchersListL
// ---------------------------------------------------------------------------
//
void CSimplePluginPublisher::UpdateActiveWatchersListL(
    RPointerArray<MSimpleElement>& aElems )
    {
    // Collect active users.
    using namespace NSimplePlugin::NSimpleOma;

    HBufC* nodeContent = NULL;

    TInt count = aElems.Count();

    for ( TInt i = 0; i < count; i++ )
        {
        MSimpleElement* elem = aElems[i];
        TPtrC8 p8( elem->LocalName());
        if (!( p8.CompareF( KSimpleWatcher8 )))
            {
            const TDesC8* pp8 = elem->AttrValue( KSimpleStatus8 );
            // Active wathers here
            if ( pp8 && !pp8->CompareF( KSimpleActive8 ))
                {

                // save id since there may be multiple subscriptions
                // from a single watcher SIP identity.
                const TDesC8* pId8 = elem->AttrValue( KSimpleId8 );

                // Build collection of grant requests
                // Find the child node containing the SIP entity
                nodeContent = elem->ContentUnicodeL();
                CleanupStack::PushL( nodeContent );         // << nodeContent

                AddWatcherIfNotExistsL( pId8 ? *pId8 : KNullDesC8, nodeContent->Des() );

                CleanupStack::PopAndDestroy( nodeContent ); // >> nodeContent
                }
            // Terminated wathers here, remove them from active list
            else if ( pp8 && !pp8->CompareF( KSimpleTerminated8 ))
                {

                const TDesC8* pId8 = elem->AttrValue( KSimpleId8 );

                // Remove terminated from iWatcherList
                nodeContent = elem->ContentUnicodeL();
                CleanupStack::PushL( nodeContent );             // << nodeContent

                RemoveWatcherIfExistsL( pId8 ? *pId8 : KNullDesC8, nodeContent->Des() );

                CleanupStack::PopAndDestroy( nodeContent );     // >> nodeContent
                }
            }
        }

    }



// End of file