diff -r 000000000000 -r 95b198f216e5 omadrm/drmplugins/drmrohandler/src/CRoHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmplugins/drmrohandler/src/CRoHandler.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,1773 @@ +/* +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: ECOM plugin for receiving OMA Rights Objects +* +*/ + + +// INCLUDE FILES +#include // for CRichText +#include // for CDrmMessageParser +#include // for CDRMRights +#include // for TImplementationProxy +#include // for CPushHandlerBase +#include // for CPluginKiller +#include // for CPushMessage +#include // for CRoapEng +#include +#include +#include // link against centralrepository.lib +#include +#include +#include + +#ifdef RD_MULTIPLE_DRIVE +#include +#endif + +#include // TUriParser16 +#include // KDC_MTM_RESOURCE_DIR +#include // UriUtils and so on +#include // for R_PUSHMISC_UNK_SENDER +#include // for R_QTN_DRM_MGR_INB_TITLE +#include // Disk space checking + +#include "crohandler.h" +#include "romtmcli.h" // for CRightsObjectMtmClient +#include "roapsyncwrapper.h" + +#include "stringresourcereader.h" +#include "rohandlerdmgrwrapper.h" +#include "rohandlerinternalcrkeys.h" + +#ifdef _DEBUG +#define DRMDEBUGLIT( a, b ) _LIT( a, b ) +#define DRMDEBUG( a ) RDebug::Print( a ) +#define DRMDEBUG2( a, b ) RDebug::Print( a, b ) +_LIT( KRoLogDir, "DRM" ); +_LIT( KRoLogFile, "RoHandler.log" ); +#define LOG( a ) RFileLogger::Write( KRoLogDir(), KRoLogFile(), EFileLoggingModeAppend, a ); +#define LOGHEX( ptr, len ) RFileLogger::HexDump( \ + KRoLogDir(), KRoLogFile(), EFileLoggingModeAppend, _S(""), _S(""), ptr, len ); +#define LOG2( a, b ) RFileLogger::WriteFormat( \ + KRoLogDir(), KRoLogFile(), EFileLoggingModeAppend, a, b ); +#else +#define DRMDEBUGLIT( a, b ) +#define DRMDEBUG( a ) +#define DRMDEBUG2( a, b ) +#define LOG( a ) +#define LOGHEX( ptr, len ) +#define LOG2( a, b ) +#endif + +using namespace Roap; + + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(0x101F7B93, CRoHandler::NewL) + //{{0x101F7B93}, CRoHandler::NewL} + }; + +// For reading the string value of cenrep key Inbox entry visible (for +// received RO). The size of string "false" is 5. +const TInt KBooleanStringMaxSize = 5; + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +#ifdef RD_MULTIPLE_DRIVE +_LIT( KRoHandlerTriggerFilePath, "%c:\\system\\data\\" ); +#else +_LIT( KDriveZ, "z:" ); +_LIT( KRoHandlerTriggerFilePath, "c:\\system\\data\\" ); +#endif + +_LIT( KPushMtmRes, "PushMtmUi.rsc" ); +_LIT( KRoHandlerResourceFile, "RoHandler.rsc" ); + +_LIT8( KRoapTriggerElement, "roapTrigger" ); +_LIT8( KWbxmlRoapTriggerElement, "\x03\x13j" ); +_LIT8( KRoapTriggerRoAcquisition, "roAcquisition" ); +_LIT8( KRoapTriggerMeteringReport, "meteringReport" ); +_LIT8( KRoapRoPduElement, "roResponse" ); + +_LIT( KFalse, "false" ); +_LIT( KZero, "0" ); + +_LIT( KRoAcquisitionPrefix, "ROA:" ); +_LIT( KTriggerPrefix, "TRI:" ); + +// MODULE DATA STRUCTURES + +// Helper class for deleting file with given filename on cleanupstack +// Note does not own its members +// Used for cleaning up saved trigger if creating trigger related message +// inbox entry fails. +NONSHARABLE_CLASS( CFileDeleter ) : public CBase + { +public: + static CFileDeleter* NewLC( RFs& aFs, TFileName& aFileName ) + { + CFileDeleter* self( new ( ELeave ) CFileDeleter( aFs, aFileName ) ); + CleanupStack::PushL( self ); + return self; + } + + inline void SetDelete() + { + iDeleteFileOnDestroy = ETrue; + } + + inline void SetNoDelete() + { + iDeleteFileOnDestroy = EFalse; + } + + virtual ~CFileDeleter() + { + if ( iDeleteFileOnDestroy ) + { + iFs.Delete( iFileName ); + } + } + +private: + CFileDeleter() + { + } + CFileDeleter( const CFileDeleter& ) + { + } + CFileDeleter( RFs& aFs, TFileName& aFileName ) + : iFs( aFs ), iFileName( aFileName ) + { + } + + CFileDeleter& operator=( const CFileDeleter& ); + + TBool iDeleteFileOnDestroy; + RFs iFs; + TFileName iFileName; + }; + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== +#ifdef _DRM_TESTING +LOCAL_C void WriteLogL( const TDesC8& text, RFs &aFs ); +LOCAL_C void WriteFileL( const TDesC8& text, RFs &aFs, const TDesC& aName ); +LOCAL_C void CreateLogL(); +LOCAL_C void WriteL( const TDesC8& aText ); +LOCAL_C void WriteL( const TDesC& aText ); +LOCAL_C void WriteL( const TDesC8& aText, TInt aErr ); +LOCAL_C void WriteL( const TDesC& aText, TInt aErr ); +LOCAL_C void WriteCurrentTimeL(); +#endif + +// ----------------------------------------------------------------------------- +// Testing stuff +// ----------------------------------------------------------------------------- +// + +#ifdef _DRM_TESTING +LOCAL_C void WriteLogL( const TDesC8& text, RFs &aFs ) + { + _LIT( KLogFile, "c:\\CROHandler.txt" ); + WriteFileL( text, aFs, KLogFile ); + } + +LOCAL_C void WriteFileL( const TDesC8& text, RFs &aFs, const TDesC& aName ) + { + RFile file; + TInt size; + User::LeaveIfError( file.Open( aFs, aName, EFileWrite ) ); + CleanupClosePushL( file ); + User::LeaveIfError( file.Size( size ) ); + User::LeaveIfError( file.Write( size, text ) ); + CleanupStack::PopAndDestroy( &file ); + } + +LOCAL_C void CreateLogL() + { + RFs fs; + User::LeaveIfError( fs.Connect() ); + CleanupClosePushL( fs ); + RFile file; + User::LeaveIfError( file.Replace( fs, _L( "c:\\CROHandler.txt" ), EFileWrite ) ); + file.Close(); + CleanupStack::PopAndDestroy( &fs ); + } + +LOCAL_C void WriteL( const TDesC& aText ) + { + RFs fs; + User::LeaveIfError( fs.Connect() ); + CleanupClosePushL( fs ); + HBufC8* text = HBufC8::NewLC( 1000 ); + TPtr8 textptr( text->Des() ); + textptr.Append( aText ); + textptr.Append( _L8( "\r\n" ) ); + WriteLogL( textptr, fs ); + CleanupStack::PopAndDestroy( text ); + CleanupStack::PopAndDestroy( &fs ); + WriteCurrentTimeL(); + } + +LOCAL_C void WriteL( const TDesC8& aText ) + { + RFs fs; + User::LeaveIfError( fs.Connect() ); + CleanupClosePushL( fs ); + HBufC8* text = HBufC8::NewLC( 1000 ); + TPtr8 textptr( text->Des() ); + textptr.Append( aText ); + textptr.Append( _L8( "\r\n" ) ); + WriteLogL( textptr, fs ); + CleanupStack::PopAndDestroy( text ); + CleanupStack::PopAndDestroy( &fs ); + WriteCurrentTimeL(); + } + +LOCAL_C void WriteL( const TDesC8& aText, TInt aErr ) + { + _LIT8( KErr, ": %d" ); + HBufC8* text = HBufC8::NewLC( 1000 + 20 ); + TBuf8<20> num; + TPtr8 textptr( text->Des() ); + textptr.Append( aText ); + num.Format( KErr(), aErr ); + textptr.Append( num ); + WriteL( textptr ); + CleanupStack::PopAndDestroy( text ); + } + +LOCAL_C void WriteL( const TDesC& aText, TInt aErr ) + { + _LIT8( KErr, ": %d" ); + HBufC8* text = HBufC8::NewLC( 1000+20 ); + TBuf8<20> num; + TPtr8 textptr( text->Des() ); + textptr.Append( aText ); + num.Format( KErr(), aErr ); + textptr.Append( num ); + WriteL( textptr ); + CleanupStack::PopAndDestroy( text ); + } + +LOCAL_C void WriteCurrentTimeL() + { + RFs fs; + User::LeaveIfError( fs.Connect() ); + CleanupClosePushL( fs ); + HBufC8* text = HBufC8::NewLC( 100 ); + TPtr8 textptr( text->Des() ); + // Date and Time display + TTime time; + time.HomeTime(); + TBuf<256> dateString; + _LIT( KDate, "%*E%*D%X%*N%*Y %1 %2 '%3" ); + time.FormatL( dateString, KDate ); + textptr.Append( _L( "\r\n\t\tData:\t" ) ); + textptr.Append( dateString ); + _LIT( KTime, "%-B%:0%J%:1%T%:2%S%:3%+B" ); + time.FormatL( dateString, KTime ); + textptr.Append( _L( "\r\n\t\tTime:\t" ) ); + textptr.Append( dateString ); + textptr.Append( _L( "\r\n" ) ); + textptr.Append( _L( "\r\n" ) ); + WriteLogL( textptr, fs ); + CleanupStack::PopAndDestroy( text ); + CleanupStack::PopAndDestroy( &fs ); + } +#endif + + +// ---------------------------------------------------------------------------- +// DoResetAndDestroy +// Does RPointerArray< >->ResetAndDestroy() for the given array aPtr. +// ---------------------------------------------------------------------------- +// +LOCAL_C void DoResetAndDestroy( TAny* aPtr ) + { + ( reinterpret_cast< RPointerArray< CDRMRights >* >( aPtr ) )->ResetAndDestroy(); + delete aPtr; + aPtr = NULL; + } + +// ---------------------------------------------------------------------------- +// LeaveIfNullL +// Leaves with given error or with KErrArgument if aBuf is null +// ---------------------------------------------------------------------------- +// +LOCAL_C inline void LeaveIfNullL( const TInt aRet, const HBufC8* aBuf ) + { + if ( !aBuf ) + { + User::LeaveIfError( aRet ); + User::Leave( KErrArgument ); + } + } + +// ---------------------------------------------------------------------------- +// IsMeteringSupported +// ---------------------------------------------------------------------------- +// +LOCAL_C TBool IsMeteringSupported() + { +#ifdef RD_DRM_METERING + return ETrue; +#else + return EFalse; +#endif + } + + +// ============================ MEMBER FUNCTIONS =============================== + +/* +----------------------------------------------------------------------------- + + Method: NewL + + Description: 1st phase constructor + + Return Value: new CRoHandler + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +CRoHandler* CRoHandler::NewL + ( + //None. + ) + { +#ifdef _DRM_TESTING + TRAPD( r, CreateLogL() ); + TRAP( r, WriteL( _L8( "NewL" ) ) ); +#endif + CRoHandler* self( new( ELeave ) CRoHandler() ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "NewL-End" ) ) ); +#endif + return self; + } + +/* +----------------------------------------------------------------------------- + + Method: CRoHandler + + Description: C++ default constructor. Initialises the object + with zero/NULL values. + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +CRoHandler::CRoHandler + ( + //None. + ) + : CPushHandlerBase(), + iFirstTime( ETrue ), iPushMsg( NULL ), iMsvId( NULL ), + iPutRightsToInbox( ETrue ) + { + } + +/* +----------------------------------------------------------------------------- + + Method: ConstructL + + Description: Adds the AO to the Active Scheduler. Constructs iDrm object + then connects to drm server + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +void CRoHandler::ConstructL + ( + //None. + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "ConstructL" ) ) ); +#endif + + CRepository* repository( NULL ); + TInt err( KErrNone ); + + User::LeaveIfError( iFs.Connect() ); + + // create drm + iMessageParser = CDRMMessageParser::NewL(); + + // Create wbxml trigger parser instance + iWbxmlTriggerParser = DRM::CWbxmlRoapTriggerParser::NewL(); + + // Create CMsvSession + // new session is opened Synchronously + iSession = CMsvSession::OpenSyncL( *this ); + + iMtmReg = CClientMtmRegistry::NewL( *iSession ); + + // Check if metering feature is active + iMeteringSupported = IsMeteringSupported(); + + // Check cenrep key in order to find out whether received RO + // should be stored to inbox or not. + TRAP( err, repository = CRepository::NewL( KCRUidRoHandler ) ); + if ( !err ) + { + CleanupStack::PushL( repository ); + TBuf string; + TInt error = repository->Get( KDRMRoHandlerInboxEntryVisible, + string ); + + // If the value of the repository key is found either "false" or + // "0", do not store rights to an Inbox entry. + if ( ( string.CompareF( KFalse ) == 0 ) || + ( string.CompareF( KZero ) == 0 ) ) + { + iPutRightsToInbox = EFalse; + } + + CleanupStack::PopAndDestroy( repository ); + } + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "Repository->Get done" ), iPutRightsToInbox ) ); + TRAP( r, WriteL( _L8( "ConstructL-End" ) ) ); +#endif + } + +/* +----------------------------------------------------------------------------- + + Method: ~CRoHandler + + Description: Calls also baseclass destructor which calls + REcomSession::DestroyedImplementation( iDtor_ID_Key). + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +CRoHandler::~CRoHandler + ( + //None. + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "~CRoHandler" ) ) ); +#endif + + iFs.Close(); + // Delete the necessary instance attributes + delete iPushMsg; + delete iMessageParser; + delete iWbxmlTriggerParser; + delete iParsedXmlTrigger; + delete iMtm; + delete iMtmReg; + + iMsvId = NULL; + + // session must be deleted last (and constructed first) + delete iSession; + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "~CRoHandler-End" ) ) ); +#endif + } + +/* +----------------------------------------------------------------------------- + + Method: AddRoContentL + + Description: Adds Message content and number + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ +void CRoHandler::AddRoContentL + ( + TDesC& aMessageContent //message content descriptor + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "AddRoContentL" ) ) ); +#endif + TMsvEntry msvEntry( ( iMtm->Entry() ).Entry() ); + + // We get the message body from Mtm and insert a bodytext + CRichText& mtmBody( iMtm->Body() ); + mtmBody.Reset(); + mtmBody.InsertL( 0, aMessageContent ); // insert our msg tag as the body text + + // set iRecipient into the Details of the entry + msvEntry.SetNew( ETrue ); // set New + msvEntry.SetUnread( ETrue ); + msvEntry.SetVisible( ETrue ); + msvEntry.SetInPreparation( EFalse ); // set inPreparation to false + msvEntry.iDate.UniversalTime(); // set time to Universal Time + + // To handle the sms specifics we start using SmsMtm + CRightsObjectMtmClient* roMtm( NULL ); + roMtm = static_cast< CRightsObjectMtmClient* >( iMtm ); + + // save message + CMsvEntry& entry( iMtm->Entry() ); + entry.ChangeL( msvEntry ); // make sure that we are handling the right entry + roMtm->SaveMessageL(); // closes the message + + // This moves the message entry to Inbox + MoveMessageEntryL( KMsvGlobalInBoxIndexEntryId ); + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "AddRoContentL-End" ) ) ); +#endif + } + + +/* +----------------------------------------------------------------------------- + + Method: HandleSessionEventL + + Description: Starts the message handling procedure asynchronously. + Basically all the work is done in RunL method. + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ +void CRoHandler::HandleSessionEventL + ( + TMsvSessionEvent /* aEvent*/ , + TAny* /* aArg1*/ , + TAny* /* aArg2 */, + TAny* /* aArg3 */ + ) + { + } + +/* +----------------------------------------------------------------------------- + + Method: HandleMessageL + + Description: Asynchronous version of the HandleMessageL(). + NOT SUPPORTED + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ +void CRoHandler::HandleMessageL + ( + CPushMessage* aPushMsg, // push message + TRequestStatus& aStatus // status of the request + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "HandleMessageL(2)" ) ) ); +#endif + iPushMsg = aPushMsg; + SetConfirmationStatus( aStatus ); + SignalConfirmationStatus( KErrNotSupported ); + iPluginKiller->KillPushPlugin(); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "HandleMessageL(2)-End" ) ) ); +#endif + } + +/* +----------------------------------------------------------------------------- + + Method: HandleMessageL + + Description: Synchronous version of the HandleMessageL(). + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +void CRoHandler::HandleMessageL + ( + CPushMessage* aPushMsg // push message + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "HandleMessageL(1)" ) ) ); +#endif + iPushMsg = aPushMsg; + // + // Do sanity checks for the message. + // + User::LeaveIfError( PerformChecks() ); + iMsgType = CheckMessageTypeL(); + switch( iMsgType ) + { + case EOma1Ro: + { + HandleRightsMessageL(); + break; + } +#ifdef __DRM_OMA2 + case EOma2RoapTrigger: + case EOma2RoapTriggerRoAcquisition: + { + HandleRoapTriggerL(); + break; + } + case EOma2RoapTriggerMetering: + { + HandleMeteringTriggerSilentlyL(); + break; + } + case EOma2RoapPdu: + { + HandleRoapPduL(); + break; + } +#endif + default: + { + User::Leave( KErrNotSupported ); + } + } + + iPluginKiller->KillPushPlugin(); + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "HandleMessageL(1)-End" ) ) ); +#endif + } + +/* +----------------------------------------------------------------------------- + + Method: HandleRightsMessageL + + Description: Process rights object and + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + + +void CRoHandler::HandleRightsMessageL() + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "HandleRightsMessageL" ) ) ); +#endif + + HBufC16 *number( NULL ); + HBufC16 *messageContent( NULL ); + HBufC16* buffer( NULL ); + + TInt ret( 0 ); + if ( iMessageBodyPtr.Size() == 0 ) + { + User::Leave( KErrCorrupt ); + } + + // Heap desc contains Content URI + HBufC8* contentURI( NULL ); + TUint32 localId( 0 ); + RPointerArray< CDRMRights >* + rights( new ( ELeave ) RPointerArray< CDRMRights > ); + + if ( rights ) + { + // process rights + ret = iMessageParser->ProcessRightsObject( iMessageBodyPtr, *rights ); + } + else + { + User::Leave( KErrNoMemory ); + } + + if ( !ret && rights->Count() ) + { + TCleanupItem cleanup( DoResetAndDestroy, rights ); + CleanupStack::PushL( cleanup ); + ret = ( *rights )[ 0 ]->GetContentURI( contentURI ); + // null contentURI means invalid RO + LeaveIfNullL( ret, contentURI ); + localId = ( *rights )[ 0 ]->GetLocalID(); + CleanupStack::PopAndDestroy( rights ); + rights = NULL; + CleanupStack::PushL( contentURI ); + } + else + { + rights->ResetAndDestroy(); + delete rights; + rights = NULL; + User::LeaveIfError( ret ); + } + + if ( iPutRightsToInbox ) + { + buffer = HBufC16::NewL( contentURI->Length() ); + TPtr uri16( buffer->Des() ); + uri16.Copy( *contentURI ); + CleanupStack::PopAndDestroy( contentURI ); + contentURI = NULL; + CleanupStack::PushL( buffer ); + + number = HBufC16::NewLC( 11 ); //longer than max of tuint32 + TPtr ptr( number->Des() ); + ptr.AppendNum( localId, EDecimal ); + + messageContent = HBufC16::NewL( ptr.Length() + uri16.Length() + 4 ); + TPtr ptrToMz( messageContent->Des() ); + ptrToMz.Append( _L( "1 " ) ); + ptrToMz.Append( ptr ); // add localID + ptrToMz.Append( _L( " " ) ); // add space + ptrToMz.Append( uri16 ); //add uri16 + + CleanupStack::PopAndDestroy( number ); + CleanupStack::PopAndDestroy( buffer ); + CleanupStack::PushL( messageContent ); + + // create empty sms + iMsvId = CreateNewMessageL(); + SetEntryL( iMsvId ); + // adds content in sms and moves it inbox + AddRoContentL( ptrToMz ); + + CleanupStack::PopAndDestroy( messageContent ); + } + else + { + CleanupStack::PopAndDestroy( contentURI ); + } + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "HandleRightsMessageL-End" ) ) ); +#endif + } + + +/* +----------------------------------------------------------------------------- + + Method: HandleRoapPduL + + Description: Handles OMA 2.0 ROAP RO Response message + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ +void CRoHandler::HandleRoapPduL() + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "HandleRoapPduL" ) ) ); +#endif + Roap::CRoapEngBase* roapHandler( NULL ); + RPointerArray< CDRMRights > rights; + + roapHandler = CRoapEng::NewL(); + CleanupStack::PushL( roapHandler ); + + TCleanupItem cleanup( DoResetAndDestroy, &rights ); + CleanupStack::PushL( cleanup ); + + + //Parse received rights. +#ifdef _DRM_TESTING + TRAPD( err, roapHandler->HandleRoReponseL( iMessageBodyPtr, rights ) ); + TRAP( r, WriteL( _L8( "HandleRoapPduL->HandleRoReponseL done" ), err ) ); + User::LeaveIfError( err ); +#else + roapHandler->HandleRoReponseL( iMessageBodyPtr, rights ); +#endif + + + //handle parsed rights and save uri into mtm + if ( rights.Count() ) + { + HBufC8* contentURI( NULL ); + HBufC16* buffer( NULL ); + HBufC16* number( NULL ); + HBufC16* messageContent( NULL ); + TUint32 localId( 0 ); + TInt ret( KErrNone ); + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "HandleRoapPduL->CID" ) ) ); +#endif + ret = rights[0]->GetContentURI( contentURI ); + // null contentURI means invalid RO + LeaveIfNullL( ret, contentURI ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( *contentURI ) ); +#endif + localId = rights[0]->GetLocalID(); + CleanupStack::PushL( contentURI ); + buffer = HBufC16::NewL( contentURI->Length() ); + TPtr uri16( buffer->Des() ); + uri16.Copy( *contentURI ); + CleanupStack::PopAndDestroy( contentURI ); + contentURI = NULL; + CleanupStack::PushL( buffer ); + number = HBufC16::NewLC( 11 ); //longer than max of tuint32 + TPtr ptr( number->Des() ); + ptr.AppendNum( localId, EDecimal ); + messageContent = HBufC16::NewL( ptr.Length() + uri16.Length() + 4 ); + TPtr ptrToMz( messageContent->Des() ); + ptrToMz.Append( _L( "1 " ) ); + ptrToMz.Append( ptr ); // add localID + ptrToMz.Append( _L( " " ) ); // add space + ptrToMz.Append( uri16 ); //add uri16 + CleanupStack::PopAndDestroy( number ); + CleanupStack::PopAndDestroy( buffer ); + CleanupStack::PushL( messageContent ); + // create empty sms + iMsvId = CreateNewMessageL(); + SetEntryL( iMsvId ); + // adds content in sms and moves it inbox + AddRoContentL( ptrToMz ); + CleanupStack::PopAndDestroy( messageContent ); + } + + // Finish up + CleanupStack::PopAndDestroy( &rights ); + CleanupStack::PopAndDestroy( roapHandler ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "HandleRoapPduL-End" ) ) ); +#endif + } + +/* +----------------------------------------------------------------------------- + + Method: HandleRoapTriggerL + + Description: Handles OMA 2.0 ROAP Trigger message + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ +void CRoHandler::HandleRoapTriggerL() + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "HandleRoapTriggerL" ) ) ); +#endif + + _LIT( KFile, "%S%u.tri" ); + RFile f; + TFileName fileName; + TPtr ptr( NULL, 0 ); + HBufC* content( NULL ); + TInt ret( KErrNone ); + TInt driveNumber( -1 ); + + + // create empty sms + iMsvId = CreateNewMessageL(); + SetEntryL( iMsvId ); + +#ifndef RD_MULTIPLE_DRIVE + + driveNumber = EDriveC; + ret = iFs.MkDirAll( KRoHandlerTriggerFilePath ); + fileName.Format( KFile, &KRoHandlerTriggerFilePath, iMsvId ); + +#else //RD_MULTIPLE_DRIVE + + TChar driveLetter; + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); + iFs.DriveToChar( driveNumber, driveLetter ); + + TFileName roHandlerTriggerFilePath; + roHandlerTriggerFilePath.Format( + KRoHandlerTriggerFilePath, ( TUint )driveLetter ); + + ret = iFs.MkDirAll( roHandlerTriggerFilePath ); + fileName.Format( KFile, &roHandlerTriggerFilePath, iMsvId ); + +#endif + if ( ret && ret != KErrAlreadyExists ) + { + User::LeaveIfError( ret ); + } + + // Create cleanup item for file to be deleted on leave. + CFileDeleter* fileDeleter( CFileDeleter::NewLC( iFs, fileName ) ); + + // Leave if there is not enough space for file to be created. + if ( SysUtil::DiskSpaceBelowCriticalLevelL( + &iFs, iMessageBodyPtr.Size(), driveNumber ) ) + { + User::Leave( KErrDiskFull ); + } + + User::LeaveIfError( f.Replace( iFs, fileName, EFileWrite ) ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( fileName, iMsvId ) ); +#endif + CleanupClosePushL( f ); + User::LeaveIfError( f.Write( iMessageBodyPtr ) ); + CleanupStack::PopAndDestroy( &f ); + + // Delete created file on leave. + fileDeleter->SetDelete(); + + + //format content + if ( iMsgType == EOma2RoapTriggerRoAcquisition ) + { +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "HandleRoapTriggerL->EOma2RoapTriggerRoAcquisition" ) ) ); +#endif + content = HBufC::NewLC( + fileName.Length() + KRoAcquisitionPrefix().Length() ); + ptr.Set( content->Des() ); + ptr.Append( KRoAcquisitionPrefix() ); + ptr.Append( fileName ); +#ifdef RD_DRM_SILENT_RIGHTS_ACQUISITION + // do the ROAP silently, but if it fails, create the inbox entry + if ( !DoRoapL( iMessageBodyPtr ) ) + { + AddRoContentL( ptr ); + } +#else + // adds content in sms and moves it inbox + AddRoContentL( ptr ); +#endif + CleanupStack::PopAndDestroy( content ); + } + else + { + content = HBufC::NewLC( + fileName.Length() + KTriggerPrefix().Length() ); + ptr.Set( content->Des() ); + ptr.Append( KTriggerPrefix() ); + ptr.Append( fileName ); + AddRoContentL( ptr ); + CleanupStack::PopAndDestroy( content ); + } + // No leaves. So keep created file. + fileDeleter->SetNoDelete(); + CleanupStack::PopAndDestroy( fileDeleter ); + +#ifdef _DRM_TESTING + TRAP( r, WriteL( ptr ) ); +#endif + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "HandleRoapTriggerL-End" ) ) ); +#endif + } + +/* +----------------------------------------------------------------------------- + + Method: CancelHandleMessage + + Description: Cancels the pending asynchronous HandleMessageL. + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +void CRoHandler::CancelHandleMessage + ( + //None. + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "CancelHandleMessage" ) ) ); +#endif + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "CancelHandleMessage-End" ) ) ); +#endif + } + + +/* +----------------------------------------------------------------------------- + + Method: CreateNewMessageL + + Description: Creates a new message server entry and set up default values. + + Return values: TMsvId (the id of created entry) + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +TMsvId CRoHandler::CreateNewMessageL + ( + //None. + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "CreateNewMessageL" ) ) ); +#endif + TMsvEntry newEntry;// This represents an entry in the Message Server index + newEntry.iMtm = KUidMsgTypeRO;// message type is RO + newEntry.iType = KUidMsvMessageEntry; // this defines the type of the entry: message + newEntry.iServiceId = KMsvLocalServiceIndexEntryId; // ID of local service (containing the standard folders) + newEntry.iDate.UniversalTime(); // set the date of the entry to Universal time + newEntry.SetVisible( EFalse ); + newEntry.SetUnread( ETrue ); // a soft notification would come + + HBufC* detail( GetDetailLC() ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L( "detail" ) ) ); + TRAP( r, WriteL( *detail, detail->Des().Length() ) ); +#endif + + HBufC* description( GetDescriptionLC() ); + + newEntry.iDetails.Set( detail->Des() ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L( "newEntry.iDetails:" ) ) ); + TRAP( r, WriteL( newEntry.iDetails, newEntry.iDetails.Length() ) ); +#endif + + newEntry.iDescription.Set( description->Des() ); + + newEntry.SetInPreparation( ETrue ); // a flag that this message is in preparation + //---- + //newEntry.iBioType = 0x1000ffff; // define a bio UID if sending a bio message over SMS bearer + //---- + + // - CMsvEntry accesses and acts upon a particular Message Server entry. + // - NewL() does not create a new entry, but simply a new object to access an existing entry. + // - It takes in as parameters the client's message server session, + // ID of the entry to access and initial sorting order of the children of the entry. + // + CMsvEntry* entry( NULL ); + entry = CMsvEntry::NewL( + *iSession, KMsvDraftEntryIdValue, TMsvSelectionOrdering() ); + CleanupStack::PushL( entry ); + + CMsvOperationActiveSchedulerWait* wait( NULL ); + wait = CMsvOperationActiveSchedulerWait::NewLC(); + CMsvOperation* oper( entry->CreateL( newEntry, wait->iStatus ) ); + CleanupStack::PushL( oper ); + wait->Start(); + + // ...and keep track of the progress of the create operation. + TMsvLocalOperationProgress progress( + McliUtils::GetLocalProgressL( *oper ) ); + User::LeaveIfError( progress.iError ); + + // Set our entry context to the created one + entry->SetEntryL( progress.iId ); // operation progress contains the ID of the ceated entry + CleanupStack::PopAndDestroy( oper ); + CleanupStack::PopAndDestroy( wait ); + CleanupStack::PopAndDestroy( entry ); + CleanupStack::PopAndDestroy( description ); + CleanupStack::PopAndDestroy( detail ); + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "CreateNewMessageL-End" ) ) ); +#endif + return progress.iId; + } + + + +HBufC* CRoHandler::ConvertDetailsL( const TDesC8& aFrom ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "ConvertDetailsL" ) ) ); +#endif + HBufC* from( HBufC::NewMaxLC( aFrom.Length() ) ); + from->Des().Copy( aFrom ); + + TUriParser16 pars; + User::LeaveIfError( pars.Parse( *from ) ); + + HBufC* res( NULL ); + if ( pars.IsPresent( EUriHost ) ) + { + res = pars.Extract( EUriHost ).AllocL(); + } + else + { + res = from->AllocL(); + } + + CleanupStack::PopAndDestroy( from ); + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "ConvertDetailsL-End" ) ) ); +#endif + return res; + } + +void CRoHandler::ReadFromResourceLC( + const TDesC& aFile, + const TInt& aIndex, + HBufC*& aBuf ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "ReadFromResourceLC" ) ) ); +#endif + RFs fs; + if ( aBuf ) + { + delete aBuf; + aBuf = NULL; + } + User::LeaveIfError( fs.Connect() ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "ReadFromResourceLC-fs.Connect" ) ) ); +#endif + CleanupClosePushL( fs ); + CStringResourceReader* reader( + new ( ELeave ) CStringResourceReader( fs, aFile ) ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "ReadFromResourceLC-CStringResourceReader" ) ) ); +#endif + CleanupStack::PushL( reader ); + aBuf = reader->AllocReadResourceL( aIndex ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "ReadFromResourceLC-AllocReadResourceL" ) ) ); +#endif + CleanupStack::PopAndDestroy( reader ); + CleanupStack::PopAndDestroy( &fs ); + CleanupStack::PushL( aBuf ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "ReadFromResourceLC-End" ) ) ); +#endif + } + +HBufC* CRoHandler::GetDetailLC() + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "GetDetailLC" ) ) ); +#endif + // Get server address. + TPtrC8 srvAddress; + TBool flag( iPushMsg->GetServerAddress( srvAddress ) ); + HBufC* buf( NULL ); + HBufC* result( NULL ); + + // First line in Inbox: TMsvEntry::iDetails. + if ( !flag || srvAddress.Length() == 0 ) + { + // Read from resource. + +#ifndef RD_MULTIPLE_DRIVE + + TFileName resourceFile( KDriveZ ); + +#else //RD_MULTIPLE_DRIVE + + _LIT( KDriveRoot, "%c:" ); + TInt driveNumber( -1 ); + TChar driveLetter; + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber ); + iFs.DriveToChar( driveNumber, driveLetter ); + + TFileName resourceFile; + resourceFile.Format( KDriveRoot, (TUint )driveLetter ); + +#endif + + resourceFile.Append( KDC_MTM_RESOURCE_DIR ); + resourceFile.Append( KPushMtmRes ); + ReadFromResourceLC( resourceFile, R_PUSHMISC_UNK_SENDER, result ); + } + else + { + // Convert the "From" information to the format required by the UI + // spec and then decode it. +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L( "From form: " ) ) ); + TRAP( r, WriteL( srvAddress, srvAddress.Length() ) ); +#endif + buf = ConvertDetailsL( srvAddress ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L( "Uri form: " ) ) ); + TRAP( r, WriteL( *buf, buf->Length() ) ); +#endif + CleanupStack::PushL( buf ); + result = ConvertUriToDisplayFormL( *buf ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L( "Final form: " ) ) ); + TRAP( r, WriteL( *result, result->Length() ) ); +#endif + CleanupStack::PopAndDestroy( buf ); // buf + buf = NULL; + CleanupStack::PushL( result ); + } +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "GetDetailLC-End" ) ) ); +#endif + return result; + } + +HBufC* CRoHandler::ConvertUriToDisplayFormL( const TDesC& aUri ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "ConvertUriToDisplayFormL" ) ) ); +#endif + HBufC8* uri8( HBufC8::NewMaxLC( aUri.Length() ) ); + uri8->Des().Copy( aUri ); + TUriParser8 uriParser8; + User::LeaveIfError( uriParser8.Parse( *uri8 ) ); + CUri16* convertedCUri( UriUtils::ConvertToDisplayFormL( uriParser8 ) ); + CleanupStack::PopAndDestroy( uri8 ); + CleanupStack::PushL( convertedCUri ); + HBufC* convertedUri( convertedCUri->Uri().UriDes().AllocL() ); + CleanupStack::PopAndDestroy( convertedCUri ); +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "ConvertUriToDisplayFormL-End" ) ) ); +#endif + return convertedUri; + } + +HBufC* CRoHandler::GetDescriptionLC() + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "GetDescriptionLC" ) ) ); +#endif + HBufC* buf( NULL ); + +#ifndef RD_MULTIPLE_DRIVE + + TFileName resourceFile( KDriveZ ); + +#else //RD_MULTIPLE_DRIVE + + _LIT( KDriveRoot, "%c:" ); + TInt driveNumber( -1 ); + TChar driveLetter; + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber ); + iFs.DriveToChar( driveNumber, driveLetter ); + + TFileName resourceFile; + resourceFile.Format( KDriveRoot, ( TUint )driveLetter ); + +#endif + + resourceFile.Append( KDC_RESOURCE_FILES_DIR ); + resourceFile.Append( KRoHandlerResourceFile ); + + if ( iMsgType == EOma2RoapTrigger ) + { +#ifdef _DRM_TESTING + TRAP( r, WriteL( resourceFile ) ); +#endif + ReadFromResourceLC( + resourceFile, R_ROHL_INBOX_DESCRIPTION_ROA, buf ); + } + else + { +#ifdef _DRM_TESTING + TRAP( r, WriteL( resourceFile ) ); +#endif + ReadFromResourceLC( resourceFile, R_ROHL_INBOX_DESCRIPTION, buf ); + } + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "GetDescriptionLC-End" ) ) ); +#endif + return buf; + } + +/* +----------------------------------------------------------------------------- + + Method: DoCancel + + Description:Cancels the operation. + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +void CRoHandler::DoCancel + ( + //None. + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "DoCancel" ) ) ); +#endif + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "DoCancel-End" ) ) ); +#endif + } + +/* +----------------------------------------------------------------------------- + + Method: RunL + + Description: Basically all the work is done from/through this method + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +void CRoHandler::RunL + ( + //None. + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "RunL" ) ) ); +#endif + // First checking whether cancel has been called + if ( iStatus == KErrCancel ) + { + iPluginKiller->KillPushPlugin(); + return; + } + + switch( iMsgType ) + { + case EOma1Ro: + { + HandleRightsMessageL(); + break; + } +#ifdef __DRM_OMA2 + case EOma2RoapTrigger: + case EOma2RoapTriggerRoAcquisition: + { + HandleRoapTriggerL(); + break; + } + case EOma2RoapPdu: + { + HandleRoapPduL(); + break; + } +#endif + default: + { + User::Leave( KErrNotSupported ); + } + } +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "RunL-End" ) ) ); +#endif + } +/* +----------------------------------------------------------------------------- + + Method: RunError + + Description: Called by ActiveScheduler in case RunL leaves. + Currently does nothing. + + Return Value: : Currently same as was given as a parameter + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +TInt CRoHandler::RunError + ( + TInt +#ifdef _DRM_TESTING + aError // errorcode +#endif + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "RunError" ) ) ); +#endif + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "RunError-End" ), aError ) ); +#endif + return KErrNone; + } + +/* +----------------------------------------------------------------------------- + + Method: CPushHandlerBase_Reserved1 + + Description: Reserved for future expansion. + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +void CRoHandler::CPushHandlerBase_Reserved1 + ( + //None. + ) + { + _LIT( KNotSupported, "This method is not supported!" ); + User::Panic( KNotSupported, KErrNotSupported ); + } + +/* +----------------------------------------------------------------------------- + + Method: CPushHandlerBase_Reserved2 + + Description: Reserved for future expansion. + + Return Value: None. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +void CRoHandler::CPushHandlerBase_Reserved2 + ( + //None. + ) + { + _LIT( KNotSupported, "This method is not supported!" ); + User::Panic( KNotSupported, KErrNotSupported ); + } + +/* +----------------------------------------------------------------------------- + + Method: PerformChecks + + Description: Checks that message is current type + + Return Value: TInt: KErrNone if ok else KErrCorrupt. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +TInt CRoHandler::PerformChecks + ( + //None. + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "PerformChecks" ) ) ); +#endif + if ( !iPushMsg ) + { + return KErrCorrupt; + } + // Check that body != NULL + TBool bodyPresent( EFalse ); + // fetch message body + bodyPresent = iPushMsg->GetMessageBody( iMessageBodyPtr ); + + // 6 == minimum number of message fields. This is a very "mild" check but + // at least it guarantees that there is no empty body in the message +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "PerformChecks-End" ) ) ); +#endif + if ( ( !bodyPresent ) || ( iMessageBodyPtr.Size() < 6 ) ) + { + return KErrCorrupt; + } + return KErrNone; + } + + +/* +----------------------------------------------------------------------------- + + Method: CheckMessageTypeL + + Description: Checks the message type + + Return Value: EOma1Ro, EOma2RoapPdu or EOma2RoapTrigger + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +TMessageType CRoHandler::CheckMessageTypeL + ( + //None. + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "CheckMessageType" ) ) ); +#endif + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "CheckMessageType-End" ) ) ); +#endif + TPtrC8 messageBodyPtr( iMessageBodyPtr ); + TMessageType recognizedMessageType( EOma1Ro ); + if ( iMessageBodyPtr.FindF( KWbxmlRoapTriggerElement() ) != KErrNotFound ) + { + iParsedXmlTrigger = iWbxmlTriggerParser->ParseL( iMessageBodyPtr ); + messageBodyPtr.Set( *iParsedXmlTrigger ); + } + if ( messageBodyPtr.FindF( KRoapTriggerElement() ) != KErrNotFound ) + { + if ( messageBodyPtr.FindF( KRoapTriggerRoAcquisition() ) != KErrNotFound ) + { + recognizedMessageType = EOma2RoapTriggerRoAcquisition; + } + else if ( messageBodyPtr.FindF( KRoapTriggerMeteringReport() ) != KErrNotFound ) + { + recognizedMessageType = EOma2RoapTriggerMetering; + } + else + { + recognizedMessageType = EOma2RoapTrigger; + } + + } + if ( iMessageBodyPtr.FindF( KRoapRoPduElement() ) != KErrNotFound ) + { + recognizedMessageType = EOma2RoapPdu; + } + delete iParsedXmlTrigger; + iParsedXmlTrigger = NULL; + return recognizedMessageType; + } + + +/* +----------------------------------------------------------------------------- + + Method: SetEntryL + + Description: Set up current message entry. + + Note: It can be useful to remember the original entry id for + error handling. + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +void CRoHandler::SetEntryL + ( + TMsvId aEntryId //an entry in the Message Server index + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "SetEntryL" ) ) ); +#endif + + // Get the server entry from our session + CMsvEntry* entry( iSession->GetEntryL( aEntryId ) ); + CleanupStack::PushL( entry ); + + // Check if our mtm is different from the mtm set to our entry + if ( !iMtm || entry->Entry().iMtm != ( iMtm->Entry() ).Entry().iMtm ) + { + // If so, we delete the old... + delete iMtm; + iMtm = NULL; + // ...and get a new one from the MtmRegistry + iMtm = iMtmReg->NewMtmL( entry->Entry().iMtm ); + } + // Set our entry as current. + iMtm->SetCurrentEntryL( entry ); + + CleanupStack::Pop( entry ); + entry = NULL; + +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "SetEntryL-End" ) ) ); +#endif + } + +/* +----------------------------------------------------------------------------- + + Method: MoveMessageEntryL + + Description: Moves an entry to another parent. + + Return values: TMsvId of the moved message + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +TMsvId CRoHandler::MoveMessageEntryL + ( + TMsvId aTarget //an entry in the Message Server index + ) + { +#ifdef _DRM_TESTING + TRAPD( r, WriteL( _L8( "MoveMessageEntryL" ) ) ); +#endif + TMsvEntry msvEntry( ( iMtm->Entry() ).Entry() ); + TMsvId id = msvEntry.Id(); + + if ( msvEntry.Parent() != aTarget ) + { + TMsvSelectionOrdering sort; + sort.SetShowInvisibleEntries( ETrue ); // we want to handle also the invisible entries + // Take a handle to the parent entry + CMsvEntry* parentEntry( + CMsvEntry::NewL( iMtm->Session(), msvEntry.Parent(), sort ) ); + CleanupStack::PushL( parentEntry ); + + // Move original from the parent to the new location + CMsvOperationActiveSchedulerWait* wait( + CMsvOperationActiveSchedulerWait::NewLC() ); + CMsvOperation* op( + parentEntry->MoveL( msvEntry.Id(), aTarget, wait->iStatus ) ); + CleanupStack::PushL( op ); + wait->Start(); + + TMsvLocalOperationProgress prog = McliUtils::GetLocalProgressL( *op ); + User::LeaveIfError( prog.iError ); + id = prog.iId; // id of the moved entry + CleanupStack::PopAndDestroy( op ); + CleanupStack::PopAndDestroy( wait ); + CleanupStack::PopAndDestroy( parentEntry ); + } +#ifdef _DRM_TESTING + TRAP( r, WriteL( _L8( "MoveMessageEntryL-End" ) ) ); +#endif + return id; + } + +TBool CRoHandler::DoRoapL( const TDesC8& aTrigger ) + { + TBool r( EFalse ); + LOG( _L8( "CRoHandler::DoRoapL ->" ) ); + LOGHEX( aTrigger.Ptr(), aTrigger.Length() ); + CRoapSyncWrapper *roap( CRoapSyncWrapper::NewL() ); + CleanupStack::PushL( roap ); + r = roap->HandleTriggerSilentlyL( aTrigger ); + CleanupStack::PopAndDestroy( roap ); + LOG( _L8( "CRoHandler::DoRoapL <-" ) ); + return r; + } + + +void CRoHandler::HandleMeteringTriggerSilentlyL() + { + LOG( _L8( "CRoHandler::HandleMeteringTriggerSilentlyL ->" ) ); + LOGHEX( iMessageBodyPtr.Ptr(), iMessageBodyPtr.Length() ); + + if ( iMeteringSupported ) + { + LOG( _L8( "Handling" ) ); + CRoHandlerDMgrWrapper* dMgrWrapper( CRoHandlerDMgrWrapper::NewL() ); + CleanupStack::PushL( dMgrWrapper ); + dMgrWrapper->HandleRoapTriggerL( iMessageBodyPtr ); + CleanupStack::PopAndDestroy( dMgrWrapper ); + LOG( _L8( "Handled" ) ); + } + else + { + LOG( _L8( "Metering trigger not supported --> dropping it" ) ); + } + LOG( _L8( "CRoHandler::HandleMeteringTriggerSilentlyL <-" ) ); + } +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +/* + ----------------------------------------------------------------------------- + +Method: ImplementationGroupProxy + + Description: + + Return Value: TImplementationProxy*: Implementation table to the + ECOM framework + + Status: Proposal + +----------------------------------------------------------------------------- +*/ + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy + ( + TInt& aTableCount + ) + { + aTableCount = + sizeof( ImplementationTable ) / sizeof( TImplementationProxy ); + return ImplementationTable; + } + + +// End of File