--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/loadgen/src/loadgen_messages.cpp Tue Feb 02 00:17:27 2010 +0200
@@ -0,0 +1,978 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+
+// INCLUDE FILES
+#include "loadgen_messages.h"
+#include "loadgen_model.h"
+#include "loadgen.hrh"
+#include <loadgen.rsg>
+#include <e32math.h>
+
+_LIT(KThreadName, "Messages %d");
+_LIT(KMessageSMS, "A test message from LoadGen S60 RnD tool. ");
+_LIT( KMessageSMSType, "SMS" );
+_LIT( KMessageMMSType, "MMS" );
+
+const TInt KTestMessageLength = 42;
+const TInt KDefaultStart = 50;
+const TInt KDefaultPeriod = 5000000;
+
+// ===================================== MEMBER FUNCTIONS =====================================
+
+CMessages* CMessages::NewL( TMessageAttributes& aAttributes, TInt aReferenceNumber )
+ {
+ CMessages* self = new(ELeave) CMessages( aAttributes, aReferenceNumber );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------------------------
+
+CMessages::~CMessages()
+ {
+ Close();
+ }
+
+// --------------------------------------------------------------------------------------------
+
+CMessages::CMessages( TMessageAttributes& aAttributes,
+ TInt aReferenceNumber )
+ : iAttributes( aAttributes )
+ {
+ iAttributes.iId = aReferenceNumber;
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessages::ConstructL()
+ {
+ CLoadBase::ConstructL();
+
+ iType = ELoadGenCmdNewLoadMessages;
+
+ TBuf<64> threadName;
+ threadName.Format( KThreadName, iAttributes.iId );
+
+ // create a thread
+ User::LeaveIfError( iThread.Create( threadName,
+ ThreadFunction,
+ KDefaultStackSize * 2,
+ KMinHeapSize,
+ 1024 * KMinHeapSize,
+ (TAny*) &iAttributes ) );
+
+ // set priority of the thread
+ SetPriority();
+ }
+
+// --------------------------------------------------------------------------------------------
+
+TInt CMessages::ThreadFunction(TAny* aThreadArg)
+ {
+ CTrapCleanup* pC = CTrapCleanup::New();
+ CActiveScheduler* pS = new CActiveScheduler;
+ CActiveScheduler::Install( pS );
+
+ // start generating load, pass pointer to arguments
+ GenerateLoad( *( ( TMessageAttributes* ) aThreadArg ) );
+
+ delete pS;
+ delete pC;
+
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessages::GenerateLoad( TMessageAttributes& aAttributes )
+ {
+ CMessageManager* messagesManager = NULL;
+ TRAPD( err, messagesManager = CMessageManager::NewL( aAttributes ) );
+
+ if ( err == KErrNone )
+ {
+ CActiveScheduler::Start();
+ }
+ delete messagesManager;
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessages::Resume()
+ {
+ CLoadBase::Resume();
+
+ iThread.Resume();
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessages::Suspend()
+ {
+ CLoadBase::Suspend();
+
+ iThread.Suspend();
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessages::SetPriority()
+ {
+ CLoadBase::SetPriority();
+
+ iThread.SetPriority( CLoadGenModel::SettingItemToThreadPriority( iAttributes.iPriority ) );
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessages::Close()
+ {
+ CLoadBase::Close();
+
+ if ( iThread.ExitReason() == 0 ) // check if the thread is still alive
+ {
+ // signal the thread that it needs to close
+ iThread.RequestComplete( iAttributes.iDeathStatus, KErrCancel );
+
+ // wait the thread to die
+ TRequestStatus waiter;
+ iThread.Logon( waiter );
+ User::WaitForRequest( waiter );
+ iThread.Close();
+ }
+ }
+
+// --------------------------------------------------------------------------------------------
+
+TPtrC CMessages::Description()
+ {
+ TBuf<256> buf;
+ TBuf<16> prioBuf;
+ TBuf<3> typeBuf;
+ CLoadGenModel::SettingItemToThreadDescription( iAttributes.iPriority, prioBuf );
+ if ( iAttributes.iMessageType == EMessageTypeSMS )
+ {
+ typeBuf.Copy( KMessageSMSType );
+ }
+ else
+ {
+ typeBuf.Copy( KMessageMMSType );
+ }
+ _LIT(KMessagesEntry, "[%d] Type=%S prio=%S dest=%S idle=%dms random=%d%%");
+ buf.Format( KMessagesEntry, iAttributes.iId, &typeBuf, &prioBuf, &iAttributes.iDestination,
+ iAttributes.iIdle, iAttributes.iRandomVariance );
+
+ return TPtrC( buf );
+ }
+// --------------------------------------------------------------------------------------------
+
+CMessageManager* CMessageManager::NewL( TMessageAttributes& aAttributes )
+ {
+ CMessageManager* self = new(ELeave) CMessageManager( aAttributes );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------------------------
+CMessageManager::CMessageManager( TMessageAttributes& aAttributes ) :
+ CActive( EPriorityStandard ), iAttributes( aAttributes ), iState( EStateIdle )
+ {
+ iMessageCounter = 0;
+ }
+
+// --------------------------------------------------------------------------------------------
+
+CMessageManager::~CMessageManager()
+ {
+ Cancel();
+ delete iMessage;
+ if ( iPeriodicTimer )
+ {
+ iPeriodicTimer->Cancel();
+ delete iPeriodicTimer;
+ }
+ if ( iAttributes.iMessageType == EMessageTypeSMS && iSmsHandler )
+ {
+ delete iSmsHandler;
+ }
+ else if ( iMmsHandler )
+ {
+ delete iMmsHandler;
+ }
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessageManager::ConstructL()
+ {
+ CActiveScheduler::Add( this );
+
+ // set the status as pending
+ iStatus = KRequestPending;
+ SetActive();
+
+ // set the death status pointer point to the request status of this ao
+ iAttributes.iDeathStatus = &iStatus;
+ if ( iAttributes.iAmount > 0 )
+ {
+ iState = EStateSend;
+ }
+ iMessage = HBufC::NewL( iAttributes.iLength );
+ CreateMessage();
+
+ // init SMS sender ao
+ if ( iAttributes.iMessageType == EMessageTypeSMS )
+ {
+ iSmsHandler = CSmsHandler::NewL( *this );
+ }
+ else
+ {
+ iMmsHandler = CMmsHandler::NewL( *this );
+ }
+ // start timer
+ iPeriodicTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+ iPeriodicTimer->Start( KDefaultStart, KDefaultPeriod,
+ TCallBack( PeriodicTimerCallBack, this ) );
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessageManager::RunL()
+ {
+ // request status has completed by the main thread meaning that we need to stop now
+ CActiveScheduler::Stop();
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessageManager::DoCancel()
+ {
+ }
+
+// --------------------------------------------------------------------------------------------
+
+TInt CMessageManager::PeriodicTimerCallBack(TAny* aAny)
+ {
+ CMessageManager* self = static_cast<CMessageManager*>( aAny );
+
+ self->iPeriodicTimer->Cancel();
+ self->HandleMessageSending();
+
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessageManager::CreateMessage()
+ {
+ // Message body
+ TBuf<KTestMessageLength> mToYou( KMessageSMS );
+ TPtr ptr = iMessage->Des();
+
+ // Take as many characters as user requested to create the message
+ for ( TInt j = 0; j < iAttributes.iLength; j++ )
+ {
+ for ( TInt k = 0; k < KTestMessageLength; k++ )
+ {
+ ptr.Append( mToYou[k] );
+ j++;
+ if ( j == iAttributes.iLength )
+ {
+ break;
+ }
+ }
+ }
+ }
+
+
+// --------------------------------------------------------------------------------------------
+
+void CMessageManager::HandleMessageSending()
+ {
+ if ( iState == EStateSend && iAttributes.iDestination.Length() <= KTelephoneNumberMaxLength )
+ {
+ TBool err( KErrNone );
+
+ // make a new call
+ iState = EStateSending;
+
+ iMessageCounter++;
+ if ( iAttributes.iMessageType == EMessageTypeSMS )
+ {
+ TRAP( err, iSmsHandler->SendL( iAttributes.iDestination, *iMessage ) );
+ if ( !err )
+ {
+ iState = EStateIdle;
+ iPeriodicTimer->Start( CLoadGenModel::MilliSecondsToMicroSeconds( iAttributes.iIdle,
+ iAttributes.iRandomVariance ), KDefaultPeriod,
+ TCallBack( PeriodicTimerCallBack, this ) );
+
+ }
+ }
+ else
+ {
+ TRAP( err, iMmsHandler->SendL( iAttributes.iDestination, *iMessage ) );
+ if ( err )
+ {
+ HandleStatus( EStateIdle );
+ }
+ }
+ }
+ else
+ {
+ iState = EStateIdle;
+ iPeriodicTimer->Start( CLoadGenModel::MilliSecondsToMicroSeconds( iAttributes.iIdle,
+ iAttributes.iRandomVariance ), KDefaultPeriod,
+ TCallBack( PeriodicTimerCallBack, this ) );
+
+ }
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CMessageManager::HandleStatus( TInt /*aErr*/ )
+ {
+ // timer after wait
+ if ( iMessageCounter < iAttributes.iAmount )
+ {
+ iState = EStateSend;
+ iPeriodicTimer->Cancel();
+ iPeriodicTimer->Start( CLoadGenModel::MilliSecondsToMicroSeconds( iAttributes.iIdle,
+ iAttributes.iRandomVariance ), KDefaultPeriod,
+ TCallBack( PeriodicTimerCallBack, this ) );
+ }
+ }
+
+// --------------------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------
+// INCLUDE FILES
+#include <eikenv.h>
+#include <coemain.h>
+#include <e32std.h>
+#include <msvids.h>
+#include <msvstd.h>
+#include <smsclnt.h>
+#include <smut.h>
+#include <mtclreg.h>
+#include <txtrich.h>
+#include <smscmds.h>
+#include <mtmuibas.h>
+#include <mtmdef.h>
+#include <stringloader.h>
+#include "smutset.h"
+#include "smuthdr.h"
+
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+// -----------------------------------------------------------------------------
+// CSmsHandler::CSmsHandler()
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CSmsHandler::CSmsHandler( CMessageManager& aManager )
+ : CActive( CActive::EPriorityStandard ), iManager( aManager )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSmsHandler::ConstructL()
+ {
+ // Session to message server is opened asynchronously.
+ iSession = CMsvSession::OpenAsyncL( *this );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::NewL()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CSmsHandler* CSmsHandler::NewL( CMessageManager& aManager )
+ {
+ CSmsHandler* self = NewLC( aManager );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::NewLC()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CSmsHandler* CSmsHandler::NewLC( CMessageManager& aManager )
+ {
+ CSmsHandler* self = new ( ELeave ) CSmsHandler( aManager );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// ----------------------------------------------------------
+// CSmsHandler::~CSmsHandler()
+// Destructor.
+// ----------------------------------------------------------
+//
+CSmsHandler::~CSmsHandler()
+ {
+ Cancel(); // cancel any outstanding request
+
+ delete iOperation;
+ delete iMtmUiRegistry;
+ delete iSmsMtm;
+ delete iMtmRegistry;
+ delete iSession; // session must be deleted last
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::DoCancel()
+// Cancels a request.
+// -----------------------------------------------------------------------------
+//
+void CSmsHandler::DoCancel()
+ {
+ if ( iOperation )
+ {
+ iOperation->Cancel();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::RunL()
+// Handles request completion events.
+// -----------------------------------------------------------------------------
+//
+void CSmsHandler::RunL()
+ {
+ User::LeaveIfError( iStatus != KErrNone );
+
+ // Determine the current operations progress.
+ // ProgressL returns an 8 bit descriptor.
+ TBufC8<KMsvProgressBufferLength> progress( iOperation->ProgressL() );
+ _LIT8( KCompare, "KErrNone" );
+ User::LeaveIfError( !progress.Compare( KCompare ) );
+
+ // The pointer to the current CMsvOperation object is no longer needed.
+ delete iOperation;
+ iOperation = NULL;
+
+ // Determine which request has finished.
+ switch ( iState )
+ {
+ case EWaitingForMoving:
+ // Once a message is moved to Outbox it is scheduled for sending.
+ ScheduleL();
+ break;
+
+ case EWaitingForScheduling:
+ {
+ TMsvEntry entry( iSmsMtm->Entry().Entry() );
+ TInt state( entry.SendingState() );
+
+ if ( state == KMsvSendStateWaiting || state == KMsvSendStateScheduled)
+ {
+ // notify the observer that status has changed
+ iManager.HandleStatus( iStatus.Int() );
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::HandleSessionEventL()
+// Handles notifications of events from the Message Server.
+// -----------------------------------------------------------------------------
+//
+void CSmsHandler::HandleSessionEventL( TMsvSessionEvent aEvent,
+ TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
+ {
+ switch ( aEvent )
+ {
+ // Session to server established
+ case EMsvServerReady:
+ {
+ TMsvId serviceId( KUidMsgTypeSMS.iUid ); // SMS service id
+
+ // Determine if the event was succesful.
+ // ServiceProgress inserts TBuf8 value in progress.
+ TBuf8<KBfrLength> progress;
+ iSession->ServiceProgress( serviceId, progress );
+ _LIT8( KCompare, "KErrNone" );
+
+ if ( progress.Compare( KCompare ) )
+ {
+ // Check that MtmRegistry has not already been accessed.
+ if ( !iMtmRegistry )
+ {
+ AccessMtmL();
+ }
+ }
+ break;
+ }
+
+ // All other events are ignored.
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::AccessMtmL()
+// Access the MTM Registry and create a SMS specific Client MTM instance.
+// -----------------------------------------------------------------------------
+//
+void CSmsHandler::AccessMtmL()
+ {
+ // Create an MTM Registry object.
+ iMtmRegistry = CClientMtmRegistry::NewL( *iSession );
+
+ // Create an SMS Client MTM object.
+ iSmsMtm = STATIC_CAST( CSmsClientMtm*, iMtmRegistry->NewMtmL( KUidMsgTypeSMS ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::SendL()
+// Starts the process of creating and sending an SMS message.
+// -----------------------------------------------------------------------------
+//
+TBool CSmsHandler::SendL( const TDesC& aRecipientNumber,
+ const TDesC& aMessageText )
+ {
+ iRecipientNumber = aRecipientNumber;
+ iMessageText = aMessageText;
+
+ if ( CreateMsgL() )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::CreateMsgL()
+// Create an SMS message.
+// -----------------------------------------------------------------------------
+//
+TBool CSmsHandler::CreateMsgL()
+ {
+ // Current entry is the Draft folder.
+ iSmsMtm->SwitchCurrentEntryL( KMsvDraftEntryId );
+
+ // Create a new SMS message entry as a child of the current context.
+ iSmsMtm->CreateMessageL( KUidMsgTypeSMS.iUid );
+
+ CMsvEntry& serverEntry = iSmsMtm->Entry();
+ TMsvEntry entry( serverEntry.Entry() );
+
+ CRichText& body = iSmsMtm->Body(); // the body of the message
+ body.Reset();
+ // Insert the message text gotten as input from user.
+ body.InsertL( 0, iMessageText );
+
+ // Message will be sent immediately.
+ entry.SetSendingState( KMsvSendStateWaiting );
+
+ entry.iDate.UniversalTime(); // insert current time //Solution for HomeTime()
+
+ // Set the SMS message settings for the message.
+ CSmsHeader& header = iSmsMtm->SmsHeader();
+ CSmsSettings* settings = CSmsSettings::NewL();
+ CleanupStack::PushL( settings );
+
+ settings->CopyL( iSmsMtm->ServiceSettings() ); // restore settings
+ settings->SetDelivery( ESmsDeliveryImmediately ); // to be delivered immediately
+ settings->SetDeliveryReport(ETrue);
+ header.SetSmsSettingsL( *settings ); // new settings
+
+ // Let's check if there is a service center address.
+ if ( header.Message().ServiceCenterAddress().Length() == 0 )
+ {
+ // No, there isn't. We assume there is at least one service center
+ // number set and use the default service center number.
+ CSmsSettings* serviceSettings = &( iSmsMtm->ServiceSettings() );
+
+ // Check if number of service center addresses in the list is null.
+
+ //Changed for 3rd Edition specially
+ if ( !serviceSettings->ServiceCenterCount() )
+ {
+ CleanupStack::PopAndDestroy( settings );
+ return EFalse; // quit creating the message
+ }
+
+ else
+ {
+ //Changed for 3rd Edition specially
+ CSmsNumber* smsCenter= CSmsNumber::NewL();
+ CleanupStack::PushL(smsCenter);
+ smsCenter->SetAddressL((serviceSettings->GetServiceCenter(
+ serviceSettings->DefaultServiceCenter())).Address());
+ header.Message().SetServiceCenterAddressL( smsCenter->Address() );
+ CleanupStack::PopAndDestroy(smsCenter);
+ }
+ }
+
+ CleanupStack::PopAndDestroy( settings );
+
+ // Recipient number is displayed also as the recipient alias.
+ entry.iDetails.Set( iRecipientNumber );
+ // Add addressee.
+ iSmsMtm->AddAddresseeL( iRecipientNumber, entry.iDetails );
+
+ // Validate message.
+ if ( !ValidateL() )
+ {
+ return EFalse;
+ }
+
+ entry.SetVisible( ETrue ); // set message as visible
+ entry.SetInPreparation( EFalse ); // set together with the visibility flag
+ serverEntry.ChangeL( entry ); // commit changes
+ iSmsMtm->SaveMessageL(); // save message
+
+ TMsvSelectionOrdering selection;
+ CMsvEntry* parentEntry = CMsvEntry::NewL( iSmsMtm->Session(), KMsvDraftEntryId, selection );
+ CleanupStack::PushL( parentEntry );
+
+ // Move message to Outbox.
+ iOperation =parentEntry->MoveL( entry.Id(), KMsvGlobalOutBoxIndexEntryId, iStatus );
+
+ CleanupStack::PopAndDestroy( parentEntry );
+
+ iState = EWaitingForMoving;
+ SetActive();
+
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::ValidateL()
+// Validate an SMS message.
+// -----------------------------------------------------------------------------
+//
+TBool CSmsHandler::ValidateL()
+ {
+ // Empty part list to hold the result.
+ TMsvPartList result( KMsvMessagePartNone );
+
+ // Validate message body.
+ result = iSmsMtm->ValidateMessage( KMsvMessagePartBody );
+
+ if ( result != KMsvMessagePartNone )
+ {
+ return EFalse;
+ }
+
+ // Validate recipient.
+ result = iSmsMtm->ValidateMessage( KMsvMessagePartRecipient );
+
+ if ( result != KMsvMessagePartNone )
+ {
+ return EFalse;
+ }
+
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::ScheduleL()
+// Schedule an SMS message for sending.
+// -----------------------------------------------------------------------------
+//
+void CSmsHandler::ScheduleL()
+ {
+ CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
+ CleanupStack::PushL( selection );
+ selection->AppendL( iSmsMtm->Entry().EntryId() ); // add message to selection
+
+ // Add entry to task scheduler.
+ TBuf8<1> dummyParams; // dummy parameters needed for InvokeAsyncFunctionL
+ iOperation = iSmsMtm->InvokeAsyncFunctionL( ESmsMtmCommandScheduleCopy,
+ *selection, dummyParams, iStatus );
+
+ CleanupStack::PopAndDestroy( selection );
+
+ iState = EWaitingForScheduling;
+ SetActive();
+ }
+
+// --------------------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------
+
+
+
+// INCLUDE FILES
+#include <mtclreg.h> // for CClientMtmRegistry
+#include <msvids.h> // for Message type IDs
+#include <mmsclient.h> // for CMmsClientMtm
+#include <AknQueryDialog.h> // for CAknTextQueryDialog
+#include <f32file.h>
+#include <coeutils.h> // Check the file exist
+
+#include <CMsvMimeHeaders.h> //Attachemt mimeheader
+#include <MMsvAttachmentManager.h> //Attachment manager
+
+// -----------------------------------------------------------------------------
+// CMmsHandler::CSmsHandler()
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CMmsHandler::CMmsHandler( CMessageManager& aManager ) : iManager( aManager )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CMmsHandler::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMmsHandler::ConstructL()
+ {
+ // Session to message server is opened asynchronously.
+ iSession = CMsvSession::OpenAsyncL( *this );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMmsHandler::NewL()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMmsHandler* CMmsHandler::NewL( CMessageManager& aManager )
+ {
+ CMmsHandler* self = NewLC( aManager );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMmsHandler::NewLC()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMmsHandler* CMmsHandler::NewLC( CMessageManager& aManager )
+ {
+ CMmsHandler* self = new ( ELeave ) CMmsHandler( aManager );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// ----------------------------------------------------------
+// CMmsHandler::~CSmsHandler()
+// Destructor.
+// ----------------------------------------------------------
+//
+CMmsHandler::~CMmsHandler()
+ {
+ delete iMmsMtm;
+ delete iMtmReg;
+ delete iSession; // session must be deleted last (and constructed first)
+ }
+
+/*
+-----------------------------------------------------------------------------
+ CMmsHandler::CompleteConstructL()
+ Creates client MTM registry when session is ready for use.
+ This completes model construction and is called after 'server
+ ready' event is received after async opening of CMsvSession.
+-----------------------------------------------------------------------------
+*/
+void CMmsHandler::CompleteConstructL()
+ {
+ // We get a MtmClientRegistry from our session
+ // this registry is used to instantiate new mtms.
+ iMtmReg = CClientMtmRegistry::NewL( *iSession );
+ iMmsMtm = (CMmsClientMtm*)iMtmReg->NewMtmL( KUidMsgTypeMultimedia );
+ }
+
+/*
+-----------------------------------------------------------------------------
+ CMmsHandler::HandleSessionEventL()
+
+ Receives session events from observer and calls event handling functions.
+ Note that if additional session event handlers are defined
+ in the session, they are called before this function (as this is the
+ main session observer).
+ The type of event is indicated by the value of aEvent. The
+ interpretation of the TAny arguments depends on this type.
+-----------------------------------------------------------------------------
+*/
+void CMmsHandler::HandleSessionEventL(TMsvSessionEvent aEvent,
+ TAny* /*aArg1*/,
+ TAny* /*aArg2*/,
+ TAny* /*aArg3*/)
+ {
+ switch ( aEvent )
+ {
+ // This event tells us that the session has been opened
+ case EMsvServerReady:
+ {
+ CompleteConstructL(); // Construct the mtm registry & MMS mtm
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSmsHandler::SendL()
+// Starts the process of creating and sending an SMS message.
+// -----------------------------------------------------------------------------
+//
+TBool CMmsHandler::SendL( const TDesC& aRecipientNumber,
+ const TDesC& aMessageText )
+ {
+ TInt result( EFalse );
+
+ iRecipientNumber = aRecipientNumber;
+ iMessageText = aMessageText;
+
+ if ( CreateMsgL() )
+ {
+ if ( SendMessageL() )
+ {
+ result = ETrue;
+ }
+ }
+
+ return result;
+ }
+
+/*
+-----------------------------------------------------------------------------
+ CMmsHandler::CreateMsgL()
+ Creates a new message server entry and set up default values.
+ In case the attachment file does not found method return EFalse
+ otherwise ETrue.
+ There are differenses how to add attachment file between 2nd and 3rd edition.
+-----------------------------------------------------------------------------
+*/
+TBool CMmsHandler::CreateMsgL()
+ {
+
+ // - 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 = CMsvEntry::NewL( *iSession,
+ KMsvGlobalOutBoxIndexEntryId,
+ TMsvSelectionOrdering() );
+ CleanupStack::PushL( entry );
+
+ // Set context to the parent folder (Outbox)
+ iMmsMtm->SwitchCurrentEntryL( entry->EntryId() );
+
+ // Create new message in the parent folder (Outbox) and set it as the current context.
+ iMmsMtm->CreateMessageL( iMmsMtm->DefaultServiceL() );
+
+ CleanupStack::PopAndDestroy( entry );
+
+ // Setting recipients
+ // use this to add the "To" recipients.
+ iMmsMtm->AddAddresseeL( iRecipientNumber );
+
+ //Setting message subject
+ _LIT(KMessageSubject, "MMS Message");
+ iMmsMtm->SetSubjectL( KMessageSubject );
+
+ // add message text
+ SetMessageBodyL();
+
+ TMsvEntry ent = iMmsMtm->Entry().Entry();
+ // Set InPreparation to false
+ ent.SetInPreparation( EFalse );
+ ent.SetVisible( ETrue ); // mark as visible, after this the message can be seen in Outbox and, after sending, in Sent folder.
+
+ iMmsMtm->Entry().ChangeL( ent ); // Commit changes
+
+ //Save the changes
+ iMmsMtm->SaveMessageL();
+
+ return ETrue;
+ }
+
+//---------------------------------------------------------------------------------
+void CMmsHandler::SetMessageBodyL()
+ {
+ _LIT (KFilenameText, "msg.txt");
+ CMsvStore* store = iMmsMtm->Entry().EditStoreL();
+ CleanupStack::PushL( store );
+
+ TMsvAttachmentId attachmentId = KMsvNullIndexEntryId;
+
+ iMmsMtm->CreateTextAttachmentL ( *store,
+ attachmentId,
+ iMessageText,
+ KFilenameText );
+
+ store->CommitL();
+
+ CleanupStack::PopAndDestroy( store );
+ }
+
+/*
+-----------------------------------------------------------------------------
+ CMmsHandler::SendMessageL()
+ Sends the message.
+ Return values: ETrue or EFalse
+-----------------------------------------------------------------------------
+*/
+TBool CMmsHandler::SendMessageL()
+ {
+
+ // Start sending the message via the Server MTM to the MMS server
+ CMsvOperationWait* wait = CMsvOperationWait::NewLC();
+ wait->iStatus = KRequestPending;
+ CMsvOperation* op = NULL;
+ op = iMmsMtm->SendL( wait->iStatus );
+ wait->Start();
+ CleanupStack::PushL( op );
+ CActiveScheduler::Start();
+
+ // The following is to ignore the completion of other active objects. It is not
+ // needed if the app has a command absorbing control.
+ while( wait->iStatus == KRequestPending )
+ {
+ CActiveScheduler::Start();
+ }
+
+ iManager.HandleStatus( wait->iStatus.Int() );
+ CleanupStack::PopAndDestroy(2); // op, wait
+
+ return ETrue;
+ }
+// End of File