diff -r b3cee849fa46 -r fad26422216a loadgen/src/loadgen_messages.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loadgen/src/loadgen_messages.cpp Wed Sep 01 12:30:35 2010 +0100 @@ -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 +#include + +_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( aAny ); + + self->iPeriodicTimer->Cancel(); + self->HandleMessageSending(); + + return KErrNone; + } + +// -------------------------------------------------------------------------------------------- + +void CMessageManager::CreateMessage() + { + // Message body + TBuf 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 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 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 // for CClientMtmRegistry +#include // for Message type IDs +#include // for CMmsClientMtm +#include // for CAknTextQueryDialog +#include +#include // Check the file exist + +#include //Attachemt mimeheader +#include //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