omadrm/drmplugins/drmrohandler/src/CRoHandler.cpp
changeset 0 95b198f216e5
child 2 76350b5be3d8
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2004-2009 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:  ECOM plugin for receiving OMA Rights Objects
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <txtrich.h>                    // for CRichText
       
    21 #include <drmmessageparser.h>           // for CDrmMessageParser
       
    22 #include <drmrights.h>                  // for CDRMRights
       
    23 #include <ecom/implementationproxy.h>   // for TImplementationProxy
       
    24 #include <push/cpushhandlerbase.h>      // for CPushHandlerBase
       
    25 #include <push/pluginkiller.h>          // for CPluginKiller
       
    26 #include <push/pushmessage.h>           // for CPushMessage
       
    27 #include <roapeng.h>                    // for CRoapEng
       
    28 #include <roapengbase.h>
       
    29 #include <roapobserver.h>
       
    30 #include <centralrepository.h>          // link against centralrepository.lib
       
    31 #include <msvuids.h>
       
    32 #include <msvids.h>
       
    33 #include <downloadmgrclient.h>
       
    34 
       
    35 #ifdef RD_MULTIPLE_DRIVE
       
    36 #include <driveinfo.h>
       
    37 #endif
       
    38 
       
    39 #include <uri16.h>                          // TUriParser16
       
    40 #include <data_caging_path_literals.hrh>    // KDC_MTM_RESOURCE_DIR
       
    41 #include <uriutils.h>                       // UriUtils and so on
       
    42 #include <pushmtmui.rsg>                    // for R_PUSHMISC_UNK_SENDER
       
    43 #include <rohandler.rsg>                    // for R_QTN_DRM_MGR_INB_TITLE
       
    44 #include <sysutil.h>                        // Disk space checking
       
    45 
       
    46 #include "crohandler.h"
       
    47 #include "romtmcli.h"                       // for CRightsObjectMtmClient
       
    48 #include "roapsyncwrapper.h"
       
    49 
       
    50 #include "stringresourcereader.h"
       
    51 #include "rohandlerdmgrwrapper.h"
       
    52 #include "rohandlerinternalcrkeys.h"
       
    53 
       
    54 #ifdef _DEBUG
       
    55 #define DRMDEBUGLIT( a, b ) _LIT( a, b )
       
    56 #define DRMDEBUG( a ) RDebug::Print( a )
       
    57 #define DRMDEBUG2( a, b ) RDebug::Print( a, b )
       
    58 _LIT( KRoLogDir, "DRM" );
       
    59 _LIT( KRoLogFile, "RoHandler.log" );
       
    60 #define LOG( a ) RFileLogger::Write( KRoLogDir(), KRoLogFile(), EFileLoggingModeAppend, a );
       
    61 #define LOGHEX( ptr, len ) RFileLogger::HexDump( \
       
    62     KRoLogDir(), KRoLogFile(), EFileLoggingModeAppend, _S(""), _S(""), ptr, len );
       
    63 #define LOG2( a, b ) RFileLogger::WriteFormat( \
       
    64     KRoLogDir(), KRoLogFile(), EFileLoggingModeAppend, a, b );
       
    65 #else
       
    66 #define DRMDEBUGLIT( a, b )
       
    67 #define DRMDEBUG( a )
       
    68 #define DRMDEBUG2( a, b )
       
    69 #define LOG( a )
       
    70 #define LOGHEX( ptr, len )
       
    71 #define LOG2( a, b )
       
    72 #endif
       
    73 
       
    74 using namespace Roap;
       
    75 
       
    76 
       
    77 // EXTERNAL DATA STRUCTURES
       
    78 
       
    79 // EXTERNAL FUNCTION PROTOTYPES
       
    80 
       
    81 // CONSTANTS
       
    82 const TImplementationProxy ImplementationTable[] =
       
    83     {
       
    84     IMPLEMENTATION_PROXY_ENTRY(0x101F7B93, CRoHandler::NewL)
       
    85     //{{0x101F7B93}, CRoHandler::NewL}
       
    86     };
       
    87 
       
    88 // For reading the string value of cenrep key Inbox entry visible (for
       
    89 // received RO). The size of string "false" is 5.
       
    90 const TInt KBooleanStringMaxSize = 5;
       
    91 
       
    92 // MACROS
       
    93 
       
    94 // LOCAL CONSTANTS AND MACROS
       
    95 
       
    96 #ifdef RD_MULTIPLE_DRIVE
       
    97 _LIT( KRoHandlerTriggerFilePath, "%c:\\system\\data\\" );
       
    98 #else
       
    99 _LIT( KDriveZ, "z:" );
       
   100 _LIT( KRoHandlerTriggerFilePath, "c:\\system\\data\\" );
       
   101 #endif
       
   102 
       
   103 _LIT( KPushMtmRes, "PushMtmUi.rsc" );
       
   104 _LIT( KRoHandlerResourceFile, "RoHandler.rsc" );
       
   105 
       
   106 _LIT8( KRoapTriggerElement, "roapTrigger" );
       
   107 _LIT8( KWbxmlRoapTriggerElement, "\x03\x13j" );
       
   108 _LIT8( KRoapTriggerRoAcquisition, "roAcquisition" );
       
   109 _LIT8( KRoapTriggerMeteringReport, "meteringReport" );
       
   110 _LIT8( KRoapRoPduElement, "roResponse" );
       
   111 
       
   112 _LIT( KFalse, "false" );
       
   113 _LIT( KZero, "0" );
       
   114 
       
   115 _LIT( KRoAcquisitionPrefix, "ROA:" );
       
   116 _LIT( KTriggerPrefix, "TRI:" );
       
   117 
       
   118 // MODULE DATA STRUCTURES
       
   119 
       
   120 // Helper class for deleting file with given filename on cleanupstack
       
   121 // Note does not own its members
       
   122 // Used for cleaning up saved trigger if creating trigger related message
       
   123 // inbox entry fails.
       
   124 NONSHARABLE_CLASS( CFileDeleter ) : public CBase
       
   125     {
       
   126 public:
       
   127     static CFileDeleter* NewLC( RFs& aFs, TFileName& aFileName )
       
   128         {
       
   129         CFileDeleter* self( new ( ELeave ) CFileDeleter( aFs, aFileName ) );
       
   130         CleanupStack::PushL( self );
       
   131         return self;
       
   132         }
       
   133 
       
   134     inline void SetDelete()
       
   135         {
       
   136         iDeleteFileOnDestroy = ETrue;
       
   137         }
       
   138 
       
   139     inline void SetNoDelete()
       
   140         {
       
   141         iDeleteFileOnDestroy = EFalse;
       
   142         }
       
   143 
       
   144     virtual ~CFileDeleter()
       
   145         {
       
   146         if ( iDeleteFileOnDestroy )
       
   147             {
       
   148             iFs.Delete( iFileName );
       
   149             }
       
   150         }
       
   151 
       
   152 private:
       
   153     CFileDeleter()
       
   154         {
       
   155         }
       
   156     CFileDeleter( const CFileDeleter& )
       
   157         {
       
   158         }
       
   159     CFileDeleter( RFs& aFs, TFileName& aFileName )
       
   160         : iFs( aFs ), iFileName( aFileName )
       
   161         {
       
   162         }
       
   163 
       
   164     CFileDeleter& operator=( const CFileDeleter& );
       
   165 
       
   166     TBool iDeleteFileOnDestroy;
       
   167     RFs iFs;
       
   168     TFileName iFileName;
       
   169     };
       
   170 
       
   171 // LOCAL FUNCTION PROTOTYPES
       
   172 
       
   173 // FORWARD DECLARATIONS
       
   174 
       
   175 // ============================= LOCAL FUNCTIONS ===============================
       
   176 #ifdef _DRM_TESTING
       
   177 LOCAL_C void WriteLogL( const TDesC8& text, RFs &aFs );
       
   178 LOCAL_C void WriteFileL( const TDesC8& text, RFs &aFs, const TDesC& aName );
       
   179 LOCAL_C void CreateLogL();
       
   180 LOCAL_C void WriteL( const TDesC8& aText );
       
   181 LOCAL_C void WriteL( const TDesC& aText );
       
   182 LOCAL_C void WriteL( const TDesC8& aText, TInt aErr );
       
   183 LOCAL_C void WriteL( const TDesC& aText, TInt aErr );
       
   184 LOCAL_C void WriteCurrentTimeL();
       
   185 #endif
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // Testing stuff
       
   189 // -----------------------------------------------------------------------------
       
   190 //
       
   191 
       
   192 #ifdef _DRM_TESTING
       
   193 LOCAL_C void WriteLogL( const TDesC8& text, RFs &aFs )
       
   194     {
       
   195     _LIT( KLogFile, "c:\\CROHandler.txt" );
       
   196     WriteFileL( text, aFs, KLogFile );
       
   197     }
       
   198 
       
   199 LOCAL_C void WriteFileL( const TDesC8& text, RFs &aFs, const TDesC& aName )
       
   200     {
       
   201     RFile file;
       
   202     TInt size;
       
   203     User::LeaveIfError( file.Open( aFs, aName, EFileWrite ) );
       
   204     CleanupClosePushL( file );
       
   205     User::LeaveIfError( file.Size( size ) );
       
   206     User::LeaveIfError( file.Write( size, text ) );
       
   207     CleanupStack::PopAndDestroy( &file );
       
   208     }
       
   209 
       
   210 LOCAL_C void CreateLogL()
       
   211     {
       
   212     RFs fs;
       
   213     User::LeaveIfError( fs.Connect() );
       
   214     CleanupClosePushL( fs );
       
   215     RFile file;
       
   216     User::LeaveIfError( file.Replace( fs, _L( "c:\\CROHandler.txt" ), EFileWrite ) );
       
   217     file.Close();
       
   218     CleanupStack::PopAndDestroy( &fs );
       
   219     }
       
   220 
       
   221 LOCAL_C void WriteL( const TDesC& aText )
       
   222     {
       
   223     RFs fs;
       
   224     User::LeaveIfError( fs.Connect() );
       
   225     CleanupClosePushL( fs );
       
   226     HBufC8* text = HBufC8::NewLC( 1000 );
       
   227     TPtr8 textptr( text->Des() );
       
   228     textptr.Append( aText );
       
   229     textptr.Append( _L8( "\r\n" ) );
       
   230     WriteLogL( textptr, fs );
       
   231     CleanupStack::PopAndDestroy( text );
       
   232     CleanupStack::PopAndDestroy( &fs );
       
   233     WriteCurrentTimeL();
       
   234     }
       
   235 
       
   236 LOCAL_C void WriteL( const TDesC8& aText )
       
   237     {
       
   238     RFs fs;
       
   239     User::LeaveIfError( fs.Connect() );
       
   240     CleanupClosePushL( fs );
       
   241     HBufC8* text = HBufC8::NewLC( 1000 );
       
   242     TPtr8 textptr( text->Des() );
       
   243     textptr.Append( aText );
       
   244     textptr.Append( _L8( "\r\n" ) );
       
   245     WriteLogL( textptr, fs );
       
   246     CleanupStack::PopAndDestroy( text );
       
   247     CleanupStack::PopAndDestroy( &fs );
       
   248     WriteCurrentTimeL();
       
   249     }
       
   250 
       
   251 LOCAL_C void WriteL( const TDesC8& aText, TInt aErr )
       
   252     {
       
   253     _LIT8( KErr, ": %d" );
       
   254     HBufC8* text = HBufC8::NewLC( 1000 + 20 );
       
   255     TBuf8<20> num;
       
   256     TPtr8 textptr( text->Des() );
       
   257     textptr.Append( aText );
       
   258     num.Format( KErr(), aErr );
       
   259     textptr.Append( num );
       
   260     WriteL( textptr );
       
   261     CleanupStack::PopAndDestroy( text );
       
   262     }
       
   263 
       
   264 LOCAL_C void WriteL( const TDesC& aText, TInt aErr )
       
   265     {
       
   266     _LIT8( KErr, ": %d" );
       
   267     HBufC8* text = HBufC8::NewLC( 1000+20 );
       
   268     TBuf8<20> num;
       
   269     TPtr8 textptr( text->Des() );
       
   270     textptr.Append( aText );
       
   271     num.Format( KErr(), aErr );
       
   272     textptr.Append( num );
       
   273     WriteL( textptr );
       
   274     CleanupStack::PopAndDestroy( text );
       
   275     }
       
   276 
       
   277 LOCAL_C void WriteCurrentTimeL()
       
   278     {
       
   279     RFs fs;
       
   280     User::LeaveIfError( fs.Connect() );
       
   281     CleanupClosePushL( fs );
       
   282     HBufC8* text = HBufC8::NewLC( 100 );
       
   283     TPtr8 textptr( text->Des() );
       
   284     // Date and Time display
       
   285     TTime time;
       
   286     time.HomeTime();
       
   287     TBuf<256> dateString;
       
   288     _LIT( KDate, "%*E%*D%X%*N%*Y %1 %2 '%3" );
       
   289     time.FormatL( dateString, KDate );
       
   290     textptr.Append( _L( "\r\n\t\tData:\t" ) );
       
   291     textptr.Append( dateString );
       
   292     _LIT( KTime, "%-B%:0%J%:1%T%:2%S%:3%+B" );
       
   293     time.FormatL( dateString, KTime );
       
   294     textptr.Append( _L( "\r\n\t\tTime:\t" ) );
       
   295     textptr.Append( dateString );
       
   296     textptr.Append( _L( "\r\n" ) );
       
   297     textptr.Append( _L( "\r\n" ) );
       
   298     WriteLogL( textptr, fs );
       
   299     CleanupStack::PopAndDestroy( text );
       
   300     CleanupStack::PopAndDestroy( &fs );
       
   301     }
       
   302 #endif
       
   303 
       
   304 
       
   305 // ----------------------------------------------------------------------------
       
   306 // DoResetAndDestroy
       
   307 // Does RPointerArray< >->ResetAndDestroy() for the given array aPtr.
       
   308 // ----------------------------------------------------------------------------
       
   309 //
       
   310 LOCAL_C void DoResetAndDestroy( TAny* aPtr )
       
   311     {
       
   312     ( reinterpret_cast< RPointerArray< CDRMRights >* >( aPtr ) )->ResetAndDestroy();
       
   313     delete aPtr;
       
   314     aPtr = NULL;
       
   315     }
       
   316 
       
   317 // ----------------------------------------------------------------------------
       
   318 // LeaveIfNullL
       
   319 // Leaves with given error or with KErrArgument if aBuf is null
       
   320 // ----------------------------------------------------------------------------
       
   321 //
       
   322 LOCAL_C inline void LeaveIfNullL( const TInt aRet, const HBufC8* aBuf )
       
   323     {
       
   324     if ( !aBuf )
       
   325         {
       
   326         User::LeaveIfError( aRet );
       
   327         User::Leave( KErrArgument );
       
   328         }
       
   329     }
       
   330 
       
   331 // ----------------------------------------------------------------------------
       
   332 // IsMeteringSupported
       
   333 // ----------------------------------------------------------------------------
       
   334 //
       
   335 LOCAL_C TBool IsMeteringSupported()
       
   336     {
       
   337 #ifdef RD_DRM_METERING
       
   338     return ETrue;
       
   339 #else
       
   340     return EFalse;
       
   341 #endif
       
   342     }
       
   343 
       
   344 
       
   345 // ============================ MEMBER FUNCTIONS ===============================
       
   346 
       
   347 /*
       
   348 -----------------------------------------------------------------------------
       
   349 
       
   350     Method: NewL
       
   351 
       
   352     Description: 1st phase constructor
       
   353 
       
   354     Return Value: new CRoHandler
       
   355 
       
   356     Status: Proposal
       
   357 
       
   358 -----------------------------------------------------------------------------
       
   359 */
       
   360 
       
   361 CRoHandler* CRoHandler::NewL
       
   362         (
       
   363         //None.
       
   364         )
       
   365     {
       
   366 #ifdef _DRM_TESTING
       
   367     TRAPD( r, CreateLogL() );
       
   368     TRAP( r, WriteL( _L8( "NewL" ) ) );
       
   369 #endif
       
   370     CRoHandler* self( new( ELeave ) CRoHandler() );
       
   371     CleanupStack::PushL( self );
       
   372     self->ConstructL();
       
   373     CleanupStack::Pop( self );
       
   374 #ifdef _DRM_TESTING
       
   375     TRAP( r, WriteL( _L8( "NewL-End" ) ) );
       
   376 #endif
       
   377     return self;
       
   378     }
       
   379 
       
   380 /*
       
   381 -----------------------------------------------------------------------------
       
   382 
       
   383     Method: CRoHandler
       
   384 
       
   385     Description: C++ default constructor. Initialises the object
       
   386                  with zero/NULL values.
       
   387 
       
   388     Return Value: None.
       
   389 
       
   390     Status: Proposal
       
   391 
       
   392 -----------------------------------------------------------------------------
       
   393 */
       
   394 
       
   395 CRoHandler::CRoHandler
       
   396         (
       
   397         //None.
       
   398         )
       
   399     : CPushHandlerBase(),
       
   400     iFirstTime( ETrue ), iPushMsg( NULL ), iMsvId( NULL ),
       
   401     iPutRightsToInbox( ETrue )
       
   402     {
       
   403     }
       
   404 
       
   405 /*
       
   406 -----------------------------------------------------------------------------
       
   407 
       
   408     Method: ConstructL
       
   409 
       
   410     Description: Adds the AO to the Active Scheduler. Constructs iDrm object
       
   411                  then connects to drm server
       
   412 
       
   413     Return Value: None.
       
   414 
       
   415     Status: Proposal
       
   416 
       
   417 -----------------------------------------------------------------------------
       
   418 */
       
   419 
       
   420 void CRoHandler::ConstructL
       
   421         (
       
   422         //None.
       
   423         )
       
   424     {
       
   425 #ifdef _DRM_TESTING
       
   426     TRAPD( r, WriteL( _L8( "ConstructL" ) ) );
       
   427 #endif
       
   428 
       
   429     CRepository* repository( NULL );
       
   430     TInt err( KErrNone );
       
   431 
       
   432     User::LeaveIfError( iFs.Connect() );
       
   433 
       
   434     // create drm
       
   435     iMessageParser = CDRMMessageParser::NewL();
       
   436 
       
   437     // Create wbxml trigger parser instance
       
   438     iWbxmlTriggerParser = DRM::CWbxmlRoapTriggerParser::NewL();
       
   439 
       
   440     // Create CMsvSession
       
   441     // new session is opened Synchronously
       
   442     iSession = CMsvSession::OpenSyncL( *this );
       
   443 
       
   444     iMtmReg = CClientMtmRegistry::NewL( *iSession );
       
   445 
       
   446     // Check if metering feature is active
       
   447     iMeteringSupported = IsMeteringSupported();
       
   448 
       
   449     // Check cenrep key in order to find out whether received RO
       
   450     // should be stored to inbox or not.
       
   451     TRAP( err, repository = CRepository::NewL( KCRUidRoHandler ) );
       
   452     if ( !err )
       
   453         {
       
   454         CleanupStack::PushL( repository );
       
   455         TBuf<KBooleanStringMaxSize> string;
       
   456         TInt error = repository->Get( KDRMRoHandlerInboxEntryVisible,
       
   457         string );
       
   458 
       
   459         // If the value of the repository key is found either "false" or
       
   460         // "0", do not store rights to an Inbox entry.
       
   461         if ( ( string.CompareF( KFalse ) == 0 ) ||
       
   462             ( string.CompareF( KZero ) == 0 ) )
       
   463         {
       
   464         iPutRightsToInbox = EFalse;
       
   465         }
       
   466 
       
   467     CleanupStack::PopAndDestroy( repository );
       
   468         }
       
   469 
       
   470 #ifdef _DRM_TESTING
       
   471     TRAP( r, WriteL( _L8( "Repository->Get done" ), iPutRightsToInbox ) );
       
   472     TRAP( r, WriteL( _L8( "ConstructL-End" ) ) );
       
   473 #endif
       
   474     }
       
   475 
       
   476 /*
       
   477 -----------------------------------------------------------------------------
       
   478 
       
   479     Method: ~CRoHandler
       
   480 
       
   481     Description: Calls also baseclass destructor which calls
       
   482                  REcomSession::DestroyedImplementation( iDtor_ID_Key).
       
   483 
       
   484     Return Value: None.
       
   485 
       
   486     Status: Proposal
       
   487 
       
   488 -----------------------------------------------------------------------------
       
   489 */
       
   490 
       
   491 CRoHandler::~CRoHandler
       
   492         (
       
   493         //None.
       
   494         )
       
   495     {
       
   496 #ifdef _DRM_TESTING
       
   497     TRAPD( r, WriteL( _L8( "~CRoHandler" ) ) );
       
   498 #endif
       
   499 
       
   500     iFs.Close();
       
   501     // Delete the necessary instance attributes
       
   502     delete iPushMsg;
       
   503     delete iMessageParser;
       
   504     delete iWbxmlTriggerParser;
       
   505     delete iParsedXmlTrigger;
       
   506     delete iMtm;
       
   507     delete iMtmReg;
       
   508 
       
   509     iMsvId = NULL;
       
   510 
       
   511     // session must be deleted last (and constructed first)
       
   512     delete iSession;
       
   513 
       
   514 #ifdef _DRM_TESTING
       
   515     TRAP( r, WriteL( _L8( "~CRoHandler-End" ) ) );
       
   516 #endif
       
   517     }
       
   518 
       
   519 /*
       
   520 -----------------------------------------------------------------------------
       
   521 
       
   522     Method: AddRoContentL
       
   523 
       
   524     Description: Adds Message content and number
       
   525 
       
   526     Return Value: None.
       
   527 
       
   528     Status: Proposal
       
   529 
       
   530 -----------------------------------------------------------------------------
       
   531 */
       
   532 void CRoHandler::AddRoContentL
       
   533         (
       
   534         TDesC& aMessageContent             //message content descriptor
       
   535         )
       
   536     {
       
   537 #ifdef _DRM_TESTING
       
   538     TRAPD( r, WriteL( _L8( "AddRoContentL" ) ) );
       
   539 #endif
       
   540     TMsvEntry msvEntry( ( iMtm->Entry() ).Entry() );
       
   541 
       
   542     // We get the message body from Mtm and insert a bodytext
       
   543     CRichText& mtmBody( iMtm->Body() );
       
   544     mtmBody.Reset();
       
   545     mtmBody.InsertL( 0, aMessageContent ); // insert our msg tag as the body text
       
   546 
       
   547     // set iRecipient into the Details of the entry
       
   548     msvEntry.SetNew( ETrue );              // set New
       
   549     msvEntry.SetUnread( ETrue );
       
   550     msvEntry.SetVisible( ETrue );
       
   551     msvEntry.SetInPreparation( EFalse );   // set inPreparation to false
       
   552     msvEntry.iDate.UniversalTime();        // set time to Universal Time
       
   553 
       
   554     // To handle the sms specifics we start using SmsMtm
       
   555     CRightsObjectMtmClient* roMtm( NULL );
       
   556     roMtm = static_cast< CRightsObjectMtmClient* >( iMtm );
       
   557 
       
   558     // save message
       
   559     CMsvEntry& entry( iMtm->Entry() );
       
   560     entry.ChangeL( msvEntry );             // make sure that we are handling the right entry
       
   561     roMtm->SaveMessageL();                 // closes the message
       
   562 
       
   563     // This moves the message entry to Inbox
       
   564     MoveMessageEntryL( KMsvGlobalInBoxIndexEntryId );
       
   565 
       
   566 #ifdef _DRM_TESTING
       
   567     TRAP( r, WriteL( _L8( "AddRoContentL-End" ) ) );
       
   568 #endif
       
   569     }
       
   570 
       
   571 
       
   572 /*
       
   573 -----------------------------------------------------------------------------
       
   574 
       
   575     Method: HandleSessionEventL
       
   576 
       
   577     Description: Starts the message handling procedure asynchronously.
       
   578                  Basically all the work is done in RunL method.
       
   579 
       
   580     Return Value: None.
       
   581 
       
   582     Status: Proposal
       
   583 
       
   584 -----------------------------------------------------------------------------
       
   585 */
       
   586 void CRoHandler::HandleSessionEventL
       
   587         (
       
   588         TMsvSessionEvent /* aEvent*/ ,
       
   589         TAny* /* aArg1*/ ,
       
   590         TAny* /* aArg2 */,
       
   591         TAny* /* aArg3 */
       
   592         )
       
   593     {
       
   594     }
       
   595 
       
   596 /*
       
   597 -----------------------------------------------------------------------------
       
   598 
       
   599     Method: HandleMessageL
       
   600 
       
   601     Description: Asynchronous version of the HandleMessageL().
       
   602                  NOT SUPPORTED
       
   603 
       
   604     Return Value: None.
       
   605 
       
   606     Status: Proposal
       
   607 
       
   608 -----------------------------------------------------------------------------
       
   609 */
       
   610 void CRoHandler::HandleMessageL
       
   611         (
       
   612         CPushMessage* aPushMsg,  // push message
       
   613         TRequestStatus& aStatus  // status of the request
       
   614         )
       
   615     {
       
   616 #ifdef _DRM_TESTING
       
   617     TRAPD( r, WriteL( _L8( "HandleMessageL(2)" ) ) );
       
   618 #endif
       
   619     iPushMsg = aPushMsg;
       
   620     SetConfirmationStatus( aStatus );
       
   621     SignalConfirmationStatus( KErrNotSupported );
       
   622     iPluginKiller->KillPushPlugin();
       
   623 #ifdef _DRM_TESTING
       
   624     TRAP( r, WriteL( _L8( "HandleMessageL(2)-End" ) ) );
       
   625 #endif
       
   626     }
       
   627 
       
   628 /*
       
   629 -----------------------------------------------------------------------------
       
   630 
       
   631     Method: HandleMessageL
       
   632 
       
   633     Description: Synchronous version of the HandleMessageL().
       
   634 
       
   635     Return Value: None.
       
   636 
       
   637     Status: Proposal
       
   638 
       
   639 -----------------------------------------------------------------------------
       
   640 */
       
   641 
       
   642 void CRoHandler::HandleMessageL
       
   643         (
       
   644         CPushMessage* aPushMsg // push message
       
   645         )
       
   646     {
       
   647 #ifdef _DRM_TESTING
       
   648     TRAPD( r, WriteL( _L8( "HandleMessageL(1)" ) ) );
       
   649 #endif
       
   650     iPushMsg = aPushMsg;
       
   651     //
       
   652     // Do sanity checks for the message.
       
   653     //
       
   654     User::LeaveIfError( PerformChecks() );
       
   655     iMsgType = CheckMessageTypeL();
       
   656     switch( iMsgType )
       
   657         {
       
   658         case EOma1Ro:
       
   659             {
       
   660             HandleRightsMessageL();
       
   661             break;
       
   662             }
       
   663 #ifdef __DRM_OMA2
       
   664         case EOma2RoapTrigger:
       
   665         case EOma2RoapTriggerRoAcquisition:
       
   666             {
       
   667             HandleRoapTriggerL();
       
   668             break;
       
   669             }
       
   670         case EOma2RoapTriggerMetering:
       
   671             {
       
   672             HandleMeteringTriggerSilentlyL();
       
   673             break;
       
   674             }
       
   675         case EOma2RoapPdu:
       
   676             {
       
   677             HandleRoapPduL();
       
   678             break;
       
   679             }
       
   680 #endif
       
   681         default:
       
   682             {
       
   683             User::Leave( KErrNotSupported );
       
   684             }
       
   685         }
       
   686 
       
   687     iPluginKiller->KillPushPlugin();
       
   688 
       
   689 #ifdef _DRM_TESTING
       
   690     TRAP( r, WriteL( _L8( "HandleMessageL(1)-End" ) ) );
       
   691 #endif
       
   692     }
       
   693 
       
   694 /*
       
   695 -----------------------------------------------------------------------------
       
   696 
       
   697     Method: HandleRightsMessageL
       
   698 
       
   699     Description: Process rights object and
       
   700 
       
   701     Return Value: None.
       
   702 
       
   703     Status: Proposal
       
   704 
       
   705 -----------------------------------------------------------------------------
       
   706 */
       
   707 
       
   708 
       
   709 void CRoHandler::HandleRightsMessageL()
       
   710     {
       
   711 #ifdef _DRM_TESTING
       
   712     TRAPD( r, WriteL( _L8( "HandleRightsMessageL" ) ) );
       
   713 #endif
       
   714 
       
   715     HBufC16 *number( NULL );
       
   716     HBufC16 *messageContent( NULL );
       
   717     HBufC16* buffer( NULL );
       
   718 
       
   719     TInt ret( 0 );
       
   720     if ( iMessageBodyPtr.Size() == 0 )
       
   721         {
       
   722         User::Leave( KErrCorrupt );
       
   723         }
       
   724 
       
   725     // Heap desc contains Content URI
       
   726     HBufC8* contentURI( NULL );
       
   727     TUint32 localId( 0 );
       
   728     RPointerArray< CDRMRights >*
       
   729         rights( new ( ELeave ) RPointerArray< CDRMRights > );
       
   730 
       
   731     if ( rights )
       
   732         {
       
   733         // process rights
       
   734         ret = iMessageParser->ProcessRightsObject( iMessageBodyPtr, *rights );
       
   735         }
       
   736     else
       
   737         {
       
   738         User::Leave( KErrNoMemory );
       
   739         }
       
   740 
       
   741     if ( !ret && rights->Count() )
       
   742         {
       
   743         TCleanupItem cleanup( DoResetAndDestroy, rights );
       
   744         CleanupStack::PushL( cleanup );
       
   745         ret = ( *rights )[ 0 ]->GetContentURI( contentURI );
       
   746         // null contentURI means invalid RO
       
   747         LeaveIfNullL( ret, contentURI );
       
   748         localId = ( *rights )[ 0 ]->GetLocalID();
       
   749         CleanupStack::PopAndDestroy( rights );
       
   750         rights = NULL;
       
   751         CleanupStack::PushL( contentURI );
       
   752         }
       
   753     else
       
   754         {
       
   755         rights->ResetAndDestroy();
       
   756         delete rights;
       
   757         rights = NULL;
       
   758         User::LeaveIfError( ret );
       
   759         }
       
   760 
       
   761     if ( iPutRightsToInbox )
       
   762         {
       
   763         buffer = HBufC16::NewL( contentURI->Length() );
       
   764         TPtr uri16( buffer->Des() );
       
   765         uri16.Copy( *contentURI );
       
   766         CleanupStack::PopAndDestroy( contentURI );
       
   767         contentURI = NULL;
       
   768         CleanupStack::PushL( buffer );
       
   769 
       
   770         number = HBufC16::NewLC( 11 ); //longer than max of tuint32
       
   771         TPtr ptr( number->Des() );
       
   772         ptr.AppendNum( localId, EDecimal );
       
   773 
       
   774         messageContent = HBufC16::NewL( ptr.Length() + uri16.Length() + 4 );
       
   775         TPtr ptrToMz( messageContent->Des() );
       
   776         ptrToMz.Append( _L( "1 " ) );
       
   777         ptrToMz.Append( ptr ); // add localID
       
   778         ptrToMz.Append( _L( " " ) ); // add space
       
   779         ptrToMz.Append( uri16 ); //add uri16
       
   780 
       
   781         CleanupStack::PopAndDestroy( number );
       
   782         CleanupStack::PopAndDestroy( buffer );
       
   783         CleanupStack::PushL( messageContent );
       
   784 
       
   785         // create empty sms
       
   786         iMsvId = CreateNewMessageL();
       
   787         SetEntryL( iMsvId );
       
   788         // adds content in sms and moves it inbox
       
   789         AddRoContentL( ptrToMz );
       
   790 
       
   791         CleanupStack::PopAndDestroy( messageContent );
       
   792         }
       
   793     else
       
   794         {
       
   795         CleanupStack::PopAndDestroy( contentURI );
       
   796         }
       
   797 
       
   798 #ifdef _DRM_TESTING
       
   799     TRAP( r, WriteL( _L8( "HandleRightsMessageL-End" ) ) );
       
   800 #endif
       
   801     }
       
   802 
       
   803 
       
   804 /*
       
   805 -----------------------------------------------------------------------------
       
   806 
       
   807     Method: HandleRoapPduL
       
   808 
       
   809     Description: Handles OMA 2.0 ROAP RO Response message
       
   810 
       
   811     Return Value: None.
       
   812 
       
   813     Status: Proposal
       
   814 
       
   815 -----------------------------------------------------------------------------
       
   816 */
       
   817 void CRoHandler::HandleRoapPduL()
       
   818     {
       
   819 #ifdef _DRM_TESTING
       
   820     TRAPD( r, WriteL( _L8( "HandleRoapPduL" ) ) );
       
   821 #endif
       
   822     Roap::CRoapEngBase* roapHandler( NULL );
       
   823     RPointerArray< CDRMRights > rights;
       
   824 
       
   825     roapHandler = CRoapEng::NewL();
       
   826     CleanupStack::PushL( roapHandler );
       
   827 
       
   828     TCleanupItem cleanup( DoResetAndDestroy, &rights );
       
   829     CleanupStack::PushL( cleanup );
       
   830 
       
   831 
       
   832     //Parse received rights.
       
   833 #ifdef  _DRM_TESTING
       
   834     TRAPD( err, roapHandler->HandleRoReponseL( iMessageBodyPtr, rights ) );
       
   835     TRAP( r, WriteL( _L8( "HandleRoapPduL->HandleRoReponseL done" ), err ) );
       
   836     User::LeaveIfError( err );
       
   837 #else
       
   838     roapHandler->HandleRoReponseL( iMessageBodyPtr, rights );
       
   839 #endif
       
   840 
       
   841 
       
   842     //handle parsed rights and save uri into mtm
       
   843     if ( rights.Count() )
       
   844         {
       
   845         HBufC8* contentURI( NULL );
       
   846         HBufC16* buffer( NULL );
       
   847         HBufC16* number( NULL );
       
   848         HBufC16* messageContent( NULL );
       
   849         TUint32 localId( 0 );
       
   850         TInt ret( KErrNone );
       
   851 
       
   852 #ifdef  _DRM_TESTING
       
   853         TRAP( r, WriteL( _L8( "HandleRoapPduL->CID" ) ) );
       
   854 #endif
       
   855         ret = rights[0]->GetContentURI( contentURI );
       
   856         // null contentURI means invalid RO
       
   857         LeaveIfNullL( ret,  contentURI );
       
   858 #ifdef  _DRM_TESTING
       
   859         TRAP( r, WriteL( *contentURI ) );
       
   860 #endif
       
   861         localId = rights[0]->GetLocalID();
       
   862         CleanupStack::PushL( contentURI );
       
   863         buffer = HBufC16::NewL( contentURI->Length() );
       
   864         TPtr uri16( buffer->Des() );
       
   865         uri16.Copy( *contentURI );
       
   866         CleanupStack::PopAndDestroy( contentURI );
       
   867         contentURI = NULL;
       
   868         CleanupStack::PushL( buffer );
       
   869         number = HBufC16::NewLC( 11 ); //longer than max of tuint32
       
   870         TPtr ptr( number->Des() );
       
   871         ptr.AppendNum( localId, EDecimal );
       
   872         messageContent = HBufC16::NewL( ptr.Length() + uri16.Length() + 4 );
       
   873         TPtr ptrToMz( messageContent->Des() );
       
   874         ptrToMz.Append( _L( "1 " ) );
       
   875         ptrToMz.Append( ptr ); // add localID
       
   876         ptrToMz.Append( _L( " " ) ); // add space
       
   877         ptrToMz.Append( uri16 ); //add uri16
       
   878         CleanupStack::PopAndDestroy( number );
       
   879         CleanupStack::PopAndDestroy( buffer );
       
   880         CleanupStack::PushL( messageContent );
       
   881         // create empty sms
       
   882         iMsvId = CreateNewMessageL();
       
   883         SetEntryL( iMsvId );
       
   884         // adds content in sms and moves it inbox
       
   885         AddRoContentL( ptrToMz );
       
   886         CleanupStack::PopAndDestroy( messageContent );
       
   887         }
       
   888 
       
   889     // Finish up
       
   890     CleanupStack::PopAndDestroy( &rights );
       
   891     CleanupStack::PopAndDestroy( roapHandler );
       
   892 #ifdef _DRM_TESTING
       
   893     TRAP( r, WriteL( _L8( "HandleRoapPduL-End" ) ) );
       
   894 #endif
       
   895     }
       
   896 
       
   897 /*
       
   898 -----------------------------------------------------------------------------
       
   899 
       
   900     Method: HandleRoapTriggerL
       
   901 
       
   902     Description: Handles OMA 2.0 ROAP Trigger message
       
   903 
       
   904     Return Value: None.
       
   905 
       
   906     Status: Proposal
       
   907 
       
   908 -----------------------------------------------------------------------------
       
   909 */
       
   910 void CRoHandler::HandleRoapTriggerL()
       
   911     {
       
   912 #ifdef _DRM_TESTING
       
   913     TRAPD( r, WriteL( _L8( "HandleRoapTriggerL" ) ) );
       
   914 #endif
       
   915 
       
   916     _LIT( KFile, "%S%u.tri" );
       
   917     RFile f;
       
   918     TFileName fileName;
       
   919     TPtr ptr( NULL, 0 );
       
   920     HBufC* content( NULL );
       
   921     TInt ret( KErrNone );
       
   922     TInt driveNumber( -1 );
       
   923 
       
   924 
       
   925     // create empty sms
       
   926     iMsvId = CreateNewMessageL();
       
   927     SetEntryL( iMsvId );
       
   928 
       
   929 #ifndef RD_MULTIPLE_DRIVE
       
   930 
       
   931     driveNumber = EDriveC;
       
   932     ret = iFs.MkDirAll( KRoHandlerTriggerFilePath );
       
   933     fileName.Format( KFile, &KRoHandlerTriggerFilePath, iMsvId );
       
   934 
       
   935 #else //RD_MULTIPLE_DRIVE
       
   936 
       
   937     TChar driveLetter;
       
   938     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
       
   939     iFs.DriveToChar( driveNumber, driveLetter );
       
   940 
       
   941     TFileName roHandlerTriggerFilePath;
       
   942     roHandlerTriggerFilePath.Format(
       
   943                     KRoHandlerTriggerFilePath, ( TUint )driveLetter );
       
   944 
       
   945     ret = iFs.MkDirAll( roHandlerTriggerFilePath );
       
   946     fileName.Format( KFile, &roHandlerTriggerFilePath, iMsvId );
       
   947 
       
   948 #endif
       
   949     if ( ret && ret != KErrAlreadyExists )
       
   950         {
       
   951         User::LeaveIfError( ret );
       
   952         }
       
   953 
       
   954     // Create cleanup item for file to be deleted on leave.
       
   955     CFileDeleter* fileDeleter( CFileDeleter::NewLC( iFs, fileName ) );
       
   956 
       
   957     // Leave if there is not enough space for file to be created.
       
   958     if ( SysUtil::DiskSpaceBelowCriticalLevelL(
       
   959             &iFs, iMessageBodyPtr.Size(), driveNumber ) )
       
   960         {
       
   961         User::Leave( KErrDiskFull );
       
   962         }
       
   963 
       
   964     User::LeaveIfError( f.Replace( iFs, fileName, EFileWrite ) );
       
   965 #ifdef _DRM_TESTING
       
   966     TRAP( r, WriteL( fileName, iMsvId ) );
       
   967 #endif
       
   968     CleanupClosePushL( f );
       
   969     User::LeaveIfError( f.Write( iMessageBodyPtr ) );
       
   970     CleanupStack::PopAndDestroy( &f );
       
   971 
       
   972     // Delete created file on leave.
       
   973     fileDeleter->SetDelete();
       
   974 
       
   975 
       
   976     //format content
       
   977     if ( iMsgType == EOma2RoapTriggerRoAcquisition )
       
   978         {
       
   979 #ifdef _DRM_TESTING
       
   980         TRAP( r, WriteL( _L8( "HandleRoapTriggerL->EOma2RoapTriggerRoAcquisition" ) ) );
       
   981 #endif
       
   982         content = HBufC::NewLC(
       
   983             fileName.Length() + KRoAcquisitionPrefix().Length() );
       
   984         ptr.Set( content->Des() );
       
   985         ptr.Append( KRoAcquisitionPrefix() );
       
   986         ptr.Append( fileName );
       
   987 #ifdef RD_DRM_SILENT_RIGHTS_ACQUISITION
       
   988         // do the ROAP silently, but if it fails, create the inbox entry
       
   989         if ( !DoRoapL( iMessageBodyPtr ) )
       
   990             {
       
   991             AddRoContentL( ptr );
       
   992             }
       
   993 #else
       
   994         // adds content in sms and moves it inbox
       
   995         AddRoContentL( ptr );
       
   996 #endif
       
   997         CleanupStack::PopAndDestroy( content );
       
   998         }
       
   999     else
       
  1000         {
       
  1001         content = HBufC::NewLC(
       
  1002             fileName.Length() + KTriggerPrefix().Length() );
       
  1003         ptr.Set( content->Des() );
       
  1004         ptr.Append( KTriggerPrefix() );
       
  1005         ptr.Append( fileName );
       
  1006         AddRoContentL( ptr );
       
  1007         CleanupStack::PopAndDestroy( content );
       
  1008         }
       
  1009     // No leaves. So keep created file.
       
  1010     fileDeleter->SetNoDelete();
       
  1011     CleanupStack::PopAndDestroy( fileDeleter );
       
  1012 
       
  1013 #ifdef _DRM_TESTING
       
  1014     TRAP( r, WriteL( ptr ) );
       
  1015 #endif
       
  1016 
       
  1017 #ifdef _DRM_TESTING
       
  1018     TRAP( r, WriteL( _L8( "HandleRoapTriggerL-End" ) ) );
       
  1019 #endif
       
  1020     }
       
  1021 
       
  1022 /*
       
  1023 -----------------------------------------------------------------------------
       
  1024 
       
  1025     Method: CancelHandleMessage
       
  1026 
       
  1027     Description: Cancels the pending asynchronous HandleMessageL.
       
  1028 
       
  1029     Return Value: None.
       
  1030 
       
  1031     Status: Proposal
       
  1032 
       
  1033 -----------------------------------------------------------------------------
       
  1034 */
       
  1035 
       
  1036 void CRoHandler::CancelHandleMessage
       
  1037         (
       
  1038         //None.
       
  1039         )
       
  1040     {
       
  1041 #ifdef _DRM_TESTING
       
  1042     TRAPD( r, WriteL( _L8( "CancelHandleMessage" ) ) );
       
  1043 #endif
       
  1044 
       
  1045 #ifdef _DRM_TESTING
       
  1046     TRAP( r, WriteL( _L8( "CancelHandleMessage-End" ) ) );
       
  1047 #endif
       
  1048     }
       
  1049 
       
  1050 
       
  1051 /*
       
  1052 -----------------------------------------------------------------------------
       
  1053 
       
  1054     Method: CreateNewMessageL
       
  1055 
       
  1056     Description: Creates a new message server entry and set up default values.
       
  1057 
       
  1058     Return values:      TMsvId (the id of created entry)
       
  1059 
       
  1060     Status: Proposal
       
  1061 
       
  1062 -----------------------------------------------------------------------------
       
  1063 */
       
  1064 
       
  1065 TMsvId CRoHandler::CreateNewMessageL
       
  1066         (
       
  1067         //None.
       
  1068         )
       
  1069     {
       
  1070 #ifdef _DRM_TESTING
       
  1071     TRAPD( r, WriteL( _L8( "CreateNewMessageL" ) ) );
       
  1072 #endif
       
  1073     TMsvEntry newEntry;// This represents an entry in the Message Server index
       
  1074     newEntry.iMtm = KUidMsgTypeRO;// message type is RO
       
  1075     newEntry.iType = KUidMsvMessageEntry;                   // this defines the type of the entry: message
       
  1076     newEntry.iServiceId = KMsvLocalServiceIndexEntryId;     // ID of local service (containing the standard folders)
       
  1077     newEntry.iDate.UniversalTime();                         // set the date of the entry to Universal time
       
  1078     newEntry.SetVisible( EFalse );
       
  1079     newEntry.SetUnread( ETrue );                            // a soft notification would come
       
  1080 
       
  1081     HBufC* detail( GetDetailLC() );
       
  1082 #ifdef _DRM_TESTING
       
  1083     TRAP( r, WriteL( _L( "detail" ) ) );
       
  1084     TRAP( r, WriteL( *detail, detail->Des().Length() ) );
       
  1085 #endif
       
  1086 
       
  1087     HBufC* description( GetDescriptionLC() );
       
  1088 
       
  1089     newEntry.iDetails.Set( detail->Des() );
       
  1090 #ifdef _DRM_TESTING
       
  1091     TRAP( r, WriteL( _L( "newEntry.iDetails:" ) ) );
       
  1092     TRAP( r, WriteL( newEntry.iDetails, newEntry.iDetails.Length() ) );
       
  1093 #endif
       
  1094 
       
  1095     newEntry.iDescription.Set( description->Des() );
       
  1096 
       
  1097     newEntry.SetInPreparation( ETrue );                       // a flag that this message is in preparation
       
  1098     //----
       
  1099     //newEntry.iBioType = 0x1000ffff;                         // define a bio UID if sending a bio message over SMS bearer
       
  1100     //----
       
  1101 
       
  1102     // - CMsvEntry accesses and acts upon a particular Message Server entry.
       
  1103     // - NewL() does not create a new entry, but simply a new object to access an existing entry.
       
  1104     // - It takes in as parameters the client's message server session,
       
  1105     //   ID of the entry to access and initial sorting order of the children of the entry.
       
  1106     //
       
  1107     CMsvEntry* entry( NULL );
       
  1108     entry = CMsvEntry::NewL(
       
  1109         *iSession, KMsvDraftEntryIdValue, TMsvSelectionOrdering() );
       
  1110     CleanupStack::PushL( entry );
       
  1111 
       
  1112     CMsvOperationActiveSchedulerWait* wait( NULL );
       
  1113     wait = CMsvOperationActiveSchedulerWait::NewLC();
       
  1114     CMsvOperation* oper( entry->CreateL( newEntry, wait->iStatus ) );
       
  1115     CleanupStack::PushL( oper );
       
  1116     wait->Start();
       
  1117 
       
  1118     // ...and keep track of the progress of the create operation.
       
  1119     TMsvLocalOperationProgress progress(
       
  1120         McliUtils::GetLocalProgressL( *oper ) );
       
  1121     User::LeaveIfError( progress.iError );
       
  1122 
       
  1123     // Set our entry context to the created one
       
  1124     entry->SetEntryL( progress.iId ); // operation progress contains the ID of the ceated entry
       
  1125     CleanupStack::PopAndDestroy( oper );
       
  1126     CleanupStack::PopAndDestroy( wait );
       
  1127     CleanupStack::PopAndDestroy( entry );
       
  1128     CleanupStack::PopAndDestroy( description );
       
  1129     CleanupStack::PopAndDestroy( detail );
       
  1130 
       
  1131 #ifdef _DRM_TESTING
       
  1132     TRAP( r, WriteL( _L8( "CreateNewMessageL-End" ) ) );
       
  1133 #endif
       
  1134     return progress.iId;
       
  1135     }
       
  1136 
       
  1137 
       
  1138 
       
  1139 HBufC* CRoHandler::ConvertDetailsL( const TDesC8& aFrom )
       
  1140     {
       
  1141 #ifdef _DRM_TESTING
       
  1142     TRAPD( r, WriteL( _L8( "ConvertDetailsL" ) ) );
       
  1143 #endif
       
  1144     HBufC* from( HBufC::NewMaxLC( aFrom.Length() ) );
       
  1145     from->Des().Copy( aFrom );
       
  1146 
       
  1147     TUriParser16 pars;
       
  1148     User::LeaveIfError( pars.Parse( *from ) );
       
  1149 
       
  1150     HBufC* res( NULL );
       
  1151     if ( pars.IsPresent( EUriHost ) )
       
  1152         {
       
  1153         res = pars.Extract( EUriHost ).AllocL();
       
  1154         }
       
  1155     else
       
  1156         {
       
  1157         res = from->AllocL();
       
  1158         }
       
  1159 
       
  1160     CleanupStack::PopAndDestroy( from );
       
  1161 
       
  1162 #ifdef _DRM_TESTING
       
  1163     TRAP( r, WriteL( _L8( "ConvertDetailsL-End" ) ) );
       
  1164 #endif
       
  1165     return res;
       
  1166     }
       
  1167 
       
  1168 void CRoHandler::ReadFromResourceLC(
       
  1169             const TDesC& aFile,
       
  1170             const TInt& aIndex,
       
  1171             HBufC*& aBuf )
       
  1172     {
       
  1173 #ifdef _DRM_TESTING
       
  1174     TRAPD( r, WriteL( _L8( "ReadFromResourceLC" ) ) );
       
  1175 #endif
       
  1176     RFs fs;
       
  1177     if ( aBuf )
       
  1178         {
       
  1179         delete aBuf;
       
  1180         aBuf = NULL;
       
  1181         }
       
  1182     User::LeaveIfError( fs.Connect() );
       
  1183 #ifdef _DRM_TESTING
       
  1184     TRAP( r, WriteL( _L8( "ReadFromResourceLC-fs.Connect" ) ) );
       
  1185 #endif
       
  1186     CleanupClosePushL( fs );
       
  1187     CStringResourceReader* reader(
       
  1188         new ( ELeave ) CStringResourceReader( fs, aFile ) );
       
  1189 #ifdef _DRM_TESTING
       
  1190     TRAP( r, WriteL( _L8( "ReadFromResourceLC-CStringResourceReader" ) ) );
       
  1191 #endif
       
  1192     CleanupStack::PushL( reader );
       
  1193     aBuf = reader->AllocReadResourceL( aIndex );
       
  1194 #ifdef _DRM_TESTING
       
  1195     TRAP( r, WriteL( _L8( "ReadFromResourceLC-AllocReadResourceL" ) ) );
       
  1196 #endif
       
  1197     CleanupStack::PopAndDestroy( reader );
       
  1198     CleanupStack::PopAndDestroy( &fs );
       
  1199     CleanupStack::PushL( aBuf );
       
  1200 #ifdef _DRM_TESTING
       
  1201     TRAP( r, WriteL( _L8( "ReadFromResourceLC-End" ) ) );
       
  1202 #endif
       
  1203     }
       
  1204 
       
  1205 HBufC* CRoHandler::GetDetailLC()
       
  1206     {
       
  1207 #ifdef _DRM_TESTING
       
  1208     TRAPD( r, WriteL( _L8( "GetDetailLC" ) ) );
       
  1209 #endif
       
  1210     // Get server address.
       
  1211     TPtrC8 srvAddress;
       
  1212     TBool flag( iPushMsg->GetServerAddress( srvAddress ) );
       
  1213     HBufC* buf( NULL );
       
  1214     HBufC* result( NULL );
       
  1215 
       
  1216     // First line in Inbox: TMsvEntry::iDetails.
       
  1217     if ( !flag || srvAddress.Length() == 0 )
       
  1218         {
       
  1219         // Read from resource.
       
  1220 
       
  1221 #ifndef RD_MULTIPLE_DRIVE
       
  1222 
       
  1223         TFileName resourceFile( KDriveZ );
       
  1224 
       
  1225 #else //RD_MULTIPLE_DRIVE
       
  1226 
       
  1227         _LIT( KDriveRoot, "%c:" );
       
  1228         TInt driveNumber( -1 );
       
  1229         TChar driveLetter;
       
  1230         DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber );
       
  1231         iFs.DriveToChar( driveNumber, driveLetter );
       
  1232 
       
  1233         TFileName resourceFile;
       
  1234         resourceFile.Format( KDriveRoot, (TUint )driveLetter );
       
  1235 
       
  1236 #endif
       
  1237 
       
  1238         resourceFile.Append( KDC_MTM_RESOURCE_DIR );
       
  1239         resourceFile.Append( KPushMtmRes );
       
  1240         ReadFromResourceLC( resourceFile, R_PUSHMISC_UNK_SENDER, result );
       
  1241         }
       
  1242     else
       
  1243         {
       
  1244         // Convert the "From" information to the format required by the UI
       
  1245         // spec and then decode it.
       
  1246 #ifdef _DRM_TESTING
       
  1247         TRAP( r, WriteL( _L( "From form: " ) ) );
       
  1248         TRAP( r, WriteL( srvAddress, srvAddress.Length() ) );
       
  1249 #endif
       
  1250         buf = ConvertDetailsL( srvAddress );
       
  1251 #ifdef _DRM_TESTING
       
  1252         TRAP( r, WriteL( _L( "Uri form: " ) ) );
       
  1253         TRAP( r, WriteL( *buf, buf->Length() ) );
       
  1254 #endif
       
  1255         CleanupStack::PushL( buf );
       
  1256         result = ConvertUriToDisplayFormL( *buf );
       
  1257 #ifdef _DRM_TESTING
       
  1258         TRAP( r, WriteL( _L( "Final form: " ) ) );
       
  1259         TRAP( r, WriteL( *result, result->Length() ) );
       
  1260 #endif
       
  1261         CleanupStack::PopAndDestroy( buf ); // buf
       
  1262         buf = NULL;
       
  1263         CleanupStack::PushL( result );
       
  1264         }
       
  1265 #ifdef _DRM_TESTING
       
  1266     TRAP( r, WriteL( _L8( "GetDetailLC-End" ) ) );
       
  1267 #endif
       
  1268     return result;
       
  1269     }
       
  1270 
       
  1271 HBufC* CRoHandler::ConvertUriToDisplayFormL( const TDesC& aUri )
       
  1272     {
       
  1273 #ifdef _DRM_TESTING
       
  1274     TRAPD( r, WriteL( _L8( "ConvertUriToDisplayFormL" ) ) );
       
  1275 #endif
       
  1276     HBufC8* uri8( HBufC8::NewMaxLC( aUri.Length() ) );
       
  1277     uri8->Des().Copy( aUri );
       
  1278     TUriParser8 uriParser8;
       
  1279     User::LeaveIfError( uriParser8.Parse( *uri8 ) );
       
  1280     CUri16* convertedCUri( UriUtils::ConvertToDisplayFormL( uriParser8 ) );
       
  1281     CleanupStack::PopAndDestroy( uri8 );
       
  1282     CleanupStack::PushL( convertedCUri );
       
  1283     HBufC* convertedUri( convertedCUri->Uri().UriDes().AllocL() );
       
  1284     CleanupStack::PopAndDestroy( convertedCUri );
       
  1285 #ifdef _DRM_TESTING
       
  1286     TRAP( r, WriteL( _L8( "ConvertUriToDisplayFormL-End" ) ) );
       
  1287 #endif
       
  1288     return convertedUri;
       
  1289     }
       
  1290 
       
  1291 HBufC* CRoHandler::GetDescriptionLC()
       
  1292     {
       
  1293 #ifdef _DRM_TESTING
       
  1294     TRAPD( r, WriteL( _L8( "GetDescriptionLC" ) ) );
       
  1295 #endif
       
  1296     HBufC* buf( NULL );
       
  1297 
       
  1298 #ifndef RD_MULTIPLE_DRIVE
       
  1299 
       
  1300     TFileName resourceFile( KDriveZ );
       
  1301 
       
  1302 #else //RD_MULTIPLE_DRIVE
       
  1303 
       
  1304     _LIT( KDriveRoot, "%c:" );
       
  1305     TInt driveNumber( -1 );
       
  1306     TChar driveLetter;
       
  1307     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber );
       
  1308     iFs.DriveToChar( driveNumber, driveLetter );
       
  1309 
       
  1310     TFileName resourceFile;
       
  1311     resourceFile.Format( KDriveRoot, ( TUint )driveLetter );
       
  1312 
       
  1313 #endif
       
  1314 
       
  1315     resourceFile.Append( KDC_RESOURCE_FILES_DIR );
       
  1316     resourceFile.Append( KRoHandlerResourceFile );
       
  1317 
       
  1318     if ( iMsgType == EOma2RoapTrigger )
       
  1319         {
       
  1320 #ifdef _DRM_TESTING
       
  1321     TRAP( r, WriteL( resourceFile ) );
       
  1322 #endif
       
  1323         ReadFromResourceLC(
       
  1324             resourceFile, R_ROHL_INBOX_DESCRIPTION_ROA, buf );
       
  1325         }
       
  1326     else
       
  1327         {
       
  1328 #ifdef _DRM_TESTING
       
  1329     TRAP( r, WriteL( resourceFile ) );
       
  1330 #endif
       
  1331         ReadFromResourceLC( resourceFile, R_ROHL_INBOX_DESCRIPTION, buf );
       
  1332         }
       
  1333 
       
  1334 #ifdef _DRM_TESTING
       
  1335     TRAP( r, WriteL( _L8( "GetDescriptionLC-End" ) ) );
       
  1336 #endif
       
  1337     return buf;
       
  1338     }
       
  1339 
       
  1340 /*
       
  1341 -----------------------------------------------------------------------------
       
  1342 
       
  1343     Method: DoCancel
       
  1344 
       
  1345     Description:Cancels the operation.
       
  1346 
       
  1347     Return Value: None.
       
  1348 
       
  1349     Status: Proposal
       
  1350 
       
  1351 -----------------------------------------------------------------------------
       
  1352 */
       
  1353 
       
  1354 void CRoHandler::DoCancel
       
  1355         (
       
  1356         //None.
       
  1357         )
       
  1358     {
       
  1359 #ifdef _DRM_TESTING
       
  1360     TRAPD( r, WriteL( _L8( "DoCancel" ) ) );
       
  1361 #endif
       
  1362 
       
  1363 #ifdef _DRM_TESTING
       
  1364     TRAP( r, WriteL( _L8( "DoCancel-End" ) ) );
       
  1365 #endif
       
  1366     }
       
  1367 
       
  1368 /*
       
  1369 -----------------------------------------------------------------------------
       
  1370 
       
  1371     Method: RunL
       
  1372 
       
  1373     Description: Basically all the work is done from/through this method
       
  1374 
       
  1375     Return Value: None.
       
  1376 
       
  1377     Status: Proposal
       
  1378 
       
  1379 -----------------------------------------------------------------------------
       
  1380 */
       
  1381 
       
  1382 void CRoHandler::RunL
       
  1383         (
       
  1384         //None.
       
  1385         )
       
  1386     {
       
  1387 #ifdef _DRM_TESTING
       
  1388     TRAPD( r, WriteL( _L8( "RunL" ) ) );
       
  1389 #endif
       
  1390     // First checking whether cancel has been called
       
  1391     if ( iStatus == KErrCancel )
       
  1392         {
       
  1393         iPluginKiller->KillPushPlugin();
       
  1394         return;
       
  1395         }
       
  1396 
       
  1397     switch( iMsgType )
       
  1398         {
       
  1399         case EOma1Ro:
       
  1400             {
       
  1401             HandleRightsMessageL();
       
  1402             break;
       
  1403             }
       
  1404 #ifdef __DRM_OMA2
       
  1405         case EOma2RoapTrigger:
       
  1406         case EOma2RoapTriggerRoAcquisition:
       
  1407             {
       
  1408             HandleRoapTriggerL();
       
  1409             break;
       
  1410             }
       
  1411         case EOma2RoapPdu:
       
  1412             {
       
  1413             HandleRoapPduL();
       
  1414             break;
       
  1415             }
       
  1416 #endif
       
  1417         default:
       
  1418             {
       
  1419             User::Leave( KErrNotSupported );
       
  1420             }
       
  1421         }
       
  1422 #ifdef _DRM_TESTING
       
  1423     TRAP( r, WriteL( _L8( "RunL-End" ) ) );
       
  1424 #endif
       
  1425     }
       
  1426 /*
       
  1427 -----------------------------------------------------------------------------
       
  1428 
       
  1429     Method: RunError
       
  1430 
       
  1431     Description: Called by ActiveScheduler in case RunL leaves.
       
  1432                  Currently does nothing.
       
  1433 
       
  1434     Return Value: <errorcode>: Currently same as was given as a parameter
       
  1435 
       
  1436     Status: Proposal
       
  1437 
       
  1438 -----------------------------------------------------------------------------
       
  1439 */
       
  1440 
       
  1441 TInt CRoHandler::RunError
       
  1442         (
       
  1443         TInt
       
  1444 #ifdef _DRM_TESTING
       
  1445         aError // errorcode
       
  1446 #endif
       
  1447         )
       
  1448     {
       
  1449 #ifdef _DRM_TESTING
       
  1450     TRAPD( r, WriteL( _L8( "RunError" ) ) );
       
  1451 #endif
       
  1452 
       
  1453 #ifdef _DRM_TESTING
       
  1454     TRAP( r, WriteL( _L8( "RunError-End" ), aError ) );
       
  1455 #endif
       
  1456     return KErrNone;
       
  1457     }
       
  1458 
       
  1459 /*
       
  1460 -----------------------------------------------------------------------------
       
  1461 
       
  1462     Method: CPushHandlerBase_Reserved1
       
  1463 
       
  1464     Description: Reserved for future expansion.
       
  1465 
       
  1466     Return Value: None.
       
  1467 
       
  1468     Status: Proposal
       
  1469 
       
  1470 -----------------------------------------------------------------------------
       
  1471 */
       
  1472 
       
  1473 void CRoHandler::CPushHandlerBase_Reserved1
       
  1474         (
       
  1475         //None.
       
  1476         )
       
  1477     {
       
  1478     _LIT( KNotSupported, "This method is not supported!" );
       
  1479     User::Panic( KNotSupported, KErrNotSupported );
       
  1480     }
       
  1481 
       
  1482 /*
       
  1483 -----------------------------------------------------------------------------
       
  1484 
       
  1485     Method: CPushHandlerBase_Reserved2
       
  1486 
       
  1487     Description: Reserved for future expansion.
       
  1488 
       
  1489     Return Value: None.
       
  1490 
       
  1491     Status: Proposal
       
  1492 
       
  1493 -----------------------------------------------------------------------------
       
  1494 */
       
  1495 
       
  1496 void CRoHandler::CPushHandlerBase_Reserved2
       
  1497         (
       
  1498         //None.
       
  1499         )
       
  1500     {
       
  1501     _LIT( KNotSupported, "This method is not supported!" );
       
  1502     User::Panic( KNotSupported, KErrNotSupported );
       
  1503     }
       
  1504 
       
  1505 /*
       
  1506 -----------------------------------------------------------------------------
       
  1507 
       
  1508     Method: PerformChecks
       
  1509 
       
  1510     Description: Checks that message is current type
       
  1511 
       
  1512     Return Value:  TInt: KErrNone if ok else KErrCorrupt.
       
  1513 
       
  1514     Status: Proposal
       
  1515 
       
  1516 -----------------------------------------------------------------------------
       
  1517 */
       
  1518 
       
  1519 TInt CRoHandler::PerformChecks
       
  1520         (
       
  1521         //None.
       
  1522         )
       
  1523     {
       
  1524 #ifdef _DRM_TESTING
       
  1525     TRAPD( r, WriteL( _L8( "PerformChecks" ) ) );
       
  1526 #endif
       
  1527     if ( !iPushMsg )
       
  1528         {
       
  1529         return KErrCorrupt;
       
  1530         }
       
  1531     // Check that body != NULL
       
  1532     TBool bodyPresent( EFalse );
       
  1533     // fetch message body
       
  1534     bodyPresent = iPushMsg->GetMessageBody( iMessageBodyPtr );
       
  1535 
       
  1536     // 6 == minimum number of message fields. This is a very "mild" check but
       
  1537     // at least it guarantees that there is no empty body in the message
       
  1538 #ifdef _DRM_TESTING
       
  1539     TRAP( r, WriteL( _L8( "PerformChecks-End" ) ) );
       
  1540 #endif
       
  1541     if ( ( !bodyPresent ) || ( iMessageBodyPtr.Size() < 6 ) )
       
  1542         {
       
  1543         return KErrCorrupt;
       
  1544         }
       
  1545     return KErrNone;
       
  1546     }
       
  1547 
       
  1548 
       
  1549 /*
       
  1550 -----------------------------------------------------------------------------
       
  1551 
       
  1552     Method: CheckMessageTypeL
       
  1553 
       
  1554     Description: Checks the message type
       
  1555 
       
  1556     Return Value:  EOma1Ro, EOma2RoapPdu or EOma2RoapTrigger
       
  1557 
       
  1558     Status: Proposal
       
  1559 
       
  1560 -----------------------------------------------------------------------------
       
  1561 */
       
  1562 
       
  1563 TMessageType CRoHandler::CheckMessageTypeL
       
  1564         (
       
  1565         //None.
       
  1566         )
       
  1567     {
       
  1568 #ifdef _DRM_TESTING
       
  1569     TRAPD( r, WriteL( _L8( "CheckMessageType" ) ) );
       
  1570 #endif
       
  1571 
       
  1572 #ifdef _DRM_TESTING
       
  1573     TRAP( r, WriteL( _L8( "CheckMessageType-End" ) ) );
       
  1574 #endif
       
  1575     TPtrC8 messageBodyPtr( iMessageBodyPtr );
       
  1576     TMessageType recognizedMessageType( EOma1Ro );
       
  1577     if ( iMessageBodyPtr.FindF( KWbxmlRoapTriggerElement() ) != KErrNotFound  )
       
  1578         {
       
  1579         iParsedXmlTrigger = iWbxmlTriggerParser->ParseL( iMessageBodyPtr );
       
  1580         messageBodyPtr.Set( *iParsedXmlTrigger );
       
  1581         }
       
  1582     if ( messageBodyPtr.FindF( KRoapTriggerElement() ) != KErrNotFound )
       
  1583         {
       
  1584         if ( messageBodyPtr.FindF( KRoapTriggerRoAcquisition() ) != KErrNotFound )
       
  1585             {
       
  1586             recognizedMessageType = EOma2RoapTriggerRoAcquisition;
       
  1587             }
       
  1588         else if ( messageBodyPtr.FindF( KRoapTriggerMeteringReport() ) != KErrNotFound )
       
  1589             {
       
  1590             recognizedMessageType = EOma2RoapTriggerMetering;
       
  1591             }
       
  1592         else
       
  1593             {
       
  1594             recognizedMessageType = EOma2RoapTrigger;
       
  1595             }
       
  1596 
       
  1597         }
       
  1598     if ( iMessageBodyPtr.FindF( KRoapRoPduElement() ) != KErrNotFound )
       
  1599         {
       
  1600         recognizedMessageType = EOma2RoapPdu;
       
  1601         }
       
  1602     delete iParsedXmlTrigger;
       
  1603     iParsedXmlTrigger = NULL;
       
  1604     return recognizedMessageType;
       
  1605     }
       
  1606 
       
  1607 
       
  1608 /*
       
  1609 -----------------------------------------------------------------------------
       
  1610 
       
  1611     Method: SetEntryL
       
  1612 
       
  1613     Description: Set up current message entry.
       
  1614 
       
  1615     Note: It can be useful to remember the original entry id for
       
  1616           error handling.
       
  1617 
       
  1618     Status: Proposal
       
  1619 
       
  1620 -----------------------------------------------------------------------------
       
  1621 */
       
  1622 
       
  1623 void  CRoHandler::SetEntryL
       
  1624         (
       
  1625         TMsvId aEntryId //an entry in the Message Server index
       
  1626         )
       
  1627     {
       
  1628 #ifdef _DRM_TESTING
       
  1629     TRAPD( r, WriteL( _L8( "SetEntryL" ) ) );
       
  1630 #endif
       
  1631 
       
  1632     // Get the server entry from our session
       
  1633     CMsvEntry* entry( iSession->GetEntryL( aEntryId ) );
       
  1634     CleanupStack::PushL( entry );
       
  1635 
       
  1636     // Check if our mtm is different from the mtm set to our entry
       
  1637     if ( !iMtm || entry->Entry().iMtm != ( iMtm->Entry() ).Entry().iMtm )
       
  1638         {
       
  1639         // If so, we delete the old...
       
  1640         delete iMtm;
       
  1641         iMtm = NULL;
       
  1642         // ...and get a new one from the MtmRegistry
       
  1643         iMtm = iMtmReg->NewMtmL( entry->Entry().iMtm );
       
  1644         }
       
  1645     // Set our entry as current.
       
  1646     iMtm->SetCurrentEntryL( entry );
       
  1647 
       
  1648     CleanupStack::Pop( entry );
       
  1649     entry = NULL;
       
  1650 
       
  1651 #ifdef _DRM_TESTING
       
  1652     TRAP( r, WriteL( _L8( "SetEntryL-End" ) ) );
       
  1653 #endif
       
  1654     }
       
  1655 
       
  1656 /*
       
  1657 -----------------------------------------------------------------------------
       
  1658 
       
  1659     Method: MoveMessageEntryL
       
  1660 
       
  1661     Description: Moves an entry to another parent.
       
  1662 
       
  1663     Return values: TMsvId of the moved message
       
  1664 
       
  1665     Status: Proposal
       
  1666 
       
  1667 -----------------------------------------------------------------------------
       
  1668 */
       
  1669 
       
  1670 TMsvId CRoHandler::MoveMessageEntryL
       
  1671         (
       
  1672         TMsvId aTarget //an entry in the Message Server index
       
  1673         )
       
  1674     {
       
  1675 #ifdef _DRM_TESTING
       
  1676     TRAPD( r, WriteL( _L8( "MoveMessageEntryL" ) ) );
       
  1677 #endif
       
  1678     TMsvEntry msvEntry( ( iMtm->Entry() ).Entry() );
       
  1679     TMsvId id = msvEntry.Id();
       
  1680 
       
  1681     if ( msvEntry.Parent() != aTarget )
       
  1682         {
       
  1683         TMsvSelectionOrdering sort;
       
  1684         sort.SetShowInvisibleEntries( ETrue );    // we want to handle also the invisible entries
       
  1685         // Take a handle to the parent entry
       
  1686         CMsvEntry* parentEntry(
       
  1687             CMsvEntry::NewL( iMtm->Session(), msvEntry.Parent(), sort ) );
       
  1688         CleanupStack::PushL( parentEntry );
       
  1689 
       
  1690         // Move original from the parent to the new location
       
  1691         CMsvOperationActiveSchedulerWait* wait(
       
  1692             CMsvOperationActiveSchedulerWait::NewLC() );
       
  1693         CMsvOperation* op(
       
  1694             parentEntry->MoveL( msvEntry.Id(), aTarget, wait->iStatus ) );
       
  1695         CleanupStack::PushL( op );
       
  1696         wait->Start();
       
  1697 
       
  1698         TMsvLocalOperationProgress prog = McliUtils::GetLocalProgressL( *op );
       
  1699         User::LeaveIfError( prog.iError );
       
  1700         id = prog.iId; // id of the moved entry
       
  1701         CleanupStack::PopAndDestroy( op );
       
  1702         CleanupStack::PopAndDestroy( wait );
       
  1703         CleanupStack::PopAndDestroy( parentEntry );
       
  1704         }
       
  1705 #ifdef _DRM_TESTING
       
  1706     TRAP( r, WriteL( _L8( "MoveMessageEntryL-End" ) ) );
       
  1707 #endif
       
  1708     return id;
       
  1709     }
       
  1710 
       
  1711 TBool CRoHandler::DoRoapL( const TDesC8& aTrigger )
       
  1712     {
       
  1713     TBool r( EFalse );
       
  1714     LOG( _L8( "CRoHandler::DoRoapL ->" ) );
       
  1715     LOGHEX( aTrigger.Ptr(), aTrigger.Length() );
       
  1716     CRoapSyncWrapper *roap( CRoapSyncWrapper::NewL() );
       
  1717     CleanupStack::PushL( roap );
       
  1718     r = roap->HandleTriggerSilentlyL( aTrigger );
       
  1719     CleanupStack::PopAndDestroy( roap );
       
  1720     LOG( _L8( "CRoHandler::DoRoapL <-" ) );
       
  1721     return r;
       
  1722     }
       
  1723 
       
  1724 
       
  1725 void CRoHandler::HandleMeteringTriggerSilentlyL()
       
  1726     {
       
  1727     LOG( _L8( "CRoHandler::HandleMeteringTriggerSilentlyL ->" ) );
       
  1728     LOGHEX( iMessageBodyPtr.Ptr(), iMessageBodyPtr.Length() );
       
  1729 
       
  1730     if ( iMeteringSupported )
       
  1731         {
       
  1732         LOG( _L8( "Handling" ) );
       
  1733         CRoHandlerDMgrWrapper* dMgrWrapper( CRoHandlerDMgrWrapper::NewL() );
       
  1734         CleanupStack::PushL( dMgrWrapper );
       
  1735         dMgrWrapper->HandleRoapTriggerL( iMessageBodyPtr );
       
  1736         CleanupStack::PopAndDestroy( dMgrWrapper );
       
  1737         LOG( _L8( "Handled" ) );
       
  1738         }
       
  1739     else
       
  1740         {
       
  1741         LOG( _L8( "Metering trigger not supported --> dropping it" ) );
       
  1742         }
       
  1743     LOG( _L8( "CRoHandler::HandleMeteringTriggerSilentlyL <-" ) );
       
  1744     }
       
  1745 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
  1746 
       
  1747 /*
       
  1748    -----------------------------------------------------------------------------
       
  1749 
       
  1750 Method: ImplementationGroupProxy
       
  1751 
       
  1752     Description:
       
  1753 
       
  1754     Return Value: TImplementationProxy*: Implementation table to the
       
  1755                   ECOM framework
       
  1756 
       
  1757     Status: Proposal
       
  1758 
       
  1759 -----------------------------------------------------------------------------
       
  1760 */
       
  1761 
       
  1762 EXPORT_C const TImplementationProxy* ImplementationGroupProxy
       
  1763         (
       
  1764         TInt& aTableCount
       
  1765         )
       
  1766     {
       
  1767     aTableCount =
       
  1768         sizeof( ImplementationTable ) / sizeof( TImplementationProxy );
       
  1769     return ImplementationTable;
       
  1770     }
       
  1771 
       
  1772 
       
  1773 //  End of File