loadgen/src/loadgen_messages.cpp
branchRCL_3
changeset 22 fad26422216a
equal deleted inserted replaced
21:b3cee849fa46 22:fad26422216a
       
     1 /*
       
     2 * Copyright (c) 2009 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_model.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( CLoadGenModel::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     CLoadGenModel::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( CLoadGenModel::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( CLoadGenModel::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( CLoadGenModel::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     // Current entry is the Draft folder.
       
   588     iSmsMtm->SwitchCurrentEntryL( KMsvDraftEntryId );
       
   589  
       
   590     // Create a new SMS message entry as a child of the current context.
       
   591     iSmsMtm->CreateMessageL( KUidMsgTypeSMS.iUid );
       
   592  
       
   593     CMsvEntry& serverEntry = iSmsMtm->Entry();
       
   594     TMsvEntry entry( serverEntry.Entry() );
       
   595  
       
   596     CRichText& body = iSmsMtm->Body();   // the body of the message
       
   597     body.Reset();
       
   598     // Insert the message text gotten as input from user.
       
   599     body.InsertL( 0, iMessageText );
       
   600  
       
   601     // Message will be sent immediately.
       
   602     entry.SetSendingState( KMsvSendStateWaiting );
       
   603  
       
   604     entry.iDate.UniversalTime(); // insert current time //Solution for HomeTime()
       
   605 
       
   606     // Set the SMS message settings for the message.
       
   607     CSmsHeader& header = iSmsMtm->SmsHeader();
       
   608     CSmsSettings* settings = CSmsSettings::NewL();
       
   609     CleanupStack::PushL( settings );
       
   610  
       
   611     settings->CopyL( iSmsMtm->ServiceSettings() );    // restore settings
       
   612     settings->SetDelivery( ESmsDeliveryImmediately ); // to be delivered immediately
       
   613     settings->SetDeliveryReport(ETrue);
       
   614     header.SetSmsSettingsL( *settings );              // new settings
       
   615  
       
   616     // Let's check if there is a service center address.
       
   617     if ( header.Message().ServiceCenterAddress().Length() == 0 )
       
   618         {
       
   619         // No, there isn't. We assume there is at least one service center
       
   620         // number set and use the default service center number.
       
   621         CSmsSettings* serviceSettings = &( iSmsMtm->ServiceSettings() );
       
   622  
       
   623         // Check if number of service center addresses in the list is null.
       
   624  
       
   625         //Changed for 3rd Edition specially
       
   626         if ( !serviceSettings->ServiceCenterCount() )
       
   627             {
       
   628             CleanupStack::PopAndDestroy( settings ); 
       
   629             return EFalse;     // quit creating the message
       
   630             }
       
   631  
       
   632         else
       
   633             {
       
   634             //Changed for 3rd Edition specially            
       
   635             CSmsNumber* smsCenter= CSmsNumber::NewL();
       
   636             CleanupStack::PushL(smsCenter);
       
   637             smsCenter->SetAddressL((serviceSettings->GetServiceCenter( 
       
   638                             serviceSettings->DefaultServiceCenter())).Address());
       
   639             header.Message().SetServiceCenterAddressL( smsCenter->Address() );
       
   640             CleanupStack::PopAndDestroy(smsCenter);
       
   641             }
       
   642         }
       
   643  
       
   644     CleanupStack::PopAndDestroy( settings );
       
   645  
       
   646     // Recipient number is displayed also as the recipient alias.
       
   647     entry.iDetails.Set( iRecipientNumber );
       
   648     // Add addressee.
       
   649     iSmsMtm->AddAddresseeL( iRecipientNumber, entry.iDetails );
       
   650  
       
   651     // Validate message.
       
   652     if ( !ValidateL() )
       
   653         {
       
   654         return EFalse;
       
   655         }
       
   656  
       
   657     entry.SetVisible( ETrue );          // set message as visible
       
   658     entry.SetInPreparation( EFalse );   // set together with the visibility flag
       
   659     serverEntry.ChangeL( entry );       // commit changes        
       
   660     iSmsMtm->SaveMessageL();            // save message
       
   661  
       
   662     TMsvSelectionOrdering selection;
       
   663     CMsvEntry* parentEntry = CMsvEntry::NewL( iSmsMtm->Session(), KMsvDraftEntryId, selection );
       
   664     CleanupStack::PushL( parentEntry );
       
   665  
       
   666     // Move message to Outbox.
       
   667     iOperation =parentEntry->MoveL( entry.Id(), KMsvGlobalOutBoxIndexEntryId, iStatus );
       
   668  
       
   669     CleanupStack::PopAndDestroy( parentEntry );
       
   670  
       
   671     iState = EWaitingForMoving;
       
   672     SetActive();
       
   673  
       
   674     return ETrue;
       
   675   }
       
   676  
       
   677 // -----------------------------------------------------------------------------
       
   678 // CSmsHandler::ValidateL()
       
   679 // Validate an SMS message.
       
   680 // -----------------------------------------------------------------------------
       
   681 //
       
   682 TBool CSmsHandler::ValidateL()
       
   683     {
       
   684     // Empty part list to hold the result.
       
   685     TMsvPartList result( KMsvMessagePartNone );
       
   686  
       
   687     // Validate message body.
       
   688     result = iSmsMtm->ValidateMessage( KMsvMessagePartBody );
       
   689  
       
   690     if ( result != KMsvMessagePartNone )
       
   691         {
       
   692         return EFalse;
       
   693         }
       
   694  
       
   695     // Validate recipient.
       
   696     result = iSmsMtm->ValidateMessage( KMsvMessagePartRecipient );
       
   697  
       
   698     if ( result != KMsvMessagePartNone )
       
   699         {
       
   700         return EFalse;
       
   701         }
       
   702  
       
   703     return ETrue;
       
   704     }
       
   705  
       
   706 // -----------------------------------------------------------------------------
       
   707 // CSmsHandler::ScheduleL()
       
   708 // Schedule an SMS message for sending.
       
   709 // -----------------------------------------------------------------------------
       
   710 //
       
   711 void CSmsHandler::ScheduleL()
       
   712     {
       
   713     CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
       
   714     CleanupStack::PushL( selection );
       
   715     selection->AppendL( iSmsMtm->Entry().EntryId() ); // add message to selection
       
   716  
       
   717     // Add entry to task scheduler.
       
   718     TBuf8<1> dummyParams;   // dummy parameters needed for InvokeAsyncFunctionL
       
   719     iOperation = iSmsMtm->InvokeAsyncFunctionL( ESmsMtmCommandScheduleCopy,
       
   720                           *selection, dummyParams, iStatus );
       
   721  
       
   722     CleanupStack::PopAndDestroy( selection );
       
   723  
       
   724     iState = EWaitingForScheduling;
       
   725     SetActive();
       
   726     }
       
   727  
       
   728 // --------------------------------------------------------------------------------------------
       
   729 // --------------------------------------------------------------------------------------------
       
   730 
       
   731 
       
   732 
       
   733 // INCLUDE FILES
       
   734 #include <mtclreg.h>                  // for CClientMtmRegistry 
       
   735 #include <msvids.h>                   // for Message type IDs
       
   736 #include <mmsclient.h>                // for CMmsClientMtm
       
   737 #include <AknQueryDialog.h>           // for CAknTextQueryDialog
       
   738 #include <f32file.h>                
       
   739 #include <coeutils.h>                  // Check the file exist
       
   740 
       
   741 #include <cmsvmimeheaders.h>        //Attachemt mimeheader
       
   742 #include <mmsvattachmentmanager.h>    //Attachment manager
       
   743 
       
   744 // -----------------------------------------------------------------------------
       
   745 // CMmsHandler::CSmsHandler()
       
   746 // C++ default constructor can NOT contain any code, that might leave.
       
   747 // -----------------------------------------------------------------------------
       
   748 //
       
   749 CMmsHandler::CMmsHandler( CMessageManager& aManager ) : iManager( aManager )
       
   750     {
       
   751     }
       
   752  
       
   753 // -----------------------------------------------------------------------------
       
   754 // CMmsHandler::ConstructL()
       
   755 // Symbian 2nd phase constructor can leave.
       
   756 // -----------------------------------------------------------------------------
       
   757 //
       
   758 void CMmsHandler::ConstructL()
       
   759     {
       
   760     // Session to message server is opened asynchronously.
       
   761     iSession = CMsvSession::OpenAsyncL( *this );
       
   762  
       
   763     }
       
   764  
       
   765 // -----------------------------------------------------------------------------
       
   766 // CMmsHandler::NewL()
       
   767 // Two-phased constructor.
       
   768 // -----------------------------------------------------------------------------
       
   769 //
       
   770 CMmsHandler* CMmsHandler::NewL( CMessageManager& aManager  )
       
   771     {
       
   772     CMmsHandler* self = NewLC( aManager );
       
   773     CleanupStack::Pop( self );
       
   774     return self;
       
   775     }
       
   776  
       
   777 // -----------------------------------------------------------------------------
       
   778 // CMmsHandler::NewLC()
       
   779 // Two-phased constructor.
       
   780 // -----------------------------------------------------------------------------
       
   781 //
       
   782 CMmsHandler* CMmsHandler::NewLC(  CMessageManager& aManager )
       
   783     {
       
   784     CMmsHandler* self = new ( ELeave ) CMmsHandler( aManager );
       
   785     CleanupStack::PushL( self );
       
   786     self->ConstructL();
       
   787     return self;
       
   788     }
       
   789  
       
   790 // ----------------------------------------------------------
       
   791 // CMmsHandler::~CSmsHandler()
       
   792 // Destructor.
       
   793 // ----------------------------------------------------------
       
   794 //
       
   795 CMmsHandler::~CMmsHandler()
       
   796     {
       
   797     delete iMmsMtm;
       
   798     delete iMtmReg;
       
   799     delete iSession;    // session must be deleted last (and constructed first)
       
   800     }
       
   801 
       
   802 /*
       
   803 -----------------------------------------------------------------------------
       
   804     CMmsHandler::CompleteConstructL()
       
   805     Creates client MTM registry when session is ready for use. 
       
   806     This completes model construction and is called after 'server
       
   807     ready' event is received after async opening of CMsvSession.
       
   808 -----------------------------------------------------------------------------
       
   809 */
       
   810 void CMmsHandler::CompleteConstructL()
       
   811     {
       
   812     // We get a MtmClientRegistry from our session
       
   813     // this registry is used to instantiate new mtms.
       
   814     iMtmReg = CClientMtmRegistry::NewL( *iSession );
       
   815     iMmsMtm = (CMmsClientMtm*)iMtmReg->NewMtmL( KUidMsgTypeMultimedia );
       
   816     }
       
   817    
       
   818 /*
       
   819 -----------------------------------------------------------------------------
       
   820     CMmsHandler::HandleSessionEventL()
       
   821 
       
   822     Receives session events from observer and calls event handling functions. 
       
   823     Note that if additional session event handlers are defined 
       
   824     in the session, they are called before this function (as this is the
       
   825     main session observer).
       
   826     The type of event is indicated by the value of aEvent. The 
       
   827     interpretation of the TAny arguments depends on this type. 
       
   828 -----------------------------------------------------------------------------
       
   829 */
       
   830 void CMmsHandler::HandleSessionEventL(TMsvSessionEvent aEvent, 
       
   831                                         TAny* /*aArg1*/, 
       
   832                                         TAny* /*aArg2*/, 
       
   833                                         TAny* /*aArg3*/)
       
   834     {
       
   835     switch ( aEvent )
       
   836         {
       
   837         // This event tells us that the session has been opened
       
   838         case EMsvServerReady:
       
   839             {
       
   840             CompleteConstructL();       // Construct the mtm registry & MMS mtm
       
   841             break;
       
   842             }
       
   843         default:
       
   844             {
       
   845             break;
       
   846             }
       
   847         }
       
   848     }
       
   849 
       
   850 
       
   851 // -----------------------------------------------------------------------------
       
   852 // CSmsHandler::SendL()
       
   853 // Starts the process of creating and sending an SMS message.
       
   854 // -----------------------------------------------------------------------------
       
   855 //
       
   856 TBool CMmsHandler::SendL( const TDesC& aRecipientNumber,
       
   857                             const TDesC& aMessageText )
       
   858     {
       
   859     TInt result( EFalse );
       
   860     
       
   861     iRecipientNumber = aRecipientNumber;
       
   862     iMessageText = aMessageText;
       
   863  
       
   864     if ( CreateMsgL() )
       
   865         {
       
   866         if ( SendMessageL() )
       
   867             {
       
   868             result = ETrue;
       
   869             }
       
   870         }
       
   871  
       
   872     return result;
       
   873     }
       
   874 
       
   875 /*
       
   876 -----------------------------------------------------------------------------
       
   877     CMmsHandler::CreateMsgL()
       
   878     Creates a new message server entry and set up default values.
       
   879     In case the attachment file does not found method return EFalse
       
   880     otherwise ETrue.
       
   881     There are differenses how to add attachment file between 2nd and 3rd edition. 
       
   882 -----------------------------------------------------------------------------
       
   883 */
       
   884 TBool CMmsHandler::CreateMsgL()
       
   885     {
       
   886 
       
   887     // - CMsvEntry accesses and acts upon a particular Message Server entry.
       
   888     // - NewL() does not create a new entry, but simply a new object to access an existing entry.
       
   889     // - It takes in as parameters the client's message server session,
       
   890     //   ID of the entry to access and initial sorting order of the children of the entry. 
       
   891     CMsvEntry* entry = CMsvEntry::NewL( *iSession, 
       
   892                                         KMsvGlobalOutBoxIndexEntryId, 
       
   893                                         TMsvSelectionOrdering() );
       
   894     CleanupStack::PushL( entry );
       
   895 
       
   896     // Set context to the parent folder (Outbox)
       
   897     iMmsMtm->SwitchCurrentEntryL( entry->EntryId() );
       
   898     
       
   899     // Create new message in the parent folder (Outbox) and set it as the current context.
       
   900     iMmsMtm->CreateMessageL( iMmsMtm->DefaultServiceL() );
       
   901 
       
   902     CleanupStack::PopAndDestroy( entry ); 
       
   903     
       
   904     // Setting recipients
       
   905     // use this to add the "To" recipients.
       
   906     iMmsMtm->AddAddresseeL( iRecipientNumber );
       
   907     
       
   908     //Setting message subject
       
   909     _LIT(KMessageSubject, "MMS Message");
       
   910     iMmsMtm->SetSubjectL( KMessageSubject );
       
   911     
       
   912     // add message text
       
   913     SetMessageBodyL();
       
   914    
       
   915     TMsvEntry ent = iMmsMtm->Entry().Entry();
       
   916     // Set InPreparation to false
       
   917     ent.SetInPreparation( EFalse );
       
   918     ent.SetVisible( ETrue );            // mark as visible, after this the message can be seen in Outbox and, after sending, in Sent folder.
       
   919   
       
   920     iMmsMtm->Entry().ChangeL( ent );    // Commit changes
       
   921     
       
   922     //Save the changes
       
   923     iMmsMtm->SaveMessageL();
       
   924     
       
   925     return ETrue;
       
   926     }
       
   927 
       
   928 //---------------------------------------------------------------------------------
       
   929 void CMmsHandler::SetMessageBodyL()
       
   930     {
       
   931     _LIT (KFilenameText, "msg.txt");
       
   932     CMsvStore* store = iMmsMtm->Entry().EditStoreL();
       
   933     CleanupStack::PushL( store );
       
   934 
       
   935     TMsvAttachmentId attachmentId = KMsvNullIndexEntryId;
       
   936 
       
   937     iMmsMtm->CreateTextAttachmentL ( *store,
       
   938                                      attachmentId,
       
   939                                      iMessageText,
       
   940                                      KFilenameText );
       
   941 
       
   942     store->CommitL();
       
   943 
       
   944     CleanupStack::PopAndDestroy( store );
       
   945     }
       
   946 
       
   947 /* 
       
   948 -----------------------------------------------------------------------------
       
   949     CMmsHandler::SendMessageL()
       
   950     Sends the message.
       
   951     Return values: ETrue or EFalse
       
   952 -----------------------------------------------------------------------------
       
   953 */
       
   954 TBool CMmsHandler::SendMessageL()
       
   955     {
       
   956 
       
   957     // Start sending the message via the Server MTM to the MMS server
       
   958     CMsvOperationWait* wait = CMsvOperationWait::NewLC();
       
   959     wait->iStatus = KRequestPending;
       
   960     CMsvOperation* op = NULL;
       
   961        op = iMmsMtm->SendL( wait->iStatus );
       
   962     wait->Start();
       
   963     CleanupStack::PushL( op );
       
   964     CActiveScheduler::Start();
       
   965 
       
   966     // The following is to ignore the completion of other active objects. It is not
       
   967     // needed if the app has a command absorbing control.
       
   968     while( wait->iStatus == KRequestPending )
       
   969         {
       
   970         CActiveScheduler::Start();
       
   971         }
       
   972 
       
   973     iManager.HandleStatus( wait->iStatus.Int() );
       
   974     CleanupStack::PopAndDestroy(2); // op, wait
       
   975     
       
   976     return ETrue;
       
   977     }
       
   978 // End of File