--- /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 <txtrich.h> // for CRichText
+#include <drmmessageparser.h> // for CDrmMessageParser
+#include <drmrights.h> // for CDRMRights
+#include <ecom/implementationproxy.h> // for TImplementationProxy
+#include <push/cpushhandlerbase.h> // for CPushHandlerBase
+#include <push/pluginkiller.h> // for CPluginKiller
+#include <push/pushmessage.h> // for CPushMessage
+#include <roapeng.h> // for CRoapEng
+#include <roapengbase.h>
+#include <roapobserver.h>
+#include <centralrepository.h> // link against centralrepository.lib
+#include <msvuids.h>
+#include <msvids.h>
+#include <downloadmgrclient.h>
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <driveinfo.h>
+#endif
+
+#include <uri16.h> // TUriParser16
+#include <data_caging_path_literals.hrh> // KDC_MTM_RESOURCE_DIR
+#include <uriutils.h> // UriUtils and so on
+#include <pushmtmui.rsg> // for R_PUSHMISC_UNK_SENDER
+#include <rohandler.rsg> // for R_QTN_DRM_MGR_INB_TITLE
+#include <sysutil.h> // 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<KBooleanStringMaxSize> 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: <errorcode>: 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