/*
* Copyright (c) 2007-2010 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: IETF SIMPLE Protocol implementation for XIMP Framework
*
*/
#include <e32std.h>
#include <e32base.h>
#include <s32strm.h>
#include <e32def.h>
#include <e32svr.h>
#include <e32math.h>
#include <utf.h>
#include <ximpbase.h>
#include <ximpobjectfactory.h>
#include <ximpobjectcollection.h>
#include <presenceobjectfactory.h>
#include <presenceinfo.h>
#include <personpresenceinfo.h>
#include <presenceinfofieldcollection.h>
#include <presenceinfofield.h>
#include <presenceinfofieldvaluetext.h>
#include <presenceinfofieldvalueenum.h>
#include <ximpidentity.h>
#include <msimpledocument.h>
#include <msimpleelement.h>
#include <msimplepresencelist.h>
#include <msimplemeta.h>
#include <simpleutils.h>
#include <presencecachewriter2.h>
#include <presencecachereader2.h>
#include <presencebuddyinfo.h>
#include <spsettings.h>
#include <spentry.h>
#include <spproperty.h>
#include <spdefinitions.h>
#include <avabilitytext.h>
#include <cvimpstsettingsstore.h>
#include "presenceplugindata.h"
#include "presenceplugincommon.h"
#include "presencepluginvirtualgroup.h"
#include "presencepluginlanguagecodes.h"
// ---------------------------------------------------------------------------
// CPresencePluginData::CPresencePluginData
// ---------------------------------------------------------------------------
//
CPresencePluginData::CPresencePluginData(
MPresencePluginConnectionObs& aObs,
TInt aServiceId ):
iConnObs( aObs ),
iServiceId( aServiceId ),
iPresenceCacheWriter( NULL ),
iPresenceCacheReader( NULL )
{
}
// ---------------------------------------------------------------------------
// CPresencePluginData::~CPresencePluginData
// ---------------------------------------------------------------------------
//
CPresencePluginData::~CPresencePluginData()
{
DP_SDA("CPresencePluginData::~CPresencePluginData");
delete iPresenceCacheWriter;
delete iPresenceCacheReader;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::NewL
// ---------------------------------------------------------------------------
//
CPresencePluginData* CPresencePluginData::NewL(
MPresencePluginConnectionObs& aObs, TInt aServiceId )
{
CPresencePluginData* self = CPresencePluginData::NewLC(
aObs,
aServiceId );
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::ConstructL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::ConstructL()
{
DP_SDA("CPresencePluginData::ConstructL");
iPresenceCacheWriter = MPresenceCacheWriter2::CreateWriterL();
iPresenceCacheReader = MPresenceCacheReader2::CreateReaderL();
}
// ---------------------------------------------------------------------------
// CPresencePluginData::NewLC
// ---------------------------------------------------------------------------
//
CPresencePluginData* CPresencePluginData::NewLC(
MPresencePluginConnectionObs& aObs, TInt aServiceId )
{
CPresencePluginData* self =
new( ELeave ) CPresencePluginData( aObs, aServiceId );
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::NotifyToBlockedToXIMPL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::NotifyToBlockedToXIMPL(
MPresenceObjectFactory& aPresenceFactory,
MPresenceInfo& aPrInfo,
const TDesC& aUnicodeNoteContent )
{
DP_SDA("CPresencePluginData::NotifyToBlockedToXIMPL");
MPersonPresenceInfo* persInfo =
aPresenceFactory.NewPersonPresenceInfoLC();
MPresenceInfoFieldCollection& coll = persInfo->Fields();
//Set pending
using namespace NPresenceInfo::NFieldType;
using namespace NPresencePlugin::NPresenceStates;
MPresenceInfoField* field = aPresenceFactory.NewInfoFieldLC();
field->SetFieldTypeL( KAvailabilityEnum );
// use mapped enums to pass status
MPresenceInfoFieldValueEnum* enumField =
aPresenceFactory.NewEnumInfoFieldLC();
// HOX: BLOCKED ENUM NEEDED TO XIMP
enumField->SetValueL( NPresenceInfo::ENotAvailable );
field->SetFieldValue( enumField );
coll.AddOrReplaceFieldL( field );
CleanupStack::Pop( 2 ); // >> field, enumField
// Add status msg field
MPresenceInfoField* noteField = aPresenceFactory.NewInfoFieldLC();
noteField->SetFieldTypeL( KStatusMessage );
MPresenceInfoFieldValueText* textField =
aPresenceFactory.NewTextInfoFieldLC();
textField->SetTextValueL( aUnicodeNoteContent );
noteField->SetFieldValue( textField );
coll.AddOrReplaceFieldL( noteField );
CleanupStack::Pop( 2 ); // >> noteField, enumField
aPrInfo.SetPersonPresenceL( persInfo );
CleanupStack::Pop(); // >> persInfo
DP_SDA("CPresencePluginData::NotifyToBlockedToXIMPL end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::NotifyToPendingToXIMPL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::NotifyToPendingToXIMPL(
MPresenceObjectFactory& aPresenceFactory,
MPresenceInfo& aPrInfo,
const TDesC& aUnicodeNoteContent )
{
DP_SDA("CPresencePluginData::NotifyToPendingToXIMP");
MPersonPresenceInfo* persInfo =
aPresenceFactory.NewPersonPresenceInfoLC();
MPresenceInfoFieldCollection& coll = persInfo->Fields();
//Set pending
using namespace NPresenceInfo::NFieldType;
using namespace NPresencePlugin::NPresenceStates;
MPresenceInfoField* field = aPresenceFactory.NewInfoFieldLC();
field->SetFieldTypeL( KAvailabilityEnum );
// use mapped enums to pass status
MPresenceInfoFieldValueEnum* enumField =
aPresenceFactory.NewEnumInfoFieldLC();
enumField->SetValueL( NPresenceInfo::ERemotePending );
field->SetFieldValue( enumField );
coll.AddOrReplaceFieldL( field );
CleanupStack::Pop( 2 ); // >> field, enumField
// Add status msg field
MPresenceInfoField* noteField = aPresenceFactory.NewInfoFieldLC();
noteField->SetFieldTypeL( KStatusMessage );
MPresenceInfoFieldValueText* textField =
aPresenceFactory.NewTextInfoFieldLC();
textField->SetTextValueL( aUnicodeNoteContent );
noteField->SetFieldValue( textField );
coll.AddOrReplaceFieldL( noteField );
CleanupStack::Pop( 2 ); // >> noteField, enumField
aPrInfo.SetPersonPresenceL( persInfo );
CleanupStack::Pop(); // >> persInfo
DP_SDA("CPresencePluginData::NotifyToPendingToXIMP end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::NotifyActiveToPrInfoL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::NotifyToActiveToXIMPL(
MPresenceObjectFactory& aPresenceFactory,
MPresenceInfo& aPrInfo,
const TDesC& aUnicodeNoteContent,
NPresenceInfo::TAvailabilityValues aAvailability )
{
DP_SDA("CPresencePluginData::NotifyToActiveToXIMPL");
MPersonPresenceInfo* persInfo =
aPresenceFactory.NewPersonPresenceInfoLC();
MPresenceInfoFieldCollection& coll = persInfo->Fields();
//Set pending
using namespace NPresenceInfo::NFieldType;
using namespace NPresencePlugin::NPresenceStates;
MPresenceInfoField* field = aPresenceFactory.NewInfoFieldLC();
field->SetFieldTypeL( KAvailabilityEnum );
// use mapped enums to pass status
MPresenceInfoFieldValueEnum* enumField =
aPresenceFactory.NewEnumInfoFieldLC();
enumField->SetValueL( aAvailability );
field->SetFieldValue( enumField );
coll.AddOrReplaceFieldL( field );
CleanupStack::Pop( 2 ); // >> field, enumField
// Add status msg field
MPresenceInfoField* noteField = aPresenceFactory.NewInfoFieldLC();
noteField->SetFieldTypeL( KStatusMessage );
MPresenceInfoFieldValueText* textField =
aPresenceFactory.NewTextInfoFieldLC();
textField->SetTextValueL( aUnicodeNoteContent );
noteField->SetFieldValue( textField );
coll.AddOrReplaceFieldL( noteField );
CleanupStack::Pop( 2 ); // >> noteField, enumField
aPrInfo.SetPersonPresenceL( persInfo );
CleanupStack::Pop(); // >> persInfo
DP_SDA("CPresencePluginData::NotifyToActiveToXIMPL end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::NotifyTerminatedToPrInfoL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::NotifyTerminatedToXIMPL(
MPresenceObjectFactory& aPresenceFactory,
MPresenceInfo& aPrInfo,
const TDesC& aUnicodeNoteContent )
{
DP_SDA("CPresencePluginData::NotifyTerminatedToXIMPL");
MPersonPresenceInfo* persInfo =
aPresenceFactory.NewPersonPresenceInfoLC();
MPresenceInfoFieldCollection& coll = persInfo->Fields();
//Set pending
using namespace NPresenceInfo::NFieldType;
using namespace NPresencePlugin::NPresenceStates;
MPresenceInfoField* field = aPresenceFactory.NewInfoFieldLC();
field->SetFieldTypeL( KAvailabilityEnum );
// use mapped enums to pass status
MPresenceInfoFieldValueEnum* enumField =
aPresenceFactory.NewEnumInfoFieldLC();
enumField->SetValueL( NPresenceInfo::EOffline );
field->SetFieldValue( enumField );
coll.AddOrReplaceFieldL( field );
CleanupStack::Pop( 2 ); // >> field, enumField
// Add status msg field
MPresenceInfoField* noteField = aPresenceFactory.NewInfoFieldLC();
noteField->SetFieldTypeL( KStatusMessage );
MPresenceInfoFieldValueText* textField =
aPresenceFactory.NewTextInfoFieldLC();
textField->SetTextValueL( aUnicodeNoteContent );
noteField->SetFieldValue( textField );
coll.AddOrReplaceFieldL( noteField );
CleanupStack::Pop( 2 ); // >> noteField, enumField
aPrInfo.SetPersonPresenceL( persInfo );
CleanupStack::Pop(); // >> persInfo
DP_SDA("CPresencePluginData::NotifyTerminatedToXIMPL end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::NotifyToPrInfoL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::NotifyToPrInfoL(
MXIMPObjectFactory& /*aFactory*/,
MPresenceObjectFactory& aPresenceFactory,
MSimpleDocument& aDocument,
MPresenceInfo& aPrInfo )
{
DP_SDA("CPresencePluginData::NotifyToPrInfoL");
MPersonPresenceInfo* persInfo =
aPresenceFactory.NewPersonPresenceInfoLC();
DP_SDA("CPresencePluginData::NotifyToPrInfoL persInfo");
if( !aDocument.EntityURI() )
{
DP_SDA("CPresencePluginData::NotifyToPrInfoL entity URL not valid");
User::Leave( KErrCancel );
}
MPresenceInfoFieldCollection& coll = persInfo->Fields();
DP_SDA("CPresencePluginData::NotifyToPrInfoL collection");
// Search own person info. Notice: Extend supported attributes later
TBool basicElementFound = EFalse;
TBool activitiesElementFound = EFalse;
TBool noteElemFound = EFalse;
DP_SDA("CPresencePluginData::NotifyToPrInfoL RPointerArray");
RPointerArray<MSimpleElement> elems;
DP_SDA("CPresencePluginData::NotifyToPrInfoL Push elems");
CleanupClosePushL( elems );
DP_SDA("CPresencePluginData::NotifyToPrInfoL aDocument");
TInt err = aDocument.SimpleElementsL( elems );
DP_SDA2("CPresencePluginData::NotifyToPrInfoL err %d", err);
RPointerArray<MSimpleElement> basicElems;
CleanupClosePushL( basicElems );
MSimpleElement* basicSimpleElem(NULL);
RPointerArray<MSimpleElement> activitiesElems;
CleanupClosePushL( activitiesElems );
MSimpleElement* activitiesSimpleElem(NULL);
MSimpleElement* noteSimpleElem(NULL);
if ( !err )
{
DP_SDA("CPresencePluginData::NotifyToPrInfoL, elements ok");
TInt count = elems.Count();
DP_SDA2("CPresencePluginData::NotifyToPrInfoL, element count: %d", count );
using namespace NPresencePlugin::NPresence;
MSimpleElement* elem = NULL;
TPtrC8 p8;
for ( TInt i = 0; i < count; i++ )
{
DP_SDA2("CPresencePluginData::NotifyToPrInfoL, handling elem[%d]", i );
elem = elems[i];
p8.Set( elem->LocalName());
if (!( p8.CompareF( KPresencePerson8 )) ||
!( p8.CompareF( KPresenceTuple8 )) )
{
// person element found
RPointerArray<MSimpleElement> elems2;
CleanupClosePushL( elems2 );
elem->SimpleElementsL( elems2 );
TInt count2 = elems2.Count();
DP_SDA2("CPresencePluginData::NotifyToPrInfoL count2 %d", count2);
for ( TInt j = 0; j < count2; j++ )
{
DP_SDA("CPresencePluginData::NotifyToPrInfoL 4");
//
MSimpleElement* elem2 = elems2[j];
//FIND BASIC/ACTIVITIES ELEMENT
if ( !elem2->LocalName().CompareF( KPresenceStatus8 ) &&
!basicElementFound )
{
DP_SDA("NotifyToPrInfoL PresenceStatus");
//Get elem2 childs
elem2->SimpleElementsL( basicElems );
TInt count3 = basicElems.Count(); //Child count
for ( TInt k = 0; k < count3; k++ )
{
MSimpleElement* tempElem = basicElems[k];
if ( !tempElem->LocalName().CompareF(
KPresenceBasic8 ))
{
DP_SDA("NotifyToPrInfoL basic elem true");
basicSimpleElem = basicElems[k];
basicElementFound = ETrue;
}
else if( !tempElem->LocalName().CompareF(
KPresenceActivities8 ))
{
DP_SDA("NotifyToPrInfoL activities under basic");
activitiesSimpleElem = basicElems[k];
activitiesElementFound = ETrue;
}
}
}
//FIND ACTIVITIES ELEMENT
if ( basicElementFound && !activitiesElementFound &&
!elem2->LocalName().CompareF( KPresenceActivities8 ) )
{
DP_SDA("NotifyToPrInfoL activities found outside basic");
elem2->SimpleElementsL( activitiesElems );
TInt count4 = activitiesElems.Count();
for ( TInt l = 0; l < count4; l++ )
{
activitiesSimpleElem = activitiesElems[l];
activitiesElementFound = ETrue;
DP_SDA("CPresencePluginData::NotifyToPrInfoL 6");
}
}
}
if ( basicElementFound && !noteSimpleElem )
{
noteSimpleElem = ResolveNoteElementL( elems2 );
}
DP_SDA("NotifyToPrInfoL ALL DONE");
CleanupStack::PopAndDestroy( &elems2 );
if ( basicElementFound && activitiesElementFound && noteElemFound )
{
DP_SDA("NotifyToPrInfoL ALL DONE break out");
//Just handle first status information from document
// In future server should support <timestamp>
//Also client should be can handle timestaps if there are present
break;
}
}
// Check note field
else if ( basicElementFound && !( p8.CompareF( KPresenceNote8 )) &&
!noteSimpleElem )
{
DP_SDA("NotifyToPrInfoL note field found outside tuple");
noteSimpleElem = elem;
}
}
}
if ( basicElementFound )
{
DP_SDA("NotifyToPrInfoL basic proceed to handling");
SingleUserStatusToXIMPL(
aPresenceFactory, basicSimpleElem,
activitiesSimpleElem, noteSimpleElem, coll );
}
CleanupStack::PopAndDestroy( &activitiesElems );
CleanupStack::PopAndDestroy( &basicElems );
CleanupStack::PopAndDestroy( &elems );
aPrInfo.SetPersonPresenceL( persInfo );
CleanupStack::Pop(); // >> persInfo
// TODO2: Notice: the following crashes in old PrFW version
/*
aPrInfo.AddDevicePresenceL ( NULL );
aPrInfo.AddServicePresenceL( NULL );
*/
DP_SDA("CPresencePluginData::NotifyToPrInfoL end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::CacheEntriesFromPrInfo
// ---------------------------------------------------------------------------
//
void CPresencePluginData::CacheEntriesFromPrInfo(
MPresenceInfo& aPrInfo,
MPresenceBuddyInfo2::TAvailabilityValues& aAvailability,
TPtr& aExtendedAvailability,
TPtr& aStatusMessage )
{
DP_SDA("CPresencePluginData::CacheEntriesFromPrInfoL");
DP_SDA(" -> CacheEntriesFromPrInfoL, fetch status enum field");
MPresenceInfoField* statusEnumInfoField = NULL;
MPersonPresenceInfo* presInfo = aPrInfo.PersonPresence();
if ( presInfo )
{
DP_SDA(" -> CacheEntriesFromPrInfoL, has person presence, get field");
presInfo->Fields().LookupFieldByFieldType(
statusEnumInfoField,
NPresenceInfo::NFieldType::KAvailabilityEnum );
DP_SDA(" -> CacheEntriesFromPrInfoL, fetch status enum field done, check item");
if ( statusEnumInfoField )
{
DP_SDA(" -> status enum field found");
const MPresenceInfoFieldValueEnum* availability =
TXIMPGetInterface< const MPresenceInfoFieldValueEnum >::From(
statusEnumInfoField->FieldValue(), MXIMPBase::EPanicIfUnknown );
switch( availability->Value() )
{
case NPresenceInfo::EAvailable:
{
DP_SDA(" -> status enum field => available");
aAvailability = MPresenceBuddyInfo2::EAvailable;
aExtendedAvailability.Copy( KDefaultAvailableStatus() );
}
break;
case NPresenceInfo::EBusy:
{
DP_SDA(" -> status enum field => busy");
aAvailability = MPresenceBuddyInfo2::EBusy;
aExtendedAvailability.Copy( KDndState() );
}
break;
case NPresenceInfo::EOnPhone:
{
DP_SDA(" -> status enum field => on phone");
aAvailability = MPresenceBuddyInfo2::EBusy;
aExtendedAvailability.Copy( KOnPhoneState() );
}
break;
case NPresenceInfo::EAway:
{
DP_SDA(" -> status enum field => away");
aAvailability = MPresenceBuddyInfo2::EBusy;
aExtendedAvailability.Copy( KAwayState() );
}
break;
case NPresenceInfo::EDoNotDisturb:
{
DP_SDA(" -> status enum field => dnd");
aAvailability = MPresenceBuddyInfo2::EBusy;
aExtendedAvailability.Copy( KDndState() );
}
break;
case NPresenceInfo::EOffline:
case NPresenceInfo::ENotAvailable:
default:
{
DP_SDA(" -> status enum field => offline/not available/default");
aAvailability = MPresenceBuddyInfo2::ENotAvailable;
aExtendedAvailability.Copy( KInvisibleState() );
}
break;
}
}
else
{
DP_SDA(" -> status enum not found => set unknown");
aAvailability = MPresenceBuddyInfo2::EUnknownAvailability;
aExtendedAvailability.Copy( KNullDesC() );
}
DP_SDA(" -> fetch status message field");
MPresenceInfoField* statusMsgInfoField = NULL;
presInfo->Fields().LookupFieldByFieldType(
statusMsgInfoField,
NPresenceInfo::NFieldType::KStatusMessage );
DP_SDA(" -> CacheEntriesFromPrInfoL, fetch status message field done, check item");
if ( statusMsgInfoField )
{
DP_SDA(" -> status msg field found");
const MPresenceInfoFieldValueText* statusMsg =
TXIMPGetInterface< const MPresenceInfoFieldValueText >::From(
statusMsgInfoField->FieldValue(), MXIMPBase::EPanicIfUnknown );
if ( statusMsg && statusMsg->TextValue().Length() )
{
DP_SDA(" -> status msg field found, copy content");
aStatusMessage.Copy( statusMsg->TextValue() );
}
}
else
{
DP_SDA(" -> status msg field not found, set empty");
aStatusMessage.Copy( KNullDesC() );
}
}
DP_SDA("CPresencePluginData::CacheEntriesFromPrInfoL out");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::SingleUserStatusToXIMPL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::SingleUserStatusToXIMPL(
MPresenceObjectFactory& aPresenceFactory,
MSimpleElement* aBasicElement,
MSimpleElement* aActivitiesElement,
MSimpleElement* aNoteElement,
MPresenceInfoFieldCollection& aCollection )
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL");
using namespace NPresenceInfo::NFieldType;
using namespace NPresencePlugin::NPresenceStates;
//Get aBasicElem content
HBufC* nodeContent = aBasicElement->ContentUnicodeL();
CleanupStack::PushL( nodeContent );
TBuf<KBufSize100> basicContentBuf;
basicContentBuf.Copy( *nodeContent );
DP_SDA2("SingleUserStatusToXIMPL basicContent %S", &basicContentBuf);
TBuf<KBufSize100> activitiesContentBuf;
if ( !aActivitiesElement )
{
activitiesContentBuf.Copy( KPresenceUnknow );
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL activities NULL");
}
else
{
activitiesContentBuf.Copy( aActivitiesElement->LocalName() );
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL else");
}
if ( nodeContent )
{
using namespace NPresenceInfo::NFieldType;
MPresenceInfoField* field = aPresenceFactory.NewInfoFieldLC();
field->SetFieldTypeL( KAvailabilityEnum );
// use mapped enums to pass status
MPresenceInfoFieldValueEnum* enumField =
aPresenceFactory.NewEnumInfoFieldLC();
// Busy case
if ( !nodeContent->Des().CompareF( KPresenceOpen ) &&
!activitiesContentBuf.CompareF ( KPresenceBusy ) )
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL open/busy");
enumField->SetValueL( NPresenceInfo::EBusy );
}
// On-The-Phone case
else if ( !nodeContent->Des().CompareF( KPresenceOpen ) &&
!activitiesContentBuf.CompareF ( KPresenceOnThePhone ) )
{
DP_SDA("CPresencePluginData::SingleUserStatusToXIMPL open/on-the-phone");
enumField->SetValueL( NPresenceInfo::EOnPhone );
}
//Away case
else if ( !nodeContent->Des().CompareF( KPresenceOpen ) &&
!activitiesContentBuf.CompareF ( KPresenceAway ) )
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL open/away");
enumField->SetValueL( NPresenceInfo::EAway );
}
//Dnd case
else if ( !nodeContent->Des().CompareF( KPresenceOpen ) &&
!activitiesContentBuf.CompareF ( KPresenceDoNotDisturb ) )
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL open/dnd");
enumField->SetValueL( NPresenceInfo::EDoNotDisturb );
}
// Unknown open
else if ( !nodeContent->Des().CompareF( KPresenceOpen ) &&
!activitiesContentBuf.CompareF ( KPresenceUnknow ) )
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL open/unknown");
enumField->SetValueL( NPresenceInfo::EAvailable );
}
// availale open
else if ( !nodeContent->Des().CompareF( KPresenceOpen ) &&
!activitiesContentBuf.CompareF ( KPresenceAvailable ) )
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL open/available");
enumField->SetValueL( NPresenceInfo::EAvailable );
}
//Unknown closed
else if ( !nodeContent->Des().CompareF( KPresenceClosed ) &&
!activitiesContentBuf.CompareF ( KPresenceUnknow ) )
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL closed/unknown");
enumField->SetValueL( NPresenceInfo::EOffline );
}
//Else set status according to basic status
else
{
if ( !nodeContent->Des().CompareF( KPresenceOpen ) )
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL else open");
enumField->SetValueL( NPresenceInfo::EAvailable );
}
else
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL else closed");
enumField->SetValueL( NPresenceInfo::ENotAvailable );
}
}
field->SetFieldValue( enumField );
aCollection.AddOrReplaceFieldL( field );
CleanupStack::Pop( 2 ); // >> field, enumField
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL check for note");
// Handle note field if found and buddy is "available".
if ( aNoteElement &&
NPresenceInfo::EOffline != enumField->Value() &&
NPresenceInfo::ENotAvailable != enumField->Value() )
{
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL note elems found");
// consider mapping note text to enum value if value not mapped
UserNoteToXIMPL( aPresenceFactory, aNoteElement, aCollection );
}
}
CleanupStack::PopAndDestroy( nodeContent );
DP_SDA(" CPresencePluginData::SingleUserStatusToXIMPL end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::UserNoteToXIMPL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::UserNoteToXIMPL(
MPresenceObjectFactory& aPresenceFactory,
MSimpleElement* aElement,
MPresenceInfoFieldCollection& aCollection )
{
DP_SDA(" CPresencePluginData::UserNoteToXIMPL IN");
HBufC* nodeContent = aElement->ContentUnicodeL();
CleanupStack::PushL( nodeContent );
if ( nodeContent )
{
DP_SDA(" CPresencePluginData::UserNoteToXIMPL - content found");
// Save note, convert from unicode
// notice: consider xml::lang-attribute
// note <-> KStatusMessage
// notice: no need to consider namespaces in XML?
using namespace NPresenceInfo::NFieldType;
DP_SDA(" CPresencePluginData::UserNoteToXIMPL - create fields");
MPresenceInfoField* field = aPresenceFactory.NewInfoFieldLC();
field->SetFieldTypeL( KStatusMessage );
MPresenceInfoFieldValueText* text =
aPresenceFactory.NewTextInfoFieldLC();
text->SetTextValueL( nodeContent->Des() );
field->SetFieldValue( text );
CleanupStack::Pop(); // >> text
aCollection.AddOrReplaceFieldL( field );
CleanupStack::Pop(); // >> field
DP_SDA(" -> fields added to collection");
}
CleanupStack::PopAndDestroy( nodeContent );
DP_SDA(" CPresencePluginData::UserNoteToXIMPL OUT");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::NotifyListToPrInfoL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::NotifyListToPrInfoL(
MXIMPObjectFactory& aFactory,
MPresenceObjectFactory& aPresenceFactory,
MSimplePresenceList& aList,
RPointerArray<MPresenceInfo>& aEntities,
RPointerArray<MXIMPIdentity>& aActives,
RPointerArray<MXIMPIdentity>& aTerminated )
{
DP_SDA(" CPresencePluginData::NotifyListToPrInfoL");
// Split array into individual prInfos
aEntities.Reset();
RPointerArray<MSimpleDocument> docs;
CleanupClosePushL( docs );
// get documents, ownership is not transferred.
aList.GetDocuments( docs );
TInt count = docs.Count();
// active presentities
for ( TInt i = 0; i < count; i++ )
{
MPresenceInfo* info =
aPresenceFactory.NewPresenceInfoLC();//<< info
aEntities.Append( info );
// aEntities may contain entries even this method leaves
CleanupStack::Pop();// >> info
NotifyToPrInfoL( aFactory, aPresenceFactory, *docs[i], *info );
// Add SIp identity to active users list
MXIMPIdentity* active = aFactory.NewIdentityLC();// << active
aActives.Append( active );
CleanupStack::Pop();// >> active
// Convert SIP entity URI from UTF to Unicode.
const TDesC8* pUri8 = (docs[i])->EntityURI();
HBufC16* uri16 = NULL;
uri16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *pUri8 );
CleanupStack::PushL( uri16 ); // << uri16
active->SetIdentityL( uri16->Des() );
CleanupStack::PopAndDestroy( uri16 );// >> uri16
}
using namespace NPresencePlugin::NPresence;
// Search "terminated" presentities
MSimpleMeta* meta = aList.MetaData();
// ownership in not transferred
if ( meta && !meta->LocalName().CompareF( KPresenceList8 ))
{
// list element found
RPointerArray<MSimpleElement> elems2;
CleanupClosePushL( elems2 );
meta->SimpleElementsL( elems2);
TInt count2 = elems2.Count();
for ( TInt i = 0; i < count2; i++ )
{
MSimpleElement* elem2 = elems2[i];
if ( !elem2->LocalName().CompareF( KPresenceResource8 ))
{
// resource element
RPointerArray<MSimpleElement> elems3;
CleanupClosePushL( elems3 );
meta->SimpleElementsL( elems3 );
TInt count3 = elems3.Count();
for ( TInt j=0; j < count3; j++ )
{
MSimpleElement* elem3 = elems3[i];
if ( !elem3->LocalName().CompareF( KPresenceInstance8 ))
{
// instance element
const TDesC8* stateVal =
elem3->AttrValue( KPresenceState8 );
if ( stateVal && stateVal->
CompareF( KPresenceTerminated8 ))
{
// get next entity if this is not state="terminated"
break;
}
// Save resource element URI into list of
// "terminated" users.
const TDesC8* uri8 = elem2->AttrValue( KPresenceUri8 );
MXIMPIdentity* terminated =
aFactory.NewIdentityLC();// << terminated
aTerminated.Append( terminated );
CleanupStack::Pop(); // >> terminated
// Convert SIP entity URI from UTF to Unicode.
HBufC16* uri16 = NULL;
uri16 =
CnvUtfConverter::ConvertToUnicodeFromUtf8L( *uri8 );
CleanupStack::PushL( uri16 ); // << uri16
terminated->SetIdentityL( uri16->Des() );
CleanupStack::PopAndDestroy( uri16 ); // >> uri16
}
}
CleanupStack::PopAndDestroy( &elems3 );
} // resource element
}// for (i); list element subelement
CleanupStack::PopAndDestroy( &elems2 );
}
CleanupStack::PopAndDestroy( &docs );
DP_SDA(" CPresencePluginData::NotifyListToPrInfoL end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::AddPrPersToSimpleDocumentL
// ---------------------------------------------------------------------------
//
void CPresencePluginData::AddPrPersToSimpleDocumentL(
const MPersonPresenceInfo* aInfo,
MSimpleDocument& aDocument,
const TDesC8& aSipId, TInt aTupleId )
{
DP_SDA("CPresencePluginData::AddPrPersToSimpleDocumentL start");
iNumBuf = aTupleId;
// notice: later: generate random id.
using namespace NPresencePlugin::NPresence;
using namespace NPresenceInfo::NFieldType;
const MPresenceInfoFieldCollection& coll = aInfo->Fields();
const MPresenceInfoField* statusEmumField = NULL;
const MPresenceInfoField* messageField = NULL;
TInt myCount = coll.FieldCount();
for ( TInt i = 0; i < myCount; i++ )
{
DP_SDA("CPresencePluginData::AddPrPersToSimpleDocumentL 1");
const MPresenceInfoField& field = coll.FieldAt( i );
const TDesC8& fieldType = field.FieldType();
TBuf<KBufSize100> printBuf;
printBuf.Copy( fieldType );
if ( !fieldType.Compare( KAvatar ) )
{
// Do nothing in sawfis, maybe later?
}
else if ( !fieldType.Compare( KAvailabilityEnum ) )
{
DP_SDA("AddPrPersToSimpleDocumentL Avaibility");
statusEmumField = &field;
DP_SDA("AddPrPersToSimpleDocumentL Avaibility done");
}
else if ( !fieldType.Compare( KStatusMessage ) )
{
DP_SDA("AddPrPersToSimpleDocumentL statusmessage");
messageField = &field;
}
}
if ( statusEmumField )
{
DoCreateDocumentL( aDocument, aSipId,
statusEmumField, messageField );
}
DP_SDA("CPresencePluginData::AddPrPersToSimpleDocumentL end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::CreatePresenceUri8LC
// ---------------------------------------------------------------------------
//
HBufC8* CPresencePluginData::CreatePresenceUri8LC(
const TDesC8& aPresentityUri )
{
DP_SDA("CPresencePluginData::CreatePresenceUri8LC ");
const TInt KMyLenSipPrefix = 4;
const TInt KMyLenSipsPrefix = 5;
_LIT8( KMySip8, "sip:" );
_LIT8( KMySips8, "sips:" );
TInt uriLen = aPresentityUri.Length();
DP_SDA2( "CPresencePluginData::CreatePresenceUri8LC - param length: %d ", uriLen );
//For debugging purposes
//TBuf<256> tmpPresentityUri;
//tmpPresentityUri.Copy( aPresentityUri );
//DP_SDA2( "CPresencePluginData::CreatePresenceUri8LC - URI: %S ", &tmpPresentityUri );
HBufC8* buf = HBufC8::NewLC( uriLen );
TPtr8 pBuf( buf->Des() );
//SIP uri check
if ( !aPresentityUri.Left( KMyLenSipPrefix ).CompareF( KMySip8 ) )
{
DP_SDA("CPresencePluginData::CreatePresenceUri8LC (sip:) prefix in SIP URI ");
pBuf.Append( aPresentityUri );
}
else if ( !aPresentityUri.Left( KMyLenSipsPrefix ).CompareF( KMySips8 ) )
{
DP_SDA( "CPresencePluginData::CreatePresenceUri8LC (sips:) prefix in SIP URI " );
pBuf.Append( aPresentityUri );
}
else // No prefix, strange ...
{
DP_SDA( "CPresencePluginData::CreatePresenceUri8LC NO prefix in SIP URI, adding... " );
// Maybe should check which prefix to use,
// but assume that no secure is used if prefix missing
TInt len = aPresentityUri.Length() + KMyLenSipPrefix;
buf = buf->ReAllocL( len );
//update pointer after realloc
CleanupStack::Pop( 1 );
CleanupStack::PushL( buf );
// Since realloc may have changed the location in memory
// we must also reset ptr
pBuf.Set( buf->Des() );
pBuf.Append( KMySip8 );
pBuf.Append( aPresentityUri );
}
return buf;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::RemovePrefixLC
// ---------------------------------------------------------------------------
//
HBufC16* CPresencePluginData::RemovePrefixLC(
const TDesC& aPresentityUri )
{
DP_SDA2("CPresencePluginData::RemovePrefixLC, uri: %S", &aPresentityUri );
HBufC* withouPrefix = HBufC::NewLC( KBufSize255 );
TPtr withouPrefixPtr( withouPrefix->Des() );
TInt prefixLocation = aPresentityUri.Locate( ':' );
DP_SDA2("CPresencePluginData::RemovePrefixLC, prefix pos: %d", prefixLocation );
if ( KErrNotFound != prefixLocation )
{
DP_SDA("CPresencePluginData::RemovePrefixLC - has prefix");
withouPrefixPtr.Copy( aPresentityUri.Mid( prefixLocation+1 ) );
DP_SDA("CPresencePluginData::RemovePrefixLC - copy ok");
}
else
{
DP_SDA("CPresencePluginData::RemovePrefixLC - has no prefix");
withouPrefixPtr.Copy( aPresentityUri );
}
//DP_SDA2("CPresencePluginData::RemovePrefixLC - returns %S", *withouPrefix );
return withouPrefix;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::DoCreateDocumentL()
// ---------------------------------------------------------------------------
//
void CPresencePluginData::DoCreateDocumentL(
MSimpleDocument& aDocument,
const TDesC8& aSipId,
const MPresenceInfoField* aStatusField,
const MPresenceInfoField* aMessageField )
{
DP_SDA("CPresencePluginData::DoCreateDocumentL ");
const TInt KNumBuf = 20;
const TInt KTupleBuf = 10;
using namespace NPresencePlugin::NPresence;
using namespace NPresencePlugin::NPresenceStates;
using namespace NPresenceInfo::NFieldType;
TBuf<KNumBuf> numBuf;
TBuf<KTupleBuf> tupleBuf;
tupleBuf.Copy( KIndent );
numBuf.Num( iNumBuf );
tupleBuf.Append( numBuf );
DP_SDA2("CPresencePluginData::DoCreateDocumentL id %d", iNumBuf);
DP_SDA("CPresencePluginData::DoCreateDocumentL 2");
//Add tuple id to document
MSimpleElement* tuple = aDocument.AddSimpleElementL( KPresenceTuple8 );
CleanupClosePushL( *tuple );
tuple->AddAttrL( KPresenceId8, tupleBuf);
//Presence status field
MSimpleElement* status = tuple->AddSimpleElementL( KPresenceStatus8 );
CleanupClosePushL( *status );
//basic field
MSimpleElement* basic = status->AddSimpleElementL( KPresenceBasic8 );
CleanupClosePushL( *basic );
basic->SetContentUnicodeL( DoCheckBasicStatusValueL( *aStatusField ) );
DP_SDA("CPresencePluginData::DoCreateDocumentL Basic ok, check msg");
if ( aMessageField )
{
DP_SDA("CPresencePluginData::DoCreateDocumentL message field");
//Creating note
MSimpleElement* note =
aDocument.AddSimpleElementL( KPresenceNote8 );
CleanupClosePushL( *note );
// Get status msg field from info field
const MPresenceInfoFieldValueText* textField =
TXIMPGetInterface<
const MPresenceInfoFieldValueText >::From(
aMessageField->FieldValue(),
MXIMPBase::EPanicIfUnknown );
note->SetContentUnicodeL( textField->TextValue() );
CleanupStack::PopAndDestroy( note );
}
/* Basic model example
<tuple id="c8dqui">
<status>
<basic>open</basic>
</status>
<ts:basic>closed</ts:basic>
</ts:timed-status>
<contact>sip:someone@example.com</contact>
</tuple>
<note>sleeping</note>
</presence>
*/
DP_SDA("CPresencePluginData::DoCreateDocumentL Rich presence person");
//Creatin person presence field
MSimpleElement* pers =
aDocument.AddSimpleElementL( KSimpleNsPDM, KPresencePerson8 );
CleanupClosePushL( *pers );
TBuf<KBufSize10> buf;
TBuf<KBufSize20> personId;
personId.Copy( KPersonId );
buf.Num( iNumBuf );
personId.Append( buf );
pers->AddAttrL( KPresenceId8, personId );
DP_SDA("CPresencePluginData::DoCreateDocumentL Rich presence person ok");
HBufC8* urlBuf = CreatePresenceUri8LC( aSipId );
DP_SDA("CPresencePluginData::DoCreateDocumentL Push urlBuf");
aDocument.SetEntityURIL( urlBuf->Des() );
DP_SDA("CPresencePluginData::DoCreateDocumentL 2");
DP_SDA("CPresencePluginData::DoCreateDocumentLC Rich presence activities");
MSimpleElement* activ = pers->AddSimpleElementL(
KSimpleNsRPID, KPresenceActivities8 );
CleanupClosePushL( *activ );
//unknown used if person presence is just open or closed
MSimpleElement* unknown = activ->AddSimpleElementL(
KSimpleNsRPID, DoCheckActivitiesValueL( *aStatusField ) );
DP_SDA("CPresencePluginData::DoCreateDocumentL, unknown/status element created");
CleanupClosePushL( *unknown );
DP_SDA("CPresencePluginData::DoCreateDocumentL Destroy unknown");
CleanupStack::PopAndDestroy( unknown );
DP_SDA("CPresencePluginData::DoCreateDocumentL Destroy activ");
CleanupStack::PopAndDestroy( activ );
DP_SDA("CPresencePluginData::DoCreateDocumentL Destroy urlBuf");
CleanupStack::PopAndDestroy( urlBuf );
DP_SDA("CPresencePluginData::DoCreateDocumentL Destroy pers");
CleanupStack::PopAndDestroy( pers );
DP_SDA("CPresencePluginData::DoCreateDocumentL Rich presence activities ok");
DP_SDA("CPresencePluginData::DoCreateDocumentL Destroy basic");
CleanupStack::PopAndDestroy( basic );
DP_SDA("CPresencePluginData::DoCreateDocumentL Destroy status");
CleanupStack::PopAndDestroy( status );
DP_SDA("CPresencePluginData::DoCreateDocumentL Destroy tuple");
CleanupStack::PopAndDestroy( tuple );
DP_SDA("CPresencePluginData::DoCreateDocumentL end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::DoCheckBasicStatusValueL()
// ---------------------------------------------------------------------------
//
TPtrC CPresencePluginData::DoCheckBasicStatusValueL(
const MPresenceInfoField& aField )
{
using namespace NPresencePlugin::NPresence;
using namespace NPresencePlugin::NPresenceStates;
using namespace NPresenceInfo::NFieldType;
TPtrC basicStatus( KPresenceOpen ); //default status open
//First check what is person status value
const MXIMPBase& storage = aField.FieldValue();
const MPresenceInfoFieldValueEnum* enumObject =
TXIMPGetInterface< const MPresenceInfoFieldValueEnum >::
From( storage,MXIMPBase::EReturnNullIfUnknown );
__ASSERT_ALWAYS( NULL != enumObject, User::Leave( KErrArgument ) );
DP_SDA2(" DoCheckBasicStatusValueL - enumValue: %d", enumObject->Value() );
switch ( enumObject->Value() )
{
case NPresenceInfo::EAvailable:
{
DP_SDA("DoCheckBasicStatusValueL stopPublish false status open");
iConnObs.SetStopPublishState( EFalse );
basicStatus.Set( KPresenceOpen );
}
break;
case NPresenceInfo::EOffline:
case NPresenceInfo::EHidden:
case NPresenceInfo::ENotAvailable:
{
//If state is closed we can stop publish
//if client is going to offline
DP_SDA("DoCheckBasicStatusValueL stopPublish true status Closed");
iConnObs.SetStopPublishState( ETrue );
basicStatus.Set( KPresenceClosed );
}
break;
default:
{
DP_SDA("DoCheckBasicStatusValueL stopPublish false else open");
iConnObs.SetStopPublishState( EFalse );
basicStatus.Set( KPresenceOpen );
}
break;
}
return basicStatus;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::DoCheckActivitiesValueL()
// ---------------------------------------------------------------------------
//
TPtrC8 CPresencePluginData::DoCheckActivitiesValueL(
const MPresenceInfoField& aField )
{
using namespace NPresencePlugin::NPresence;
using namespace NPresencePlugin::NPresenceStates;
using namespace NPresenceInfo::NFieldType;
TPtrC8 activities( KPresenceUnknow8 ); //default activities unknown
const MXIMPBase& storage = aField.FieldValue();
const MPresenceInfoFieldValueEnum* enumObject =
TXIMPGetInterface< const MPresenceInfoFieldValueEnum >::
From( storage,MXIMPBase::EReturnNullIfUnknown );
__ASSERT_ALWAYS( NULL != enumObject, User::Leave( KErrArgument ) );
DP_SDA2(" DoCheckActivitiesValueL - enumValue: %d", enumObject->Value() );
switch ( enumObject->Value() )
{
case NPresenceInfo::EAvailable:
{
DP_SDA("DoCheckActivitiesValueL - available, set publish");
iConnObs.SetStopPublishState( EFalse );
DP_SDA("DoCheckActivitiesValueL - available, set value");
activities.Set( KPresenceUnknow8 );
DP_SDA("DoCheckActivitiesValueL - available, ok");
}
break;
case NPresenceInfo::EOffline:
case NPresenceInfo::ENotAvailable:
{
DP_SDA("DoCheckActivitiesValueL - offline/not available");
iConnObs.SetStopPublishState( ETrue );
activities.Set( KPresenceUnknow8 );
}
break;
case NPresenceInfo::EBusy:
{
DP_SDA("DoCheckActivitiesValueL - busy");
iConnObs.SetStopPublishState( EFalse );
activities.Set( KPresenceBusy8 );
}
break;
case NPresenceInfo::EExtAway:
case NPresenceInfo::EAway:
{
DP_SDA("DoCheckActivitiesValueL - away");
iConnObs.SetStopPublishState( EFalse );
activities.Set( KPresenceAway8 );
}
break;
case NPresenceInfo::EOnPhone:
{
DP_SDA("DoCheckActivitiesValueL - on phone");
iConnObs.SetStopPublishState( EFalse );
activities.Set( KPresenceOnThePhone8 );
}
break;
case NPresenceInfo::EDoNotDisturb:
{
DP_SDA("DoCheckActivitiesValueL - dnd");
iConnObs.SetStopPublishState( EFalse );
activities.Set( KPresenceDoNotDisturb8 );
}
break;
default:
{
DP_SDA("DoCheckActivitiesValueL default => unknown");
iConnObs.SetStopPublishState( EFalse );
activities.Set( KPresenceUnknow8 );
}
break;
}
DP_SDA("DoCheckActivitiesValueL - done and return");
return activities;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::DoCheckNoteValueL()
// ---------------------------------------------------------------------------
//
TPtrC CPresencePluginData::DoCheckNoteValueL(
const MPresenceInfoField& aField )
{
using namespace NPresencePlugin::NPresence;
using namespace NPresencePlugin::NPresenceStates;
using namespace NPresenceInfo::NFieldType;
TPtrC note( KPresenceUnknow ); //default activities unknown
//First check what is person status value
const MXIMPBase& storage = aField.FieldValue();
const MPresenceInfoFieldValueText* text =
TXIMPGetInterface< const MPresenceInfoFieldValueText >::
From( storage,MXIMPBase::EReturnNullIfUnknown );
__ASSERT_ALWAYS( NULL != text, User::Leave( KErrArgument ) );
TBuf<KBufSize200> buffer;
buffer.Copy( text->TextValue() );
//Check if status is closed
if( !buffer.CompareF( KPresenceClosed ) )
{
//If state is closed we can stop publish
//if client is going to offline
DP_SDA("DoCheckNoteValueL stopPublish true closed");
iConnObs.SetStopPublishState( ETrue );
note.Set( KPresenceOffline );
}
else if( !buffer.CompareF( KPresenceOpen ) )
{
DP_SDA("DoCheckNoteValueL stopPublish false open");
iConnObs.SetStopPublishState( EFalse );
note.Set( KPresenceAvailable );
}
else if( !buffer.CompareF( KPresenceBusy ) )
{
DP_SDA("DoCheckNoteValueL activities BUSY");
iConnObs.SetStopPublishState( EFalse );
note.Set( KPresenceBusy );
}
else if( !buffer.CompareF( KPresenceOnThePhone ) )
{
DP_SDA("DoCheckNoteValueL activities OnThePhone");
iConnObs.SetStopPublishState( EFalse );
note.Set( KPresenceOnThePhone );
}
else if( !buffer.CompareF( KPresenceAway ) )
{
DP_SDA("DoCheckNoteValueL activities OnThePhone");
iConnObs.SetStopPublishState( EFalse );
note.Set( KPresenceAway );
}
else
{
DP_SDA("DoCheckNoteValueL stopPublish false");
iConnObs.SetStopPublishState( EFalse );
note.Set( KPresenceUnknow );
}
return note;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::GenerateTupleId()
// ---------------------------------------------------------------------------
//
TInt CPresencePluginData::GenerateTupleId()
{
// Generate unique session tuple id
DP_SDA("CPresencePluginData::GenerateTupleId start");
const TInt KMaxRand = KMaxNumber;
TInt64 seed;
TTime time;
time.HomeTime();
seed = time.Int64();
TInt random = Math::Rand( seed ) % KMaxRand;
DP_SDA("CPresencePluginData::GenerateTupleId 1");
return random;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::ServiceId()
// ---------------------------------------------------------------------------
//
TInt CPresencePluginData::ServiceId()
{
return iServiceId;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::ServiceNameLC()
// ---------------------------------------------------------------------------
//
HBufC* CPresencePluginData::ServiceNameLC( TInt aServiceId ) const
{
CSPSettings* spSettings = CSPSettings::NewLC();
CSPEntry* entry = CSPEntry::NewLC();
HBufC* serviceName = NULL;
User::LeaveIfError( spSettings->FindEntryL( aServiceId, *entry ) );
serviceName = entry->GetServiceName().AllocL();
CleanupStack::PopAndDestroy( entry );
CleanupStack::PopAndDestroy( spSettings );
CleanupStack::PushL( serviceName );
return serviceName;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::ResolveCacheXspIdentifierL()
// ---------------------------------------------------------------------------
//
HBufC* CPresencePluginData::ResolveCacheXspIdentifierL(
const TDesC& aIdentity ) const
{
DP_SDA( "CPresencePluginData::ResolveCacheXspIdentifierL" );
CSPSettings* spSettings = CSPSettings::NewLC();
CSPEntry* entry = CSPEntry::NewLC();
User::LeaveIfError( spSettings->FindEntryL( iServiceId, *entry ) );
TInt cacheUriLength = ( entry->GetServiceName().Length() +
aIdentity.Length() + 1 );
HBufC* cacheUri = HBufC::NewL( cacheUriLength );
TPtr cacheUriPtr( cacheUri->Des() );
cacheUriPtr.Append( entry->GetServiceName() );
cacheUriPtr.Append( ':' );
cacheUriPtr.Append( aIdentity );
CleanupStack::PopAndDestroy( entry );
CleanupStack::PopAndDestroy( spSettings );
DP_SDA2( "CPresencePluginData::ResolveCacheXspIdentifierL returns: %S", cacheUri );
return cacheUri;
}
// ---------------------------------------------------------------------------
// CPresencePluginData::WriteBlockItemsToCacheL()
// ---------------------------------------------------------------------------
//
void CPresencePluginData::WriteStatusToCacheL(
const TDesC& aPresentityId,
MPresenceBuddyInfo2::TAvailabilityValues aAvailability,
const TDesC& aAvailabilityText,
const TDesC& aStatusMessage )
{
DP_SDA( "CPresencePluginData::WriteStatusToCacheL start" );
DP_SDA2( "CPresencePluginData::WriteStatusToCacheL, aStatus: %d",
aAvailability );
DP_SDA2( "CPresencePluginData::WriteStatusToCacheL, availabilityText: %S",
&aAvailabilityText );
DP_SDA2( "CPresencePluginData::WriteStatusToCacheL, statusMessage: %S",
&aStatusMessage );
TBool updateCache( ETrue );
HBufC* cacheUri = ResolveCacheXspIdentifierL( aPresentityId );
CleanupStack::PushL( cacheUri );
DP_SDA(" -> WriteStatusToCacheL - read previous values from cache");
// Read previous values from cache
MPresenceBuddyInfo2* previousPresInfo =
iPresenceCacheReader->PresenceInfoLC( *cacheUri );
if ( previousPresInfo )
{
DP_SDA(" -> WriteStatusToCacheL - get availability value");
MPresenceBuddyInfo2::TAvailabilityValues availability =
previousPresInfo->Availability();
DP_SDA(" -> WriteStatusToCacheL - get availability text");
TPtrC availabilityText = previousPresInfo->AvailabilityText();
DP_SDA(" -> WriteStatusToCacheL - get status message");
TPtrC statusMessage = previousPresInfo->StatusMessage();
CleanupStack::PopAndDestroy(); //previousPresInfo
DP_SDA2( "CPresencePluginData::WriteStatusToCacheL, OLD STATUS: %d",
availability );
DP_SDA2( "CPresencePluginData::WriteStatusToCacheL, OLD AVAILABILITY TEXT: %S",
&availabilityText );
DP_SDA2( "CPresencePluginData::WriteStatusToCacheL, OLD STATUS MESSAGE: %S",
&statusMessage );
if ( ( aAvailability == availability ) &&
( aAvailabilityText.Compare( availabilityText ) == 0 ) &&
( aStatusMessage.Compare( statusMessage ) == 0 ))
{
DP_SDA(" -> WriteStatusToCacheL - no need to update cache");
updateCache = EFalse;
}
}
if ( updateCache )
{
MPresenceBuddyInfo2* newPresInfo = MPresenceBuddyInfo2::NewLC();
newPresInfo->SetIdentityL( *cacheUri );
DP_SDA(" -> WriteStatusToCacheL - update cache");
TBuf<KBufSize20> buf;
TBool handled = EFalse;
buf.Copy( KBlockedExtensionValue );
if( aAvailabilityText.Compare( buf ) == 0 )
{
DP_SDA( " -> WriteStatusToCacheL - set Blocked" );
newPresInfo->SetAnyFieldL( KExtensionKey, KBlockedExtensionValue );
handled = ETrue;
}
buf.Copy( KPendingRequestExtensionValue );
if ( aAvailabilityText.Compare( buf ) == 0 )
{
DP_SDA( " -> WriteStatusToCacheL - set Pending request" );
newPresInfo->SetAnyFieldL( KExtensionKey, KPendingRequestExtensionValue );
handled = ETrue;
}
if ( !handled )
{
DP_SDA2( " -> WriteStatusToCacheL - set availability text: %S", &aAvailabilityText );
newPresInfo->SetAvailabilityL( aAvailability, aAvailabilityText );
}
if ( aStatusMessage.Length() )
{
DP_SDA2( " -> WriteStatusToCacheL - set status message: %S", &aStatusMessage );
newPresInfo->SetStatusMessageL( aStatusMessage );
}
DP_SDA( " -> WriteStatusToCacheL - write presence to cache" );
TInt cacheError = iPresenceCacheWriter->WritePresenceL( newPresInfo );
DP_SDA2( "CPresencePluginEntityWatcher::WriteStatusToCacheL error: %d",
cacheError );
DP_SDA( " -> destroy buddy info" );
CleanupStack::PopAndDestroy(); // newPresInfo
}
DP_SDA(" -> destroy uri");
CleanupStack::PopAndDestroy( cacheUri );
DP_SDA("CPresencePluginData::WriteStatusToCacheL end");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::RemoveCacheL()
// ---------------------------------------------------------------------------
//
void CPresencePluginData::RemoveCacheL()
{
DP_SDA("CPresencePluginData::RemoveCacheL");
// Resolve service name (cache xsp identifier)
CSPSettings* spSettings = CSPSettings::NewL();
CleanupStack::PushL( spSettings );
CSPEntry* entry = CSPEntry::NewLC();
DP_SDA2(" -> RemoveCacheL look for service: %d", ServiceId() );
spSettings->FindEntryL( ServiceId(), *entry );
DP_SDA(" -> RemoveCacheL cache xsp identifier found");
TInt cacheUriLength = entry->GetServiceName().Length();
DP_SDA2(" -> cache uri length: %d", cacheUriLength );
HBufC* cacheUri = HBufC::NewLC( cacheUriLength );
TPtr cacheUriPtr( cacheUri->Des() );
DP_SDA(" -> RemoveCacheL - form cache entry");
cacheUriPtr.Append( entry->GetServiceName() );
DP_SDA(" -> RemoveCacheL - delete cache entries");
TInt error = iPresenceCacheWriter->DeleteService( cacheUriPtr );
DP_SDA2(" -> RemoveCacheL - delete error: %d", error );
CleanupStack::PopAndDestroy( cacheUri );
DP_SDA(" -> destroy sp entry");
CleanupStack::PopAndDestroy( entry );
DP_SDA(" -> destroy sp");
CleanupStack::PopAndDestroy( spSettings );
DP_SDA("CPresencePluginData::RemoveCacheL out");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::DeletePresenceL()
// ---------------------------------------------------------------------------
//
void CPresencePluginData::DeletePresenceL( const TDesC& aIdentity )
{
DP_SDA("CPresencePluginData::DeletePresenceL");
// Resolve service name (cache xsp identifier)
CSPSettings* spSettings = CSPSettings::NewL();
CleanupStack::PushL( spSettings );
CSPEntry* entry = CSPEntry::NewLC();
DP_SDA2(" -> DeletePresenceL look for service: %d", ServiceId() );
spSettings->FindEntryL( ServiceId(), *entry );
DP_SDA(" -> DeletePresenceL cache xsp identifier found");
TInt cacheUriLength = ( entry->GetServiceName().Length() +
aIdentity.Length() + 1 );
DP_SDA2(" -> cache uri length: %d", cacheUriLength );
HBufC* cacheUri = HBufC::NewLC( cacheUriLength );
TPtr cacheUriPtr( cacheUri->Des() );
DP_SDA(" -> DeletePresenceL - form cache entry");
cacheUriPtr.Append( entry->GetServiceName() );
cacheUriPtr.Append( ':' );
cacheUriPtr.Append( aIdentity );
iPresenceCacheWriter->DeletePresenceL( cacheUriPtr );
CleanupStack::PopAndDestroy( cacheUri );
CleanupStack::PopAndDestroy( entry );
DP_SDA(" -> destroy sp");
CleanupStack::PopAndDestroy( spSettings );
DP_SDA("CPresencePluginData::DeletePresenceL out");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::StorePresenceOwnPresenceL()
// ---------------------------------------------------------------------------
//
void CPresencePluginData::StorePresenceOwnPresenceL(
const TUint aServiceId,
NPresenceInfo::TAvailabilityValues aAvailability,
const TDesC& aStatusMessage )
{
DP_SDA("CPresencePluginData::StorePresenceOwnPresenceL IN");
DP_SDA2(" -> aServiceId: %d", aServiceId );
DP_SDA2(" -> SAVE AVAILABILITY VALUE: %d", aAvailability );
DP_SDA2(" -> SAVE STATUS MESSAGE: %S", &aStatusMessage );
MVIMPSTSettingsStore* settings = CVIMPSTSettingsStore::NewLC();
DP_SDA("CPresencePluginData::StorePresenceOwnPresenceL 1");
// Store availability value to uiservicetabsettings
TInt availabilityInt = ( ( TInt ) aAvailability );
User::LeaveIfError( settings->SetL(
aServiceId, EServicePresenceAvailablilityValue, availabilityInt ) );
DP_SDA("CPresencePluginData::StorePresenceOwnPresenceL 2");
// Store custom status message to uiservicetabsettings
User::LeaveIfError( settings->SetL(
aServiceId, EServiceCustomStatusMessage, aStatusMessage ) );
CleanupStack::PopAndDestroy(); //settings
DP_SDA("CPresencePluginData::StorePresenceOwnPresenceL OUT");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::ReadDocumentIdL()
// ---------------------------------------------------------------------------
//
void CPresencePluginData::ReadDocumentIdL(
const TInt aServiceId,
TDes8& aDocumentId )
{
DP_SDA("CPresencePluginData::ReadDocumentIdL IN");
DP_SDA2(" -> aServiceId: %d", aServiceId );
MVIMPSTSettingsStore* settings = CVIMPSTSettingsStore::NewLC();
RBuf8 documentId;
CleanupClosePushL( documentId );
documentId.CreateL( KBufSize255 );
TInt error = settings->GetL(
aServiceId, EServicePresenceSessionIdentifier, documentId );
DP_SDA2(" -> ERROR: %d", error );
DP_SDA2(" -> DOCUMENT ID LENGTH: %d", documentId.Length() );
if ( !error && documentId.Length() )
{
aDocumentId.Copy( documentId );
TBuf<KBufSize255> printDocumentId;
printDocumentId.Copy( aDocumentId );
DP_SDA("CPresencePluginData::ReadDocumentIdL - 1");
DP_SDA2(" -> READ DOCUMENT ID: %S", &printDocumentId );
}
else if ( KErrNotFound == error || !documentId.Length() )
{
DP_SDA("CPresencePluginData::ReadDocumentIdL - 2");
// If document id lenght is zero (KNullDesC8) or error
// is KErrNotFound leave with KErrNotFound
User::Leave( KErrNotFound );
}
else
{
User::Leave( error );
}
CleanupStack::PopAndDestroy( &documentId );
CleanupStack::PopAndDestroy(); //settings
DP_SDA("CPresencePluginData::ReadDocumentIdL OUT");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::DeletePresenceVariablesL()
// ---------------------------------------------------------------------------
//
void CPresencePluginData::DeletePresenceVariablesL( const TInt aServiceId )
{
DP_SDA("CPresencePluginData::DeletePresenceVariablesL IN");
DP_SDA2(" -> aServiceId: %d", aServiceId );
MVIMPSTSettingsStore* settings = CVIMPSTSettingsStore::NewLC();
// Reset availability value in uiservicetabsettings
User::LeaveIfError( settings->SetL(
aServiceId, EServicePresenceAvailablilityValue, KErrNotFound ) );
// Reset status message in uiservicetabsettings
User::LeaveIfError( settings->SetL(
aServiceId, EServiceCustomStatusMessage, KNullDesC ) );
// Reset document id value in uiservicetabsettings
User::LeaveIfError( settings->SetL(
aServiceId, EServicePresenceSessionIdentifier, KNullDesC8 ) );
CleanupStack::PopAndDestroy(); // settings
DP_SDA("CPresencePluginData::DeletePresenceVariablesL OUT");
}
// ---------------------------------------------------------------------------
// CPresencePluginData::ResolveNoteElementL
// Returns <note> element corresponding current locale or first <note>
// element if better match is not found.
// ---------------------------------------------------------------------------
//
MSimpleElement* CPresencePluginData::ResolveNoteElementL(
const RPointerArray<MSimpleElement>& aElements ) const
{
DP_SDA("CPresencePluginData::ResolveNoteElementL" )
MSimpleElement* bestMatch = NULL;
MSimpleElement* secondBestMatch = NULL;
for ( TInt i = aElements.Count() - 1; i >= 0 && NULL == bestMatch; i-- )
{
MSimpleElement* element = aElements[i];
using namespace NPresencePlugin::NPresence;
if ( 0 == element->LocalName().CompareF( KPresenceNote8 ) )
{
if ( IsElementLanguageValidForCurrentLocaleL( *element ) )
{
DP_SDA("CPresencePluginData::ResolveNoteElementL, BEST MATCH.")
bestMatch = element;
}
else
{
secondBestMatch = element;
}
}
}
return ( bestMatch ? bestMatch : secondBestMatch );
}
// ---------------------------------------------------------------------------
// CPresencePluginData::IsElementLanguageValidForCurrentLocaleL
// ---------------------------------------------------------------------------
//
TBool CPresencePluginData::IsElementLanguageValidForCurrentLocaleL(
MSimpleElement& aElement ) const
{
DP_SDA( "CPresencePluginData::IsElementLanguageValidForCurrentLocaleL" )
TBool isLanguageResolved = EFalse;
_LIT8( KLanguageAttribute, "xml:lang" );
TLanguage language = User::Language();
RPointerArray<MSimpleAttribute> attributes;
CleanupClosePushL( attributes );
aElement.SimpleAttributesL( attributes );
for ( TInt i = attributes.Count() - 1; i >= 0 && !isLanguageResolved; i-- )
{
if ( 0 == KLanguageAttribute().CompareF( attributes[i]->Name() ) )
{
const TDesC8& attributeValue = attributes[i]->Value();
for ( TInt index = 0; index < KLanguageCodeMappingsCount; index++ )
{
if ( language == KLanguageCodeMappings[index].SymbianLanguageCode() &&
0 == attributeValue.CompareF(
KLanguageCodeMappings[index].IsoLanguageCode() ) )
{
isLanguageResolved = ETrue;
}
}
}
}
CleanupStack::Pop( &attributes );
return isLanguageResolved;
}
// End of file