presencefwsimpleadpt/src/simpleplugindata.cpp
branchRCL_3
changeset 18 fbd2e7cec7ef
equal deleted inserted replaced
17:2669f8761a99 18:fbd2e7cec7ef
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    SIMPLE Protocol implementation for Presence Framework
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 // *** system include files go here:
       
    23 #include <e32std.h>
       
    24 #include <s32strm.h>
       
    25 #include <utf.h>
       
    26 
       
    27 #include <presenceobjectfactory.h>
       
    28 #include <presenceinfo.h>
       
    29 #include <personpresenceinfo.h>
       
    30 #include <presenceinfofieldcollection.h>
       
    31 #include <presenceinfofield.h>
       
    32 #include <presenceinfofieldvaluetext.h>
       
    33 #include <presenceinfofieldvalueenum.h>
       
    34 #include <presenceinfofieldvaluebinary.h>
       
    35 #include <presenceinfofieldvalueenum.h>
       
    36 #include <presenceerrors.hrh>
       
    37 
       
    38 #include <ximpobjectfactory.h>
       
    39 #include <ximpidentity.h>
       
    40 #include <ximpdatasubscriptionstate.h>
       
    41 #include <ximpprotocolconnectionhost.h>
       
    42 #include <ximpstatus.h>
       
    43 
       
    44 #include <msimpledocument.h>
       
    45 #include <msimpleelement.h>
       
    46 #include <msimplepresencelist.h>
       
    47 #include <msimplemeta.h>
       
    48 #include <msimplecontent.h>
       
    49 #include <simpleutils.h>
       
    50 #include <simplefactory.h>
       
    51 
       
    52 #include "simpleplugindata.h"
       
    53 #include "simpleplugincommon.h"
       
    54 #include "simpleplugindebugutils.h"
       
    55 
       
    56 
       
    57 // ----------------------------------------------------------
       
    58 // CSimplePluginData::CSimplePluginData
       
    59 // ----------------------------------------------------------
       
    60 //
       
    61 CSimplePluginData::CSimplePluginData( )
       
    62     {
       
    63     }
       
    64 
       
    65 // ---------------------------------------------------------------------------
       
    66 // CSimplePluginData::~CSimplePluginData
       
    67 // ---------------------------------------------------------------------------
       
    68 //
       
    69 CSimplePluginData::~CSimplePluginData()
       
    70     {
       
    71 
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // CSimplePluginData::NewL
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 CSimplePluginData* CSimplePluginData::NewL( )
       
    79     {
       
    80     CSimplePluginData* self = CSimplePluginData::NewLC( );
       
    81     CleanupStack::Pop( self );
       
    82     return self;
       
    83     }
       
    84 
       
    85 // ---------------------------------------------------------------------------
       
    86 // CSimplePluginData::NewLC
       
    87 // ---------------------------------------------------------------------------
       
    88 //
       
    89 CSimplePluginData* CSimplePluginData::NewLC( )
       
    90     {
       
    91     CSimplePluginData* self = new( ELeave ) CSimplePluginData;
       
    92     CleanupStack::PushL( self );
       
    93     self->ConstructL(  );
       
    94     return self;
       
    95     }
       
    96 
       
    97 // ---------------------------------------------------------------------------
       
    98 // CSimplePluginData::ConstructL
       
    99 // ---------------------------------------------------------------------------
       
   100 //
       
   101 void CSimplePluginData::ConstructL( )
       
   102     {
       
   103     }
       
   104 
       
   105 // ---------------------------------------------------------------------------
       
   106 // CSimplePluginData::NotifyToPrInfoL
       
   107 // ---------------------------------------------------------------------------
       
   108 //
       
   109 void CSimplePluginData::NotifyToPrInfoL(
       
   110         MPresenceObjectFactory& aPresenceFactory,
       
   111         MSimpleDocument& aDocument,
       
   112         MPresenceInfo& aPrInfo )
       
   113     {
       
   114     MPersonPresenceInfo* persInfo = aPresenceFactory.NewPersonPresenceInfoLC();
       
   115     MPresenceInfoFieldCollection& coll = persInfo->Fields();
       
   116 
       
   117     // Search own person info. Notice: Extend supported attributes later
       
   118 
       
   119     RPointerArray<MSimpleElement> elems;
       
   120     CleanupClosePushL( elems );
       
   121     TInt err = aDocument.SimpleElementsL( elems );
       
   122 
       
   123     if ( !err )
       
   124         {
       
   125         TInt myLatestPosition = SearchLatestTimestampL( elems );
       
   126 
       
   127         if ( myLatestPosition != KErrNotFound )
       
   128             {
       
   129             MSimpleElement* elem = elems[myLatestPosition];
       
   130 
       
   131             using namespace NSimplePlugin::NSimpleOma;
       
   132 
       
   133             // person element found
       
   134             RPointerArray<MSimpleElement> elems2;
       
   135             CleanupClosePushL( elems2 );
       
   136             elem->SimpleElementsL( elems2 );
       
   137             TInt count2 = elems2.Count();
       
   138 
       
   139             for ( TInt j = 0; j < count2; j++ )
       
   140                 {
       
   141                 MSimpleElement* elem2 = elems2[j];
       
   142                 if ( !elem2->LocalName().CompareF( KSimpleOverridingwillingness8 ))
       
   143                     {
       
   144                     UserOverridingWillingnessToPrFwL( aPresenceFactory, elem2, coll );
       
   145                     }
       
   146                 else if ( !elem2->LocalName().CompareF( KSimpleStatusicon8 ))
       
   147                     {
       
   148                     UserStatusIconToPrFwL( aPresenceFactory, elem2, coll, aDocument );
       
   149                     }
       
   150                 else if ( !elem2->LocalName().CompareF( KSimpleNote8 ))
       
   151                     {
       
   152                     UserNoteToPrFwL( aPresenceFactory, elem2, coll );
       
   153                     }
       
   154                 }
       
   155 
       
   156             CleanupStack::PopAndDestroy( &elems2 );
       
   157             }
       
   158         }
       
   159 
       
   160     CleanupStack::PopAndDestroy( &elems );
       
   161 
       
   162     aPrInfo.SetPersonPresenceL( persInfo );
       
   163     CleanupStack::Pop();   // >> persInfo
       
   164     }
       
   165 
       
   166 // ---------------------------------------------------------------------------
       
   167 // CSimplePluginData::UserOverridingWillingnessToPrFwL
       
   168 // ---------------------------------------------------------------------------
       
   169 //
       
   170 void CSimplePluginData::UserOverridingWillingnessToPrFwL(
       
   171         MPresenceObjectFactory& aPresenceFactory,
       
   172         MSimpleElement* aElement,
       
   173         MPresenceInfoFieldCollection& aCollection )
       
   174     {
       
   175 
       
   176 #ifdef _DEBUG
       
   177     PluginLogger::Log(_L("PluginData: UserOverridingWillingnessToPrFwL") );
       
   178 #endif
       
   179     using namespace NSimplePlugin::NSimpleOma;
       
   180 
       
   181     RPointerArray<MSimpleElement> elems;
       
   182     CleanupClosePushL( elems );
       
   183     User::LeaveIfError( aElement->SimpleElementsL( elems ));
       
   184     MSimpleElement* elem3 = elems[0]; // notice: we assume that there is no other sub-elements
       
   185     if ( !elem3->LocalName().CompareF( KSimpleBasic8 ))
       
   186         {
       
   187         // write the data into text field.
       
   188         HBufC* nodeContent = elem3->ContentUnicodeL();
       
   189         CleanupStack::PushL( nodeContent );
       
   190         if ( nodeContent )
       
   191             {
       
   192             // Save availability
       
   193             using namespace NPresenceInfo::NFieldType;
       
   194             MPresenceInfoField* field = aPresenceFactory.NewInfoFieldLC();
       
   195             field->SetFieldTypeL( KAvailability );
       
   196             MPresenceInfoFieldValueText* text = aPresenceFactory.NewTextInfoFieldLC();
       
   197             text->SetTextValueL( nodeContent->Des() );
       
   198             field->SetFieldValue( text );
       
   199             CleanupStack::Pop();            // >> text
       
   200             aCollection.AddOrReplaceFieldL( field );
       
   201             CleanupStack::Pop();            // >> field
       
   202             }
       
   203         CleanupStack::PopAndDestroy( nodeContent );
       
   204         }
       
   205     CleanupStack::PopAndDestroy( &elems );  // close the array, do not delete the content
       
   206     }
       
   207 
       
   208 // ---------------------------------------------------------------------------
       
   209 // CSimplePluginData::UserStatusIconToPrFwL
       
   210 // ---------------------------------------------------------------------------
       
   211 //
       
   212 void CSimplePluginData::UserStatusIconToPrFwL(
       
   213         MPresenceObjectFactory& aPresenceFactory,
       
   214         MSimpleElement* aElement,
       
   215         MPresenceInfoFieldCollection& aCollection,
       
   216         MSimpleDocument& aDocument )
       
   217     {
       
   218 #ifdef _DEBUG
       
   219     PluginLogger::Log(_L("PluginData: UserStatusIconToPrFwL") );
       
   220 #endif
       
   221     using namespace NSimpleDocument;
       
   222 
       
   223     using namespace NPresenceInfo::NFieldType;
       
   224 
       
   225     HBufC* nodeContent = aElement->ContentUnicodeL();
       
   226     CleanupStack::PushL( nodeContent );
       
   227     if ( nodeContent )
       
   228         {
       
   229         RPointerArray<MSimpleContent> contents;
       
   230         CleanupClosePushL( contents );
       
   231 
       
   232         // Search the corresponding direct content
       
   233         aDocument.GetDirectContentsL( contents );
       
   234 
       
   235         TInt contCount = contents.Count();
       
   236         for ( TInt i = 0; i<contCount; i++ )
       
   237             {
       
   238             TPtrC8 id = (contents[i])->ContentID();
       
   239             // nodecontent = "cid:simple.avatar.com"
       
   240             // content-id: simple.avatar.com
       
   241             HBufC8* cid8 = NULL;
       
   242             cid8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( nodeContent->Des() );
       
   243             CleanupStack::PushL( cid8 ); // << cid8
       
   244 
       
   245             TInt contentLen = cid8->Des().Length() - 4;  // "cid:"
       
   246             TInt headLen = id.Length();
       
   247             TPtrC8 pUnquoted( KNullDesC8 );
       
   248             if ( id.Locate('"') == 0 )
       
   249                 {
       
   250                 // remove "..." characters
       
   251                 pUnquoted.Set( id.Mid( 1, headLen-2 ));
       
   252                 }
       
   253             else
       
   254                 {
       
   255                 pUnquoted.Set( id );
       
   256                 }
       
   257             TInt foundPos = cid8->Des().Find( pUnquoted );
       
   258             if ( contentLen == headLen && foundPos >= 0 )
       
   259                 {
       
   260                 MPresenceInfoField* field = aPresenceFactory.NewInfoFieldLC();
       
   261                 field->SetFieldTypeL( KAvatar );
       
   262                 MPresenceInfoFieldValueBinary* val = aPresenceFactory.NewBinaryInfoFieldLC();
       
   263                 val->SetMimeTypeL( (contents[i])->ContentType() );
       
   264                 // Body is not BASE64 encoded internally
       
   265                 val->SetBinaryValueL( (contents[i])->Body() );
       
   266                 field->SetFieldValue( val );
       
   267                 CleanupStack::Pop();                // >> val
       
   268                 aCollection.AddOrReplaceFieldL( field );
       
   269                 CleanupStack::Pop();                // >> field
       
   270                 }
       
   271             CleanupStack::PopAndDestroy( cid8 ); // >> cid8
       
   272             }
       
   273         CleanupStack::PopAndDestroy( &contents );
       
   274         }
       
   275     CleanupStack::PopAndDestroy( nodeContent );
       
   276     }
       
   277 
       
   278 // ---------------------------------------------------------------------------
       
   279 // CSimplePluginData::UserNoteToPrFwL
       
   280 // ---------------------------------------------------------------------------
       
   281 //
       
   282 void CSimplePluginData::UserNoteToPrFwL(
       
   283         MPresenceObjectFactory& aPresenceFactory,
       
   284         MSimpleElement* aElement,
       
   285         MPresenceInfoFieldCollection& aCollection )
       
   286     {
       
   287 #ifdef _DEBUG
       
   288     PluginLogger::Log(_L("PluginData: UserNoteToPrFwL") );
       
   289 #endif
       
   290     // using namespace NSimplePlugin::NSimpleOma;
       
   291     HBufC* nodeContent = aElement->ContentUnicodeL();
       
   292     CleanupStack::PushL( nodeContent );
       
   293     if ( nodeContent )
       
   294         {
       
   295         // Save note, convert from unicode
       
   296         // notice: consider xml::lang-attribute
       
   297         // note <-> KStatusMessage
       
   298         using namespace NPresenceInfo::NFieldType;
       
   299         MPresenceInfoField* field = aPresenceFactory.NewInfoFieldLC();
       
   300         field->SetFieldTypeL( KStatusMessage );
       
   301         MPresenceInfoFieldValueText* text = aPresenceFactory.NewTextInfoFieldLC();
       
   302         text->SetTextValueL( nodeContent->Des() );
       
   303         field->SetFieldValue( text );
       
   304         CleanupStack::Pop();            // >> text
       
   305         aCollection.AddOrReplaceFieldL( field );
       
   306         CleanupStack::Pop();            // >> field
       
   307         }
       
   308     CleanupStack::PopAndDestroy( nodeContent );
       
   309     }
       
   310 
       
   311 // ---------------------------------------------------------------------------
       
   312 // CSimplePluginData::NotifyListToPrInfoL
       
   313 // ---------------------------------------------------------------------------
       
   314 //
       
   315 void CSimplePluginData::NotifyListToPrInfoL(
       
   316     MXIMPObjectFactory& aFactory,
       
   317     MPresenceObjectFactory& aPresenceFactory,
       
   318     MSimplePresenceList& aList,
       
   319     RPointerArray<MPresenceInfo>& aEntities,
       
   320     RPointerArray<MXIMPIdentity>& aActives,
       
   321     RPointerArray<MXIMPIdentity>& aTerminated,
       
   322     TBool& aFullList )
       
   323     {
       
   324     // Split array into individual prInfos
       
   325 
       
   326 #ifdef _DEBUG
       
   327     PluginLogger::Log(_L("PluginData: NotifyListToPrInfoL") );
       
   328 #endif
       
   329 
       
   330     RPointerArray<MSimpleDocument> docs;
       
   331     CleanupClosePushL( docs );
       
   332     // get documents, ownership is not transferred.
       
   333     aList.GetDocuments( docs );
       
   334 
       
   335     CollectAllPresentitiesL( aEntities, aActives, docs, aFactory, aPresenceFactory );
       
   336 
       
   337     using namespace NSimplePlugin::NSimpleOma;
       
   338 
       
   339     MSimpleMeta* meta = aList.MetaData();
       
   340 
       
   341 #ifdef _DEBUG
       
   342     // TODO: remove
       
   343     if ( meta == NULL )
       
   344     PluginLogger::Log(_L("PluginData: META Is NULL !!! *****"));
       
   345 #endif
       
   346 
       
   347 
       
   348 
       
   349     // ownership in not transferred
       
   350     if ( meta && !meta->LocalName().CompareF( KSimpleList8 ))
       
   351         {
       
   352         // list element found, find out if fullstate
       
   353         const TDesC8* fullStateVal = meta->AttrValue( KSimpleFullState8 );
       
   354         if ( fullStateVal && !fullStateVal->CompareF( KSimpleTrue8 ))
       
   355             {
       
   356             aFullList = ETrue;
       
   357             }
       
   358         else
       
   359             {
       
   360             aFullList = EFalse;
       
   361             }
       
   362 
       
   363 #ifdef _DEBUG
       
   364         PluginLogger::Log(_L("PluginData: fullState === %d"), aFullList );
       
   365 #endif
       
   366 
       
   367         // Search "terminated" presentities
       
   368         RPointerArray<MSimpleElement> elems2;
       
   369         CleanupClosePushL( elems2 );
       
   370         meta->SimpleElementsL( elems2);
       
   371         CollectTerminatedPresentitiesL( aTerminated, elems2, aFactory );
       
   372         CleanupStack::PopAndDestroy( &elems2 );
       
   373         }
       
   374 
       
   375     CleanupStack::PopAndDestroy( &docs );
       
   376     }
       
   377 
       
   378         /*
       
   379         example:
       
   380    Content-Transfer-Encoding: binary
       
   381    Content-ID: <nXYxAE@pres.vancouver.example.com>
       
   382    Content-Type: application/rlmi+xml;charset="UTF-8"
       
   383 
       
   384    <?xml version="1.0" encoding="UTF-8"?>
       
   385    <list xmlns="urn:ietf:params:xml:ns:rlmi"
       
   386          uri="sip:adam-friends@pres.vancouver.example.com"
       
   387          version="1" fullState="true">
       
   388      <name xml:lang="en">Buddy List at COM</name>
       
   389      <name xml:lang="de">Liste der Freunde an COM</name>
       
   390      <resource uri="sip:bob@vancouver.example.com"">        <------- note
       
   391        <name>Bob Smith</name>
       
   392        <instance id="juwigmtboe" state="active"
       
   393                  cid="bUZBsM@pres.vancouver.example.com"/>
       
   394      </resource>
       
   395      <resource uri="sip:dave@vancouver.example.com">
       
   396        <name>Dave Jones</name>
       
   397        <instance id="hqzsuxtfyq" state="active"
       
   398                  cid="ZvSvkz@pres.vancouver.example.com"/>
       
   399      </resource>
       
   400      <resource uri="sip:ed@dallas.example.net">
       
   401        <name>Ed at NET</name>
       
   402      </resource>
       
   403      <resource uri="sip:adam-friends@stockholm.example.org">
       
   404        <name xml:lang="en">My Friends at ORG</name>
       
   405        <name xml:lang="de">Meine Freunde an ORG</name>
       
   406      </resource>
       
   407    </list>
       
   408         */
       
   409 
       
   410 // ---------------------------------------------------------------------------
       
   411 // CSimplePluginData::AddPrPersToSimpleDocumentL
       
   412 // ---------------------------------------------------------------------------
       
   413 //
       
   414 void CSimplePluginData::AddPrPersToSimpleDocumentL(
       
   415     const MPersonPresenceInfo* aInfo,
       
   416     MSimpleDocument& aDocument,
       
   417     const TDesC8& aSipId )
       
   418     {
       
   419     using namespace NSimpleDocument;
       
   420 
       
   421     TPtrC8 p8( KSimpleAvatarCIDURI8 );
       
   422     TInt bufSize = p8.Length();
       
   423 
       
   424     HBufC16* CIDcontent = HBufC16::NewLC( bufSize );   // << CID
       
   425     CIDcontent->Des().Copy( KSimpleAvatarCIDURI8 );
       
   426 
       
   427     // notice: we do not generate random id but a static one.
       
   428 
       
   429     using namespace NSimplePlugin::NSimpleOma;
       
   430 
       
   431     aDocument.SetEntityURIL( aSipId );
       
   432 
       
   433     MSimpleElement* persElem = aDocument.AddSimpleElementL(
       
   434         KSimpleNsPDM, KSimplePerson8 );
       
   435     CleanupClosePushL( *persElem );             // << persElem
       
   436 
       
   437     using namespace NPresenceInfo::NFieldType;
       
   438 
       
   439     const MPresenceInfoFieldCollection& coll = aInfo->Fields();
       
   440 
       
   441     TInt myCount = coll.FieldCount();
       
   442     for ( TInt i = 0; i < myCount; i++ )
       
   443         {
       
   444         const MPresenceInfoField& field =  coll.FieldAt( i );
       
   445         const TDesC8& fieldType = field.FieldType();
       
   446         const MXIMPBase& storage = field.FieldValue();
       
   447 
       
   448         // Notice: tuple id saving for partial data in future.
       
   449 
       
   450         /*
       
   451         Mapping:
       
   452         Avatar -> Person/status-icon
       
   453         status-msg -> Person/note
       
   454         Availability -> Person/overriding-willingness
       
   455         */
       
   456 
       
   457         if ( !fieldType.CompareF( KAvatar ) )
       
   458             {
       
   459             const MPresenceInfoFieldValueBinary* bin =
       
   460                   TXIMPGetInterface< const MPresenceInfoFieldValueBinary >::From( storage,
       
   461                   MXIMPBase::EReturnNullIfUnknown );
       
   462             if ( bin )
       
   463                 {
       
   464                 MSimpleElement* elem = persElem->AddSimpleElementL(
       
   465                         KSimpleNsRPID,
       
   466                         KSimpleStatusicon8 );
       
   467                 CleanupClosePushL( *elem );             // << elem
       
   468                 elem->SetContentUnicodeL( CIDcontent->Des());
       
   469                 // Create the MIME multipart content
       
   470                 MSimpleContent* content = TSimpleFactory::NewContentL(
       
   471                     KSimpleAvatarContent8, bin->MimeType() );
       
   472                 CleanupClosePushL( *content );          // << content
       
   473                 content->CopyBodyL( bin->BinaryValue( ) );
       
   474                 aDocument.AddDirectContentL( *content, EFalse );
       
   475                 CleanupStack::PopAndDestroy( content );         // >> content
       
   476                 CleanupStack::PopAndDestroy( elem );  // >> elem
       
   477                 }
       
   478             }
       
   479         else if ( !fieldType.CompareF( KStatusMessage ) )
       
   480             {
       
   481             const MPresenceInfoFieldValueText* text =
       
   482                   TXIMPGetInterface< const MPresenceInfoFieldValueText >::From( storage,
       
   483                   MXIMPBase::EReturnNullIfUnknown );
       
   484             if ( text )
       
   485                 {
       
   486                 MSimpleElement* elem = persElem->AddSimpleElementL(
       
   487                     KSimpleNsPDM,
       
   488                     KSimpleNote8 );
       
   489                 CleanupClosePushL( *elem );             // << elem
       
   490                 elem->SetContentUnicodeL( text->TextValue() );
       
   491                 CleanupStack::PopAndDestroy( elem );  // >> elem
       
   492                 }
       
   493             }
       
   494         else if ( !fieldType.CompareF( KAvailability ))
       
   495             {
       
   496             const MPresenceInfoFieldValueText* text =
       
   497                   TXIMPGetInterface< const MPresenceInfoFieldValueText >::From( storage,
       
   498                   MXIMPBase::EReturnNullIfUnknown );
       
   499             if ( text )
       
   500                 {
       
   501                 AddPrPersAvailabilityToDocL( text, persElem );
       
   502                 }         
       
   503             }
       
   504         else
       
   505             {
       
   506             // Notice: currently all the fields in the namespace are supported,
       
   507             // but this ensures that if namespace is extended later, it is
       
   508             // handled right way in the adaptation
       
   509             User::Leave( KPresenceErrPresenceInfoFieldTypeNotSupported );
       
   510             }
       
   511         }
       
   512     CleanupStack::PopAndDestroy( persElem );
       
   513     CleanupStack::PopAndDestroy( CIDcontent );
       
   514     }
       
   515 
       
   516 
       
   517 // ---------------------------------------------------------------------------
       
   518 // CSimplePluginData::CollectAllPresentitiesL
       
   519 // ---------------------------------------------------------------------------
       
   520 //
       
   521 void CSimplePluginData::CollectAllPresentitiesL(
       
   522     RPointerArray<MPresenceInfo>& aEntities,
       
   523     RPointerArray<MXIMPIdentity>& aActives,
       
   524     RPointerArray<MSimpleDocument>& aDocs,
       
   525     MXIMPObjectFactory& aFactory,
       
   526     MPresenceObjectFactory& aPresenceFactory )
       
   527     {
       
   528     TInt count = aDocs.Count();
       
   529 
       
   530     // active presentities
       
   531     for ( TInt i = 0; i < count; i++ )
       
   532         {
       
   533         MPresenceInfo* info = aPresenceFactory.NewPresenceInfoLC();   // << info
       
   534         aEntities.AppendL( info );
       
   535         // aEntities may contain entries even this method leaves
       
   536         CleanupStack::Pop();                                      // >> info
       
   537 
       
   538         NotifyToPrInfoL( aPresenceFactory, *aDocs[i], *info );
       
   539 
       
   540         // Add SIP identity to active users list
       
   541         MXIMPIdentity* active = aFactory.NewIdentityLC();  // << active
       
   542         aActives.AppendL( active );
       
   543         CleanupStack::Pop();                            // >> active
       
   544 
       
   545         // Convert SIP entity URI from UTF to Unicode.
       
   546         const TDesC8* pUri8 = (aDocs[i])->EntityURI();
       
   547         HBufC16* uri16 = NULL;
       
   548         uri16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *pUri8 );
       
   549         CleanupStack::PushL( uri16 );  // << uri16
       
   550         active->SetIdentityL( uri16->Des() );
       
   551 
       
   552 #ifdef _DEBUG
       
   553     // ---------------------------------------------------------
       
   554     TBuf<200> buffer2;
       
   555     buffer2.Copy(uri16->Des());
       
   556     const MPersonPresenceInfo* pers_debug = info->PersonPresence();
       
   557     const MPresenceInfoFieldCollection& coll_debug = pers_debug->Fields();
       
   558     TInt count_debug = coll_debug.FieldCount();
       
   559     PluginLogger::Log(_L("PluginData: nbr of fields received =%d"), count_debug );
       
   560     PluginLogger::Log(_L("PluginData: User added to actives: %S"), &buffer2 );
       
   561     // ---------------------------------------------------------
       
   562 #endif
       
   563         CleanupStack::PopAndDestroy( uri16 );  // >> uri16
       
   564         }
       
   565     }
       
   566 
       
   567 // ---------------------------------------------------------------------------
       
   568 // CSimplePluginData::CollectTerminatedPresentitiesL
       
   569 // ---------------------------------------------------------------------------
       
   570 //
       
   571 void CSimplePluginData::CollectTerminatedPresentitiesL(
       
   572     RPointerArray<MXIMPIdentity>& aTerminated,
       
   573     RPointerArray<MSimpleElement>& aElems,
       
   574     MXIMPObjectFactory& aFactory )
       
   575     {
       
   576 #ifdef _DEBUG
       
   577     PluginLogger::Log(_L("PluginData: CollectTerminatedPresentitiesL"));
       
   578 #endif
       
   579     using namespace NSimplePlugin::NSimpleOma;
       
   580 
       
   581     TInt count2 = aElems.Count();
       
   582     for ( TInt i = 0; i < count2; i++ )
       
   583         {
       
   584         MSimpleElement* elem2 = aElems[i];
       
   585         if ( !elem2->LocalName().CompareF( KSimpleResource8 ))
       
   586             {
       
   587             // resource element
       
   588             RPointerArray<MSimpleElement> elems3;
       
   589             CleanupClosePushL( elems3 );
       
   590             elem2->SimpleElementsL( elems3 );
       
   591             TInt count3 = elems3.Count();
       
   592             const TDesC8* uri8 = elem2->AttrValue( KSimpleUri8 );
       
   593             if ( !uri8 )
       
   594                 {
       
   595                 continue;
       
   596                 }
       
   597             for ( TInt j=0; j < count3; j++ )
       
   598                 {
       
   599                 MSimpleElement* elem3 = elems3[j];
       
   600                 SearchTerminatedInstanceL( aTerminated, elem3, uri8, aFactory  );
       
   601                 }
       
   602             CleanupStack::PopAndDestroy( &elems3 );
       
   603             } // resource element
       
   604         }// for (i); list element subelement
       
   605 
       
   606 #ifdef _DEBUG
       
   607     PluginLogger::Log(_L("PluginData: CollectTerminatedPresentitiesL ends"));
       
   608 #endif
       
   609     }
       
   610 
       
   611 
       
   612 // ---------------------------------------------------------------------------
       
   613 // CSimplePluginData::SearchLatestTimestampL
       
   614 // ---------------------------------------------------------------------------
       
   615 //
       
   616 TInt CSimplePluginData::SearchLatestTimestampL(
       
   617     RPointerArray<MSimpleElement>& aElems  )
       
   618     {
       
   619     TInt ret = KErrNotFound;
       
   620 
       
   621     const TInt KMaxTimestamp = 40;
       
   622     TBuf<KMaxTimestamp> myTimestamp;
       
   623 
       
   624     // Timestamp to save the latest one person data
       
   625     myTimestamp = KNullDesC;
       
   626 
       
   627     // They want to get empty notifications too.
       
   628     TInt count = aElems.Count();
       
   629 
       
   630     using namespace NSimplePlugin::NSimpleOma;
       
   631 
       
   632     MSimpleElement* elem = NULL;
       
   633     TPtrC8 p8;
       
   634 
       
   635     for ( TInt i = 0; i < count; i++ )
       
   636         {
       
   637         elem = aElems[i];
       
   638         p8.Set( elem->LocalName());
       
   639         if (!( p8.CompareF( KSimplePerson8 )))
       
   640             {
       
   641 
       
   642             if ( ret == KErrNotFound )
       
   643                 {
       
   644                 // Save since the time stamp is optional, this is first <person> .
       
   645                 // the whole <person> may also be missing.
       
   646                 ret = i;
       
   647                 }
       
   648 
       
   649             // person element found
       
   650             RPointerArray<MSimpleElement> elems2;
       
   651             CleanupClosePushL( elems2 );
       
   652             elem->SimpleElementsL( elems2 );
       
   653             TInt count2 = elems2.Count();
       
   654 
       
   655             // Search optional timestamp element first, the latest one
       
   656             for ( TInt j = 0; j < count2; j++ )
       
   657                 {
       
   658                 //
       
   659                 MSimpleElement* elem2 = elems2[j];
       
   660                 // Search optional timestamp element
       
   661                 if ( !elem2->LocalName().CompareF( KSimpleTimestamp8 ))
       
   662                     {
       
   663                     HBufC* nodeContent = elem2->ContentUnicodeL();
       
   664                     // Notice: Timestamp comparision assumes now
       
   665                     // that all the timestamps have a similar format.
       
   666                     if ( myTimestamp.Compare( nodeContent->Des() ) < 0 )
       
   667                         {
       
   668                         // Save latest timestamp
       
   669                         myTimestamp.Copy( nodeContent->Des() );
       
   670                         ret = i;
       
   671                         }
       
   672                     delete nodeContent;
       
   673                     }
       
   674                 }
       
   675             CleanupStack::PopAndDestroy( &elems2 );
       
   676             }
       
   677         }  // for
       
   678 
       
   679     return ret;
       
   680     }
       
   681 
       
   682 // ---------------------------------------------------------------------------
       
   683 // CSimplePluginData::AddPrPersAvailabilityToDocL
       
   684 // ---------------------------------------------------------------------------
       
   685 //
       
   686 void CSimplePluginData::AddPrPersAvailabilityToDocL(
       
   687     const MPresenceInfoFieldValueText* aText, MSimpleElement* aPersElem )
       
   688     {
       
   689     using namespace NSimplePlugin::NSimpleOma;
       
   690 
       
   691     MSimpleElement* elem = aPersElem->AddSimpleElementL(
       
   692             KSimpleNsOP,
       
   693             KSimpleOverridingwillingness8 );
       
   694     CleanupClosePushL( *elem );             // << elem
       
   695     MSimpleElement* elem2 = elem->AddSimpleElementL(
       
   696             KSimpleNsOP,
       
   697             KSimpleBasic8 );
       
   698     CleanupClosePushL( *elem2 );             // << elem2
       
   699     if ( !aText->TextValue().CompareF( KSimpleOpen ) )
       
   700         {
       
   701         elem2->SetContentUnicodeL( KSimpleOpen );
       
   702         }
       
   703     else 
       
   704         {
       
   705         elem2->SetContentUnicodeL( KSimpleClosed );
       
   706         }
       
   707     CleanupStack::PopAndDestroy( elem2 ); // >> elem2
       
   708     CleanupStack::PopAndDestroy( elem );  // >> elem
       
   709     }
       
   710 
       
   711 // ---------------------------------------------------------------------------
       
   712 // CSimplePluginData::SearchTerminatedInstanceL
       
   713 // ---------------------------------------------------------------------------
       
   714 //
       
   715 void CSimplePluginData::SearchTerminatedInstanceL(
       
   716     RPointerArray<MXIMPIdentity>& aTerminated,
       
   717     MSimpleElement* aElem,
       
   718     const TDesC8* uri8,
       
   719     MXIMPObjectFactory& aFactory )
       
   720     {
       
   721 #ifdef _DEBUG
       
   722     PluginLogger::Log(_L("PluginData: SearchTerminatedInstanceL"));
       
   723 #endif
       
   724 
       
   725     using namespace NSimplePlugin::NSimpleOma;
       
   726     if ( !aElem->LocalName().CompareF( KSimpleInstance8 ))
       
   727         {
       
   728         // instance element
       
   729         const TDesC8* stateVal = aElem->AttrValue( KSimpleState8 );
       
   730         if ( stateVal && !stateVal->CompareF( KSimpleTerminated8 ))
       
   731             {
       
   732             // Add presentity into terminated list
       
   733             MXIMPIdentity* terminated = aFactory.NewIdentityLC();  // +terminated
       
   734             aTerminated.AppendL( terminated );
       
   735             CleanupStack::Pop();                   // -terminated
       
   736 
       
   737             // Convert SIP entity URI from UTF to Unicode.
       
   738             HBufC16* uri16 = NULL;
       
   739             uri16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *uri8 );
       
   740             CleanupStack::PushL( uri16 );  // +uri16
       
   741             terminated->SetIdentityL( uri16->Des() );
       
   742 
       
   743 #ifdef _DEBUG
       
   744             // Debug buffer size
       
   745             const TInt KMyBufSize = 200;
       
   746             // ---------------------------------------------------------
       
   747             TBuf<KMyBufSize> buffer3;
       
   748             buffer3.Copy(uri16->Des());
       
   749             PluginLogger::Log(_L("PluginData:   SearchTerminatedInstanceL TERMINATED INSTANCE FOUND ***"));
       
   750             PluginLogger::Log(_L("PluginData:   User added to terminated: %S"), &buffer3 );
       
   751             // ---------------------------------------------------------
       
   752 #endif
       
   753             CleanupStack::PopAndDestroy( uri16 );   // -uri16
       
   754             }
       
   755         else
       
   756             {
       
   757             // -------------------------------------------------------------
       
   758 #ifdef _DEBUG
       
   759             if ( stateVal != NULL )
       
   760                 {
       
   761                 // Debug buffer size
       
   762                 const TInt KMyBufSize = 100;
       
   763                 HBufC16* uri16 = NULL;
       
   764                 uri16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *stateVal );
       
   765                 CleanupStack::PushL( uri16 );  // +uri16
       
   766                 TBuf<KMyBufSize> buffer4;
       
   767                 buffer4.Copy(uri16->Des());
       
   768                 PluginLogger::Log(_L("    STATEVAL: %S"), &buffer4 );
       
   769                 CleanupStack::PopAndDestroy( uri16 );   // -uri16
       
   770                 }
       
   771 #endif
       
   772             // -------------------------------------------------------------
       
   773             }
       
   774         }
       
   775     }
       
   776