loadgen/engine/src/loadgen_messages.cpp
branchRCL_3
changeset 22 fad26422216a
parent 21 b3cee849fa46
child 23 f8280f3bfeb7
equal deleted inserted replaced
21:b3cee849fa46 22:fad26422216a
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "loadgen_messages.h"
       
    21 #include "loadgen_utils.h"
       
    22 #include "loadgen.hrh"
       
    23 #include <loadgen.rsg>
       
    24 #include <e32math.h>
       
    25 
       
    26 _LIT(KThreadName, "Messages %d");
       
    27 _LIT(KMessageSMS, "A test message from LoadGen S60 RnD tool. ");
       
    28 _LIT( KMessageSMSType, "SMS" );
       
    29 _LIT( KMessageMMSType, "MMS" );
       
    30 
       
    31 const TInt KTestMessageLength = 42;
       
    32 const TInt KDefaultStart = 50;
       
    33 const TInt KDefaultPeriod = 5000000;
       
    34 
       
    35 // ===================================== MEMBER FUNCTIONS =====================================
       
    36 
       
    37 CMessages* CMessages::NewL( TMessageAttributes& aAttributes, TInt aReferenceNumber )
       
    38     {
       
    39     CMessages* self = new(ELeave) CMessages( aAttributes, aReferenceNumber );
       
    40     CleanupStack::PushL( self );
       
    41     self->ConstructL();
       
    42     CleanupStack::Pop( self );
       
    43     return self;    
       
    44     }
       
    45 
       
    46 // --------------------------------------------------------------------------------------------
       
    47 
       
    48 CMessages::~CMessages()
       
    49     {
       
    50     Close();
       
    51     }
       
    52 
       
    53 // --------------------------------------------------------------------------------------------
       
    54 
       
    55 CMessages::CMessages( TMessageAttributes& aAttributes, 
       
    56                        TInt aReferenceNumber ) 
       
    57                             : iAttributes( aAttributes )
       
    58     {
       
    59     iAttributes.iId = aReferenceNumber;
       
    60     }
       
    61 
       
    62 // --------------------------------------------------------------------------------------------
       
    63 
       
    64 void CMessages::ConstructL()
       
    65     {
       
    66     CLoadBase::ConstructL();
       
    67     
       
    68     iType = ELoadGenCmdNewLoadMessages;
       
    69     
       
    70     TBuf<64> threadName;
       
    71     threadName.Format( KThreadName, iAttributes.iId );
       
    72     
       
    73     // create a thread
       
    74     User::LeaveIfError( iThread.Create( threadName, 
       
    75                                         ThreadFunction, 
       
    76                                         KDefaultStackSize * 2, 
       
    77                                         KMinHeapSize, 
       
    78                                         1024 * KMinHeapSize, 
       
    79                                         (TAny*) &iAttributes ) );
       
    80     
       
    81     // set priority of the thread
       
    82     SetPriority();
       
    83     }
       
    84 
       
    85 // --------------------------------------------------------------------------------------------
       
    86 
       
    87 TInt CMessages::ThreadFunction(TAny* aThreadArg)
       
    88     {
       
    89     CTrapCleanup* pC = CTrapCleanup::New();
       
    90     CActiveScheduler* pS = new CActiveScheduler;
       
    91     CActiveScheduler::Install( pS );
       
    92 
       
    93     // start generating load, pass pointer to arguments
       
    94     GenerateLoad( *( ( TMessageAttributes* ) aThreadArg ) );
       
    95 
       
    96     delete pS;
       
    97     delete pC;
       
    98     
       
    99     return KErrNone;
       
   100     }
       
   101 
       
   102 // --------------------------------------------------------------------------------------------
       
   103 
       
   104 void CMessages::GenerateLoad( TMessageAttributes& aAttributes )
       
   105     {
       
   106     CMessageManager* messagesManager = NULL;
       
   107     TRAPD( err, messagesManager = CMessageManager::NewL( aAttributes ) );
       
   108 
       
   109     if ( err == KErrNone )
       
   110         {
       
   111         CActiveScheduler::Start();
       
   112         }
       
   113     delete messagesManager;
       
   114     }
       
   115 
       
   116 // --------------------------------------------------------------------------------------------
       
   117 
       
   118 void CMessages::Resume()
       
   119     {
       
   120     CLoadBase::Resume();
       
   121     
       
   122     iThread.Resume();
       
   123     }
       
   124 
       
   125 // --------------------------------------------------------------------------------------------
       
   126 
       
   127 void CMessages::Suspend()
       
   128     {
       
   129     CLoadBase::Suspend();
       
   130     
       
   131     iThread.Suspend();
       
   132     }
       
   133 
       
   134 // --------------------------------------------------------------------------------------------
       
   135 
       
   136 void CMessages::SetPriority()
       
   137     {
       
   138     CLoadBase::SetPriority();
       
   139     
       
   140     iThread.SetPriority( CLoadGenUtils::SettingItemToThreadPriority( iAttributes.iPriority ) );
       
   141     }
       
   142     
       
   143 // --------------------------------------------------------------------------------------------
       
   144 
       
   145 void CMessages::Close()
       
   146     {
       
   147     CLoadBase::Close();
       
   148 
       
   149     if ( iThread.ExitReason() == 0 ) // check if the thread is still alive
       
   150         {
       
   151         // signal the thread that it needs to close
       
   152         iThread.RequestComplete( iAttributes.iDeathStatus, KErrCancel );
       
   153 
       
   154         // wait the thread to die
       
   155         TRequestStatus waiter;
       
   156         iThread.Logon( waiter );
       
   157         User::WaitForRequest( waiter );
       
   158         iThread.Close();
       
   159         }
       
   160     }
       
   161     
       
   162 // --------------------------------------------------------------------------------------------
       
   163 
       
   164 TPtrC CMessages::Description()
       
   165     {
       
   166     TBuf<256> buf;
       
   167     TBuf<16> prioBuf;
       
   168     TBuf<3> typeBuf;
       
   169     CLoadGenUtils::SettingItemToThreadDescription( iAttributes.iPriority, prioBuf );
       
   170     if ( iAttributes.iMessageType == EMessageTypeSMS )
       
   171         {
       
   172         typeBuf.Copy( KMessageSMSType );
       
   173         }
       
   174     else
       
   175         {
       
   176         typeBuf.Copy( KMessageMMSType );
       
   177         }
       
   178     _LIT(KMessagesEntry, "[%d] Type=%S prio=%S dest=%S idle=%dms random=%d%%");
       
   179     buf.Format( KMessagesEntry,  iAttributes.iId, &typeBuf, &prioBuf, &iAttributes.iDestination, 
       
   180                 iAttributes.iIdle, iAttributes.iRandomVariance );
       
   181     
       
   182     return TPtrC( buf );
       
   183     }               
       
   184 // --------------------------------------------------------------------------------------------
       
   185 
       
   186 CMessageManager* CMessageManager::NewL( TMessageAttributes& aAttributes )
       
   187     {
       
   188     CMessageManager* self = new(ELeave) CMessageManager( aAttributes );
       
   189     CleanupStack::PushL( self );
       
   190     self->ConstructL();
       
   191     CleanupStack::Pop( self );
       
   192     return self;
       
   193     }
       
   194 
       
   195 // --------------------------------------------------------------------------------------------
       
   196 CMessageManager::CMessageManager( TMessageAttributes& aAttributes ) :
       
   197     CActive( EPriorityStandard ), iAttributes( aAttributes ), iState( EStateIdle )
       
   198     {
       
   199     iMessageCounter = 0;
       
   200     }
       
   201 
       
   202 // --------------------------------------------------------------------------------------------
       
   203     
       
   204 CMessageManager::~CMessageManager()
       
   205     {
       
   206     Cancel();
       
   207     delete iMessage;
       
   208     if ( iPeriodicTimer )
       
   209         {
       
   210         iPeriodicTimer->Cancel();
       
   211         delete iPeriodicTimer;
       
   212         }
       
   213     if ( iAttributes.iMessageType == EMessageTypeSMS && iSmsHandler )
       
   214         {
       
   215         delete iSmsHandler;
       
   216         }
       
   217     else if ( iMmsHandler )
       
   218         {
       
   219         delete iMmsHandler;
       
   220         }
       
   221     }
       
   222 
       
   223 // --------------------------------------------------------------------------------------------
       
   224  
       
   225 void CMessageManager::ConstructL()
       
   226     {
       
   227     CActiveScheduler::Add( this );
       
   228     
       
   229     // set the status as pending
       
   230     iStatus = KRequestPending;
       
   231     SetActive();
       
   232     
       
   233     // set the death status pointer point to the request status of this ao
       
   234     iAttributes.iDeathStatus = &iStatus;
       
   235     if ( iAttributes.iAmount > 0 )
       
   236         {
       
   237         iState = EStateSend;
       
   238         }
       
   239     iMessage = HBufC::NewL( iAttributes.iLength );
       
   240     CreateMessage();
       
   241 
       
   242     // init SMS sender ao
       
   243     if ( iAttributes.iMessageType == EMessageTypeSMS )
       
   244         {
       
   245         iSmsHandler = CSmsHandler::NewL( *this );
       
   246         }
       
   247     else
       
   248         {
       
   249         iMmsHandler = CMmsHandler::NewL( *this );
       
   250         }
       
   251     // start timer    
       
   252     iPeriodicTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
   253     iPeriodicTimer->Start( KDefaultStart, KDefaultPeriod, 
       
   254                         TCallBack( PeriodicTimerCallBack, this ) );
       
   255     }
       
   256 
       
   257 // --------------------------------------------------------------------------------------------
       
   258  
       
   259 void CMessageManager::RunL()
       
   260     {
       
   261     // request status has completed by the main thread meaning that we need to stop now
       
   262     CActiveScheduler::Stop();
       
   263     }
       
   264 
       
   265 // --------------------------------------------------------------------------------------------
       
   266  
       
   267 void CMessageManager::DoCancel()
       
   268     {
       
   269     }
       
   270     
       
   271 // --------------------------------------------------------------------------------------------
       
   272 
       
   273 TInt CMessageManager::PeriodicTimerCallBack(TAny* aAny)
       
   274     {
       
   275     CMessageManager* self = static_cast<CMessageManager*>( aAny );
       
   276 
       
   277     self->iPeriodicTimer->Cancel();
       
   278     self->HandleMessageSending();
       
   279 
       
   280     return KErrNone;
       
   281     }
       
   282 
       
   283 // --------------------------------------------------------------------------------------------
       
   284 
       
   285 void CMessageManager::CreateMessage()
       
   286     {
       
   287     // Message body
       
   288     TBuf<KTestMessageLength> mToYou( KMessageSMS );
       
   289     TPtr ptr = iMessage->Des();
       
   290 
       
   291     // Take as many characters as user requested to create the message
       
   292     for ( TInt j = 0; j < iAttributes.iLength; j++ )
       
   293           {
       
   294            for ( TInt k = 0; k < KTestMessageLength;  k++ )
       
   295                {
       
   296                ptr.Append( mToYou[k] );
       
   297                j++;
       
   298                if ( j == iAttributes.iLength )
       
   299                    {
       
   300                    break;
       
   301                    }
       
   302                }        
       
   303            }
       
   304     }
       
   305 
       
   306 
       
   307 // --------------------------------------------------------------------------------------------
       
   308 
       
   309 void CMessageManager::HandleMessageSending()
       
   310     {
       
   311     if ( iState == EStateSend && iAttributes.iDestination.Length() <= KTelephoneNumberMaxLength )
       
   312         {
       
   313         TBool err( KErrNone );        
       
   314 
       
   315         // make a new call
       
   316         iState = EStateSending;
       
   317  
       
   318         iMessageCounter++;
       
   319         if ( iAttributes.iMessageType == EMessageTypeSMS )
       
   320             {
       
   321             TRAP( err, iSmsHandler->SendL( iAttributes.iDestination, *iMessage ) );
       
   322             if ( !err )
       
   323                 {
       
   324                 iState = EStateIdle;
       
   325                 iPeriodicTimer->Start( CLoadGenUtils::MilliSecondsToMicroSeconds( iAttributes.iIdle,
       
   326                             iAttributes.iRandomVariance ), KDefaultPeriod, 
       
   327                             TCallBack( PeriodicTimerCallBack, this ) );
       
   328 
       
   329                 }
       
   330             }
       
   331         else
       
   332             {
       
   333             TRAP( err, iMmsHandler->SendL( iAttributes.iDestination, *iMessage ) );            
       
   334             if ( err )
       
   335                 {
       
   336                 HandleStatus( EStateIdle );
       
   337                 }
       
   338             }
       
   339         }
       
   340     else
       
   341         {
       
   342         iState = EStateIdle;
       
   343         iPeriodicTimer->Start( CLoadGenUtils::MilliSecondsToMicroSeconds( iAttributes.iIdle,
       
   344                     iAttributes.iRandomVariance ), KDefaultPeriod, 
       
   345                     TCallBack( PeriodicTimerCallBack, this ) );
       
   346 
       
   347         }
       
   348     }
       
   349 
       
   350 // --------------------------------------------------------------------------------------------
       
   351 
       
   352 void CMessageManager::HandleStatus( TInt /*aErr*/ )
       
   353     {
       
   354     // timer after wait
       
   355     if ( iMessageCounter < iAttributes.iAmount )
       
   356         {
       
   357         iState = EStateSend;
       
   358         iPeriodicTimer->Cancel();
       
   359         iPeriodicTimer->Start( CLoadGenUtils::MilliSecondsToMicroSeconds( iAttributes.iIdle,
       
   360                     iAttributes.iRandomVariance ), KDefaultPeriod, 
       
   361                     TCallBack( PeriodicTimerCallBack, this ) );
       
   362         }
       
   363     }
       
   364 
       
   365 // --------------------------------------------------------------------------------------------
       
   366 // --------------------------------------------------------------------------------------------
       
   367 // INCLUDE FILES
       
   368 #include <eikenv.h>
       
   369 #include <coemain.h>
       
   370 #include <e32std.h>
       
   371 #include <msvids.h>
       
   372 #include <msvstd.h>
       
   373 #include <smsclnt.h>
       
   374 #include <smut.h>
       
   375 #include <mtclreg.h>
       
   376 #include <txtrich.h>
       
   377 #include <smscmds.h>
       
   378 #include <mtmuibas.h>
       
   379 #include <mtmdef.h>
       
   380 #include <StringLoader.h>
       
   381 #include "smutset.h"
       
   382 #include "smuthdr.h"
       
   383  
       
   384  
       
   385  
       
   386 // ============================ MEMBER FUNCTIONS ===============================
       
   387 // -----------------------------------------------------------------------------
       
   388 // CSmsHandler::CSmsHandler()
       
   389 // C++ default constructor can NOT contain any code, that might leave.
       
   390 // -----------------------------------------------------------------------------
       
   391 //
       
   392 CSmsHandler::CSmsHandler( CMessageManager& aManager )
       
   393     : CActive( CActive::EPriorityStandard ), iManager( aManager )
       
   394     {
       
   395     CActiveScheduler::Add( this );
       
   396     }
       
   397  
       
   398 // -----------------------------------------------------------------------------
       
   399 // CSmsHandler::ConstructL()
       
   400 // Symbian 2nd phase constructor can leave.
       
   401 // -----------------------------------------------------------------------------
       
   402 //
       
   403 void CSmsHandler::ConstructL()
       
   404     {
       
   405     // Session to message server is opened asynchronously.
       
   406     iSession = CMsvSession::OpenAsyncL( *this );
       
   407  
       
   408     }
       
   409  
       
   410 // -----------------------------------------------------------------------------
       
   411 // CSmsHandler::NewL()
       
   412 // Two-phased constructor.
       
   413 // -----------------------------------------------------------------------------
       
   414 //
       
   415 CSmsHandler* CSmsHandler::NewL( CMessageManager& aManager  )
       
   416     {
       
   417     CSmsHandler* self = NewLC( aManager );
       
   418     CleanupStack::Pop( self );
       
   419     return self;
       
   420     }
       
   421  
       
   422 // -----------------------------------------------------------------------------
       
   423 // CSmsHandler::NewLC()
       
   424 // Two-phased constructor.
       
   425 // -----------------------------------------------------------------------------
       
   426 //
       
   427 CSmsHandler* CSmsHandler::NewLC(  CMessageManager& aManager )
       
   428     {
       
   429     CSmsHandler* self = new ( ELeave ) CSmsHandler( aManager );
       
   430     CleanupStack::PushL( self );
       
   431     self->ConstructL();
       
   432     return self;
       
   433     }
       
   434  
       
   435 // ----------------------------------------------------------
       
   436 // CSmsHandler::~CSmsHandler()
       
   437 // Destructor.
       
   438 // ----------------------------------------------------------
       
   439 //
       
   440 CSmsHandler::~CSmsHandler()
       
   441     {
       
   442     Cancel();           // cancel any outstanding request
       
   443  
       
   444     delete iOperation;
       
   445     delete iMtmUiRegistry;
       
   446     delete iSmsMtm;
       
   447     delete iMtmRegistry;
       
   448     delete iSession;    // session must be deleted last
       
   449     }
       
   450  
       
   451 // -----------------------------------------------------------------------------
       
   452 // CSmsHandler::DoCancel()
       
   453 // Cancels a request.
       
   454 // -----------------------------------------------------------------------------
       
   455 //
       
   456 void CSmsHandler::DoCancel()
       
   457     {
       
   458     if ( iOperation )
       
   459         {
       
   460         iOperation->Cancel();
       
   461         }
       
   462     }
       
   463  
       
   464 // -----------------------------------------------------------------------------
       
   465 // CSmsHandler::RunL()
       
   466 // Handles request completion events.
       
   467 // -----------------------------------------------------------------------------
       
   468 //
       
   469 void CSmsHandler::RunL()
       
   470     {
       
   471     User::LeaveIfError( iStatus != KErrNone );
       
   472  
       
   473     // Determine the current operations progress.
       
   474     // ProgressL returns an 8 bit descriptor.
       
   475     TBufC8<KMsvProgressBufferLength> progress( iOperation->ProgressL() );
       
   476     _LIT8( KCompare, "KErrNone" );
       
   477     User::LeaveIfError( !progress.Compare( KCompare ) );
       
   478  
       
   479     // The pointer to the current CMsvOperation object is no longer needed.
       
   480     delete iOperation;
       
   481     iOperation = NULL;
       
   482  
       
   483     // Determine which request has finished.
       
   484     switch ( iState )
       
   485         {
       
   486         case EWaitingForMoving:
       
   487             // Once a message is moved to Outbox it is scheduled for sending.
       
   488             ScheduleL();
       
   489             break;
       
   490  
       
   491         case EWaitingForScheduling:
       
   492             {
       
   493             TMsvEntry entry( iSmsMtm->Entry().Entry() );
       
   494             TInt state( entry.SendingState() );
       
   495  
       
   496             if ( state == KMsvSendStateWaiting || state == KMsvSendStateScheduled)
       
   497                 {
       
   498                 // notify the observer that status has changed
       
   499                 iManager.HandleStatus( iStatus.Int() );
       
   500                 }
       
   501             break;
       
   502             }
       
   503  
       
   504         default:
       
   505             break;
       
   506         }
       
   507     }
       
   508  
       
   509 // -----------------------------------------------------------------------------
       
   510 // CSmsHandler::HandleSessionEventL()
       
   511 // Handles notifications of events from the Message Server.
       
   512 // -----------------------------------------------------------------------------
       
   513 //
       
   514 void CSmsHandler::HandleSessionEventL( TMsvSessionEvent aEvent,
       
   515                                       TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
       
   516     {
       
   517     switch ( aEvent )
       
   518         {
       
   519         // Session to server established
       
   520         case EMsvServerReady:
       
   521             {
       
   522             TMsvId serviceId( KUidMsgTypeSMS.iUid ); // SMS service id
       
   523  
       
   524             // Determine if the event was succesful.
       
   525             // ServiceProgress inserts TBuf8 value in progress.
       
   526             TBuf8<KBfrLength> progress;
       
   527             iSession->ServiceProgress( serviceId, progress );
       
   528             _LIT8( KCompare, "KErrNone" );
       
   529  
       
   530             if ( progress.Compare( KCompare ) )
       
   531                 {
       
   532                 // Check that MtmRegistry has not already been accessed.
       
   533                 if ( !iMtmRegistry )
       
   534                     {
       
   535                     AccessMtmL();
       
   536                     }
       
   537                 }
       
   538             break;
       
   539             }
       
   540  
       
   541         // All other events are ignored.
       
   542         default:
       
   543             break;
       
   544         }
       
   545     }
       
   546  
       
   547 // -----------------------------------------------------------------------------
       
   548 // CSmsHandler::AccessMtmL()
       
   549 // Access the MTM Registry and create a SMS specific Client MTM instance.
       
   550 // -----------------------------------------------------------------------------
       
   551 //
       
   552 void CSmsHandler::AccessMtmL()
       
   553     {
       
   554     // Create an MTM Registry object.
       
   555     iMtmRegistry = CClientMtmRegistry::NewL( *iSession );
       
   556  
       
   557     // Create an SMS Client MTM object.
       
   558     iSmsMtm = STATIC_CAST( CSmsClientMtm*, iMtmRegistry->NewMtmL( KUidMsgTypeSMS ) );
       
   559     }
       
   560  
       
   561 // -----------------------------------------------------------------------------
       
   562 // CSmsHandler::SendL()
       
   563 // Starts the process of creating and sending an SMS message.
       
   564 // -----------------------------------------------------------------------------
       
   565 //
       
   566 TBool CSmsHandler::SendL( const TDesC& aRecipientNumber,
       
   567                             const TDesC& aMessageText )
       
   568     {
       
   569     iRecipientNumber = aRecipientNumber;
       
   570     iMessageText = aMessageText;
       
   571  
       
   572     if ( CreateMsgL() )
       
   573         {
       
   574         return ETrue;
       
   575         }
       
   576  
       
   577     return EFalse;
       
   578     }
       
   579  
       
   580 // -----------------------------------------------------------------------------
       
   581 // CSmsHandler::CreateMsgL()
       
   582 // Create an SMS message.
       
   583 // -----------------------------------------------------------------------------
       
   584 //
       
   585 TBool CSmsHandler::CreateMsgL()
       
   586     {
       
   587 	if(!iSmsMtm)
       
   588 		{
       
   589 		return EFalse;
       
   590 		}
       
   591     // Current entry is the Draft folder.
       
   592     iSmsMtm->SwitchCurrentEntryL( KMsvDraftEntryId );
       
   593  
       
   594     // Create a new SMS message entry as a child of the current context.
       
   595     iSmsMtm->CreateMessageL( KUidMsgTypeSMS.iUid );
       
   596  
       
   597     CMsvEntry& serverEntry = iSmsMtm->Entry();
       
   598     TMsvEntry entry( serverEntry.Entry() );
       
   599  
       
   600     CRichText& body = iSmsMtm->Body();   // the body of the message
       
   601     body.Reset();
       
   602     // Insert the message text gotten as input from user.
       
   603     body.InsertL( 0, iMessageText );
       
   604  
       
   605     // Message will be sent immediately.
       
   606     entry.SetSendingState( KMsvSendStateWaiting );
       
   607  
       
   608     entry.iDate.UniversalTime(); // insert current time //Solution for HomeTime()
       
   609 
       
   610     // Set the SMS message settings for the message.
       
   611     CSmsHeader& header = iSmsMtm->SmsHeader();
       
   612     CSmsSettings* settings = CSmsSettings::NewL();
       
   613     CleanupStack::PushL( settings );
       
   614  
       
   615     settings->CopyL( iSmsMtm->ServiceSettings() );    // restore settings
       
   616     settings->SetDelivery( ESmsDeliveryImmediately ); // to be delivered immediately
       
   617     settings->SetDeliveryReport(ETrue);
       
   618     header.SetSmsSettingsL( *settings );              // new settings
       
   619  
       
   620     // Let's check if there is a service center address.
       
   621     if ( header.Message().ServiceCenterAddress().Length() == 0 )
       
   622         {
       
   623         // No, there isn't. We assume there is at least one service center
       
   624         // number set and use the default service center number.
       
   625         CSmsSettings* serviceSettings = &( iSmsMtm->ServiceSettings() );
       
   626  
       
   627         // Check if number of service center addresses in the list is null.
       
   628  
       
   629         //Changed for 3rd Edition specially
       
   630         if ( !serviceSettings->ServiceCenterCount() )
       
   631             {
       
   632             CleanupStack::PopAndDestroy( settings ); 
       
   633             return EFalse;     // quit creating the message
       
   634             }
       
   635  
       
   636         else
       
   637             {
       
   638             //Changed for 3rd Edition specially            
       
   639             CSmsNumber* smsCenter= CSmsNumber::NewL();
       
   640             CleanupStack::PushL(smsCenter);
       
   641             smsCenter->SetAddressL((serviceSettings->GetServiceCenter( 
       
   642                             serviceSettings->DefaultServiceCenter())).Address());
       
   643             header.Message().SetServiceCenterAddressL( smsCenter->Address() );
       
   644             CleanupStack::PopAndDestroy(smsCenter);
       
   645             }
       
   646         }
       
   647  
       
   648     CleanupStack::PopAndDestroy( settings );
       
   649  
       
   650     // Recipient number is displayed also as the recipient alias.
       
   651     entry.iDetails.Set( iRecipientNumber );
       
   652     // Add addressee.
       
   653     iSmsMtm->AddAddresseeL( iRecipientNumber, entry.iDetails );
       
   654  
       
   655     // Validate message.
       
   656     if ( !ValidateL() )
       
   657         {
       
   658         return EFalse;
       
   659         }
       
   660  
       
   661     entry.SetVisible( ETrue );          // set message as visible
       
   662     entry.SetInPreparation( EFalse );   // set together with the visibility flag
       
   663     serverEntry.ChangeL( entry );       // commit changes        
       
   664     iSmsMtm->SaveMessageL();            // save message
       
   665  
       
   666     TMsvSelectionOrdering selection;
       
   667     CMsvEntry* parentEntry = CMsvEntry::NewL( iSmsMtm->Session(), KMsvDraftEntryId, selection );
       
   668     CleanupStack::PushL( parentEntry );
       
   669  
       
   670     // Move message to Outbox.
       
   671     iOperation =parentEntry->MoveL( entry.Id(), KMsvGlobalOutBoxIndexEntryId, iStatus );
       
   672  
       
   673     CleanupStack::PopAndDestroy( parentEntry );
       
   674  
       
   675     iState = EWaitingForMoving;
       
   676     SetActive();
       
   677  
       
   678     return ETrue;
       
   679   }
       
   680  
       
   681 // -----------------------------------------------------------------------------
       
   682 // CSmsHandler::ValidateL()
       
   683 // Validate an SMS message.
       
   684 // -----------------------------------------------------------------------------
       
   685 //
       
   686 TBool CSmsHandler::ValidateL()
       
   687     {
       
   688 	if( !iSmsMtm )
       
   689 		{
       
   690 		return EFalse;
       
   691 		}
       
   692     // Empty part list to hold the result.
       
   693     TMsvPartList result( KMsvMessagePartNone );
       
   694  
       
   695     // Validate message body.
       
   696     result = iSmsMtm->ValidateMessage( KMsvMessagePartBody );
       
   697  
       
   698     if ( result != KMsvMessagePartNone )
       
   699         {
       
   700         return EFalse;
       
   701         }
       
   702  
       
   703     // Validate recipient.
       
   704     result = iSmsMtm->ValidateMessage( KMsvMessagePartRecipient );
       
   705  
       
   706     if ( result != KMsvMessagePartNone )
       
   707         {
       
   708         return EFalse;
       
   709         }
       
   710  
       
   711     return ETrue;
       
   712     }
       
   713  
       
   714 // -----------------------------------------------------------------------------
       
   715 // CSmsHandler::ScheduleL()
       
   716 // Schedule an SMS message for sending.
       
   717 // -----------------------------------------------------------------------------
       
   718 //
       
   719 void CSmsHandler::ScheduleL()
       
   720     {
       
   721 	if( !iSmsMtm )
       
   722 		{
       
   723 		return;
       
   724 		}
       
   725     CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
       
   726     CleanupStack::PushL( selection );
       
   727     selection->AppendL( iSmsMtm->Entry().EntryId() ); // add message to selection
       
   728  
       
   729     // Add entry to task scheduler.
       
   730     TBuf8<1> dummyParams;   // dummy parameters needed for InvokeAsyncFunctionL
       
   731     iOperation = iSmsMtm->InvokeAsyncFunctionL( ESmsMtmCommandScheduleCopy,
       
   732                           *selection, dummyParams, iStatus );
       
   733  
       
   734     CleanupStack::PopAndDestroy( selection );
       
   735  
       
   736     iState = EWaitingForScheduling;
       
   737     SetActive();
       
   738     }
       
   739  
       
   740 // --------------------------------------------------------------------------------------------
       
   741 // --------------------------------------------------------------------------------------------
       
   742 
       
   743 
       
   744 
       
   745 // INCLUDE FILES
       
   746 #include <mtclreg.h>                  // for CClientMtmRegistry 
       
   747 #include <msvids.h>                   // for Message type IDs
       
   748 #include <mmsclient.h>                // for CMmsClientMtm
       
   749 #include <AknQueryDialog.h>           // for CAknTextQueryDialog
       
   750 #include <f32file.h>                
       
   751 #include <coeutils.h>                  // Check the file exist
       
   752 
       
   753 #include <cmsvmimeheaders.h>        //Attachemt mimeheader
       
   754 #include <mmsvattachmentmanager.h>    //Attachment manager
       
   755 
       
   756 // -----------------------------------------------------------------------------
       
   757 // CMmsHandler::CSmsHandler()
       
   758 // C++ default constructor can NOT contain any code, that might leave.
       
   759 // -----------------------------------------------------------------------------
       
   760 //
       
   761 CMmsHandler::CMmsHandler( CMessageManager& aManager ) : iManager( aManager )
       
   762     {
       
   763     }
       
   764  
       
   765 // -----------------------------------------------------------------------------
       
   766 // CMmsHandler::ConstructL()
       
   767 // Symbian 2nd phase constructor can leave.
       
   768 // -----------------------------------------------------------------------------
       
   769 //
       
   770 void CMmsHandler::ConstructL()
       
   771     {
       
   772     // Session to message server is opened asynchronously.
       
   773     iSession = CMsvSession::OpenAsyncL( *this );
       
   774  
       
   775     }
       
   776  
       
   777 // -----------------------------------------------------------------------------
       
   778 // CMmsHandler::NewL()
       
   779 // Two-phased constructor.
       
   780 // -----------------------------------------------------------------------------
       
   781 //
       
   782 CMmsHandler* CMmsHandler::NewL( CMessageManager& aManager  )
       
   783     {
       
   784     CMmsHandler* self = NewLC( aManager );
       
   785     CleanupStack::Pop( self );
       
   786     return self;
       
   787     }
       
   788  
       
   789 // -----------------------------------------------------------------------------
       
   790 // CMmsHandler::NewLC()
       
   791 // Two-phased constructor.
       
   792 // -----------------------------------------------------------------------------
       
   793 //
       
   794 CMmsHandler* CMmsHandler::NewLC(  CMessageManager& aManager )
       
   795     {
       
   796     CMmsHandler* self = new ( ELeave ) CMmsHandler( aManager );
       
   797     CleanupStack::PushL( self );
       
   798     self->ConstructL();
       
   799     return self;
       
   800     }
       
   801  
       
   802 // ----------------------------------------------------------
       
   803 // CMmsHandler::~CSmsHandler()
       
   804 // Destructor.
       
   805 // ----------------------------------------------------------
       
   806 //
       
   807 CMmsHandler::~CMmsHandler()
       
   808     {
       
   809     delete iMmsMtm;
       
   810     delete iMtmReg;
       
   811     delete iSession;    // session must be deleted last (and constructed first)
       
   812     }
       
   813 
       
   814 /*
       
   815 -----------------------------------------------------------------------------
       
   816     CMmsHandler::CompleteConstructL()
       
   817     Creates client MTM registry when session is ready for use. 
       
   818     This completes model construction and is called after 'server
       
   819     ready' event is received after async opening of CMsvSession.
       
   820 -----------------------------------------------------------------------------
       
   821 */
       
   822 void CMmsHandler::CompleteConstructL()
       
   823     {
       
   824     // We get a MtmClientRegistry from our session
       
   825     // this registry is used to instantiate new mtms.
       
   826     iMtmReg = CClientMtmRegistry::NewL( *iSession );
       
   827     iMmsMtm = (CMmsClientMtm*)iMtmReg->NewMtmL( KUidMsgTypeMultimedia );
       
   828     }
       
   829    
       
   830 /*
       
   831 -----------------------------------------------------------------------------
       
   832     CMmsHandler::HandleSessionEventL()
       
   833 
       
   834     Receives session events from observer and calls event handling functions. 
       
   835     Note that if additional session event handlers are defined 
       
   836     in the session, they are called before this function (as this is the
       
   837     main session observer).
       
   838     The type of event is indicated by the value of aEvent. The 
       
   839     interpretation of the TAny arguments depends on this type. 
       
   840 -----------------------------------------------------------------------------
       
   841 */
       
   842 void CMmsHandler::HandleSessionEventL(TMsvSessionEvent aEvent, 
       
   843                                         TAny* /*aArg1*/, 
       
   844                                         TAny* /*aArg2*/, 
       
   845                                         TAny* /*aArg3*/)
       
   846     {
       
   847     switch ( aEvent )
       
   848         {
       
   849         // This event tells us that the session has been opened
       
   850         case EMsvServerReady:
       
   851             {
       
   852             CompleteConstructL();       // Construct the mtm registry & MMS mtm
       
   853             break;
       
   854             }
       
   855         default:
       
   856             {
       
   857             break;
       
   858             }
       
   859         }
       
   860     }
       
   861 
       
   862 
       
   863 // -----------------------------------------------------------------------------
       
   864 // CSmsHandler::SendL()
       
   865 // Starts the process of creating and sending an SMS message.
       
   866 // -----------------------------------------------------------------------------
       
   867 //
       
   868 TBool CMmsHandler::SendL( const TDesC& aRecipientNumber,
       
   869                             const TDesC& aMessageText )
       
   870     {
       
   871     TInt result( EFalse );
       
   872     
       
   873     iRecipientNumber = aRecipientNumber;
       
   874     iMessageText = aMessageText;
       
   875  
       
   876     if ( CreateMsgL() )
       
   877         {
       
   878         if ( SendMessageL() )
       
   879             {
       
   880             result = ETrue;
       
   881             }
       
   882         }
       
   883  
       
   884     return result;
       
   885     }
       
   886 
       
   887 /*
       
   888 -----------------------------------------------------------------------------
       
   889     CMmsHandler::CreateMsgL()
       
   890     Creates a new message server entry and set up default values.
       
   891     In case the attachment file does not found method return EFalse
       
   892     otherwise ETrue.
       
   893     There are differenses how to add attachment file between 2nd and 3rd edition. 
       
   894 -----------------------------------------------------------------------------
       
   895 */
       
   896 TBool CMmsHandler::CreateMsgL()
       
   897     {
       
   898 
       
   899     // - CMsvEntry accesses and acts upon a particular Message Server entry.
       
   900     // - NewL() does not create a new entry, but simply a new object to access an existing entry.
       
   901     // - It takes in as parameters the client's message server session,
       
   902     //   ID of the entry to access and initial sorting order of the children of the entry. 
       
   903     CMsvEntry* entry = CMsvEntry::NewL( *iSession, 
       
   904                                         KMsvGlobalOutBoxIndexEntryId, 
       
   905                                         TMsvSelectionOrdering() );
       
   906     CleanupStack::PushL( entry );
       
   907 
       
   908     // Set context to the parent folder (Outbox)
       
   909     iMmsMtm->SwitchCurrentEntryL( entry->EntryId() );
       
   910     
       
   911     // Create new message in the parent folder (Outbox) and set it as the current context.
       
   912     iMmsMtm->CreateMessageL( iMmsMtm->DefaultServiceL() );
       
   913 
       
   914     CleanupStack::PopAndDestroy( entry ); 
       
   915     
       
   916     // Setting recipients
       
   917     // use this to add the "To" recipients.
       
   918     iMmsMtm->AddAddresseeL( iRecipientNumber );
       
   919     
       
   920     //Setting message subject
       
   921     _LIT(KMessageSubject, "MMS Message");
       
   922     iMmsMtm->SetSubjectL( KMessageSubject );
       
   923     
       
   924     // add message text
       
   925     SetMessageBodyL();
       
   926    
       
   927     TMsvEntry ent = iMmsMtm->Entry().Entry();
       
   928     // Set InPreparation to false
       
   929     ent.SetInPreparation( EFalse );
       
   930     ent.SetVisible( ETrue );            // mark as visible, after this the message can be seen in Outbox and, after sending, in Sent folder.
       
   931   
       
   932     iMmsMtm->Entry().ChangeL( ent );    // Commit changes
       
   933     
       
   934     //Save the changes
       
   935     iMmsMtm->SaveMessageL();
       
   936     
       
   937     return ETrue;
       
   938     }
       
   939 
       
   940 //---------------------------------------------------------------------------------
       
   941 void CMmsHandler::SetMessageBodyL()
       
   942     {
       
   943     _LIT (KFilenameText, "msg.txt");
       
   944     CMsvStore* store = iMmsMtm->Entry().EditStoreL();
       
   945     CleanupStack::PushL( store );
       
   946 
       
   947     TMsvAttachmentId attachmentId = KMsvNullIndexEntryId;
       
   948 
       
   949     iMmsMtm->CreateTextAttachmentL ( *store,
       
   950                                      attachmentId,
       
   951                                      iMessageText,
       
   952                                      KFilenameText );
       
   953 
       
   954     store->CommitL();
       
   955 
       
   956     CleanupStack::PopAndDestroy( store );
       
   957     }
       
   958 
       
   959 /* 
       
   960 -----------------------------------------------------------------------------
       
   961     CMmsHandler::SendMessageL()
       
   962     Sends the message.
       
   963     Return values: ETrue or EFalse
       
   964 -----------------------------------------------------------------------------
       
   965 */
       
   966 TBool CMmsHandler::SendMessageL()
       
   967     {
       
   968 
       
   969     // Start sending the message via the Server MTM to the MMS server
       
   970     CMsvOperationWait* wait = CMsvOperationWait::NewLC();
       
   971     wait->iStatus = KRequestPending;
       
   972     CMsvOperation* op = NULL;
       
   973        op = iMmsMtm->SendL( wait->iStatus );
       
   974     wait->Start();
       
   975     CleanupStack::PushL( op );
       
   976     CActiveScheduler::Start();
       
   977 
       
   978     // The following is to ignore the completion of other active objects. It is not
       
   979     // needed if the app has a command absorbing control.
       
   980     while( wait->iStatus == KRequestPending )
       
   981         {
       
   982         CActiveScheduler::Start();
       
   983         }
       
   984 
       
   985     iManager.HandleStatus( wait->iStatus.Int() );
       
   986     CleanupStack::PopAndDestroy(2); // op, wait
       
   987     
       
   988     return ETrue;
       
   989     }
       
   990 // End of File