satengine/SatServer/Commands/SendSmCmd/src/CSendSmHandler.cpp
changeset 46 2fa1fa551b0b
parent 42 35488577e233
child 48 78df25012fda
equal deleted inserted replaced
42:35488577e233 46:2fa1fa551b0b
     1 /*
       
     2 * Copyright (c) 2002-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:  Handles SendSm command
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include    "MSatApi.h"
       
    20 #include    "MSatUtils.h"
       
    21 #include    "MSatSystemState.h"
       
    22 #include    "MSatUiSession.h"
       
    23 #include    "SatSTypes.h"
       
    24 #include    "SatSOpcodes.h"
       
    25 #include    "MSatSUiClientHandler.h"
       
    26 #include    "CSatSSendMessageNoLoggingHandler.h"
       
    27 #include    "CSendSmHandler.h"
       
    28 #include    "SatLog.h"
       
    29 #include    "gsmerror.h"
       
    30 #include    <exterror.h>
       
    31 #include    "TSatExtErrorUtils.h"
       
    32 
       
    33 const TUint8 KPlus = 0x2b; // '+' character
       
    34 
       
    35 // ======== MEMBER FUNCTIONS ========
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // Two-phased constructor.
       
    39 // -----------------------------------------------------------------------------
       
    40 //
       
    41 CSendSmHandler* CSendSmHandler::NewL( MSatUtils* aUtils )
       
    42     {
       
    43     LOG( SIMPLE, "SENDSM: CSendSmHandler::NewL calling" )
       
    44 
       
    45     CSendSmHandler* self = new( ELeave ) CSendSmHandler;
       
    46 
       
    47     CleanupStack::PushL( self );
       
    48     self->BaseConstructL( aUtils );
       
    49     self->ConstructL();
       
    50     CleanupStack::Pop( self );
       
    51 
       
    52     LOG( SIMPLE, "SENDSM: CSendSmHandler::NewL exiting" )
       
    53     return self;
       
    54     }
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // Destructor.
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 CSendSmHandler::~CSendSmHandler()
       
    61     {
       
    62     LOG( SIMPLE, "SENDSM: CSendSmHandler::~CSendSmHandler calling" )
       
    63 
       
    64     delete iMsgSender;
       
    65     Cancel();
       
    66 
       
    67     LOG( SIMPLE, "SENDSM: CSendSmHandler::~CSendSmHandler exiting" )
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // From class MSatCommand.
       
    72 // Query response.
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 void CSendSmHandler::ClientResponse()
       
    76     {
       
    77     LOG( SIMPLE, "SENDSM: CSendSmHandler::ClientResponse calling" )
       
    78 
       
    79     // Query response from client.
       
    80     if ( iQueryRsp.iAccepted && !iNotificationSent )
       
    81         {
       
    82         LOG( SIMPLE, "SENDSM: CSendSmHandler::ClientResponse Query response" )
       
    83         // Send notification to UI
       
    84         // Register notification observer
       
    85         TRAP_IGNORE( iUtils->RegisterServiceRequestL(
       
    86             ESatSProactiveNotification,
       
    87             ESatSProactiveNotificationResponse,
       
    88             this ) )
       
    89 
       
    90         // Get UISession.
       
    91         MSatUiSession* uiSession = iUtils->SatUiHandler().UiSession();
       
    92 
       
    93         // Send command to SatClient.
       
    94         uiSession->SendCommand( &iNotificationDataPckg,
       
    95             &iNotificationRspPckg, ESatSProactiveNotification );
       
    96 
       
    97         iNotificationSent = ETrue;
       
    98         }
       
    99     else if ( iNotificationRsp.iAccepted && iNotificationSent )
       
   100         {
       
   101         LOG( SIMPLE, "SENDSM: CSendSmHandler::ClientResponse get response" )
       
   102         // Then we can proceed with the msg sending
       
   103         if ( !iMsgSender->IsActive() )
       
   104             {
       
   105             LOG( SIMPLE, 
       
   106             "SENDSM: CSendSmHandler::ClientResponse start iMsgSender" )
       
   107             iMsgSender->Start( iSendSmData );
       
   108             }
       
   109         }
       
   110     else
       
   111         {
       
   112         if ( iQueryRsp.iSessionTerminatedByUser )
       
   113             {
       
   114             LOG( SIMPLE, 
       
   115             "SENDSM: CSendSmHandler::ClientResponse close ui session" )
       
   116             // Next SimSession end will close the ui session
       
   117             iUtils->NotifyEvent( MSatUtils::ESessionTerminatedByUser );
       
   118             }
       
   119 
       
   120         iSendSmRsp.iGeneralResult = RSat::KPCmdNotAcceptedByUser;
       
   121         iSendSmRsp.iInfoType = RSat::KNoAdditionalInfo;
       
   122         iSendSmRsp.iAdditionalInfo.Zero();
       
   123         iSendSmRsp.SetPCmdNumber( iSendSmData.PCmdNumber() );
       
   124 
       
   125         TerminalRsp( RSat::ESendSm, iSendSmRspPckg );
       
   126         }
       
   127 
       
   128     LOG( SIMPLE, "SENDSM: CSendSmHandler::ClientResponse exiting" )
       
   129     }
       
   130 
       
   131 // -----------------------------------------------------------------------------
       
   132 // From class MSatEventObserver.
       
   133 // Event notification.
       
   134 // -----------------------------------------------------------------------------
       
   135 //
       
   136 void CSendSmHandler::Event( TInt aEvent )
       
   137     {
       
   138     LOG( SIMPLE, "SENDSM: CSendSmHandler::Event calling" )
       
   139     LOG2( SIMPLE, "SENDSM: CSendSmHandler::Event iWaitingUiLaunch=%d",  
       
   140     iWaitingUiLaunch ) 
       
   141     LOG2( SIMPLE, "SENDSM: CSendSmHandler::Event IsActive=%d", IsActive() ) 
       
   142     if ( MSatUtils::EMoSmControlExecuting == aEvent )
       
   143         {
       
   144         LOG( NORMAL, "SENDSM:   Event EMoSmControlExecuting" )
       
   145         iMoSmControlActive = ETrue;
       
   146         }
       
   147     else if ( MSatUtils::EMoSmControlDone == aEvent )
       
   148         {
       
   149         LOG( NORMAL, "SENDSM:   Event EMoSmControlDone" )
       
   150         iMoSmControlActive = EFalse;
       
   151         // Check if Sendsm is waiting.
       
   152         // Completing call control should not trigger this command handler 
       
   153         // if it is still waiting for UI to be launched. 
       
   154         if ( !IsActive() && !iWaitingUiLaunch ) 
       
   155             {
       
   156             LOG( SIMPLE, "SENDSM: CSendSmHandler::Event sendsm" )
       
   157             // Do the Sendsm.
       
   158             HandleCommand();
       
   159             }
       
   160         }
       
   161 
       
   162     CSatCommandHandler::Event( aEvent );
       
   163 
       
   164     LOG( SIMPLE, "SENDSM: CSendSmHandler::Event exiting" )
       
   165     }
       
   166 
       
   167 // -----------------------------------------------------------------------------
       
   168 // From class MSatEventObserver.
       
   169 // Notification that sms was sent.
       
   170 // -----------------------------------------------------------------------------
       
   171 //
       
   172 void CSendSmHandler::SmsSent( TInt aErrorCode )
       
   173     {
       
   174     LOG2( SIMPLE, "SENDSM: CSendSmHandler::SmsSent calling, &d", aErrorCode )
       
   175 
       
   176     // Ui session is listening for sms sent event.
       
   177     iUtils->NotifyUiEvent( ESatSSmEndEvent, ESatEventNone, aErrorCode );
       
   178 
       
   179     iSendSmRsp.iInfoType = RSat::KNoAdditionalInfo;
       
   180     iSendSmRsp.iAdditionalInfo.Zero();
       
   181     iSendSmRsp.SetPCmdNumber( iSendSmData.PCmdNumber() );
       
   182 
       
   183     if ( KErrSatMoSmControlModified == aErrorCode )
       
   184         {
       
   185         LOG( SIMPLE, "SENDSM:   KErrSatMoSmControlModified" )
       
   186         iSendSmRsp.iGeneralResult = RSat::KSuccess;
       
   187         }
       
   188     else if ( KErrSatMoSmControlBarred == aErrorCode )
       
   189         {
       
   190         LOG( SIMPLE, "SENDSM:   KErrSatMoSmControlBarred" )
       
   191         iSendSmRsp.iGeneralResult = RSat::KInteractionWithCCPermanentError;
       
   192 
       
   193         // Additional info field contains extra info.
       
   194         iSendSmRsp.iInfoType = RSat::KControlInteraction;
       
   195 
       
   196         // Lower byte contains the SMS error cause.
       
   197         iSendSmRsp.iAdditionalInfo.SetLength( 1 );
       
   198         iSendSmRsp.iAdditionalInfo[0] =
       
   199             static_cast<TUint16>( RSat::KActionNotAllowed );
       
   200         }
       
   201     else if ( TSatExtErrorUtils::IsExtendedError( aErrorCode ) )
       
   202         {
       
   203         LOG( SIMPLE, "SENDSM:   Error code < KErrGsmSmsBase" )
       
   204 
       
   205         // Map error value
       
   206         TUint8 addInfo( 0 );
       
   207 
       
   208         if ( TSatExtErrorUtils::IsNetworkError( aErrorCode ) )
       
   209             {
       
   210             LOG( SIMPLE, "SENDSM:   NetworkError" )
       
   211             // Map extended error
       
   212             addInfo = TSatExtErrorUtils::MapError( aErrorCode );
       
   213 
       
   214             // Error utils found the correct response
       
   215             iSendSmRsp.iGeneralResult = RSat::KNetworkUnableToProcessCmd;
       
   216             // Additional info field contains extra info.
       
   217             iSendSmRsp.iInfoType = RSat::KSatNetworkErrorInfo;
       
   218             }
       
   219         else
       
   220             {
       
   221             LOG( SIMPLE, "SENDSM:   MeError" )
       
   222             // No need to modify mapped value
       
   223             addInfo = TSatExtErrorUtils::MapError( aErrorCode, EFalse );
       
   224 
       
   225             // Return GSM Error specific value.
       
   226             iSendSmRsp.iGeneralResult = RSat::KSmsRpError;
       
   227             // Additional info field contains extra info.
       
   228             iSendSmRsp.iInfoType = RSat::KMeProblem;
       
   229             }
       
   230 
       
   231         // Add additional info into terminal response
       
   232         iSendSmRsp.iAdditionalInfo.SetLength( 1 );
       
   233         iSendSmRsp.iAdditionalInfo[0] = static_cast<TUint16>( addInfo );
       
   234         }
       
   235     else if ( ( KErrGsmSMSNoNetworkService == aErrorCode ) ||
       
   236               ( KErrGsmSSNotAvailable == aErrorCode ) )
       
   237         {
       
   238         LOG( SIMPLE, "SENDSM:     UnableToProcessCmd" )
       
   239         iSendSmRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   240         iSendSmRsp.iInfoType = RSat::KMeProblem;
       
   241         iSendSmRsp.iAdditionalInfo.SetLength( 1 );
       
   242         iSendSmRsp.iAdditionalInfo[0] = RSat::KNoService;
       
   243         }
       
   244     else if ( KErrGeneral == aErrorCode )
       
   245         {
       
   246         LOG( SIMPLE, "SENDSM:   KErrGeneral" )
       
   247         iSendSmRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   248         }
       
   249     else if ( KErrTimedOut == aErrorCode )
       
   250         {
       
   251         LOG( SIMPLE, "SENDSM:   KErrTimedOut" )
       
   252         iSendSmRsp.iGeneralResult = RSat::KNetworkUnableToProcessCmd;
       
   253         }
       
   254     else
       
   255         {
       
   256         if ( !iPartialComprehension )
       
   257             {
       
   258             if ( !iNotificationRsp.iRequestedIconDisplayed &&  // No icon displayed
       
   259                 ( RSat::ESelfExplanatory ==             // Only icon
       
   260                     iSendSmData.iIconId.iQualifier ||
       
   261                   RSat::ENotSelfExplanatory ==          // Icon and text
       
   262                     iSendSmData.iIconId.iQualifier ) )
       
   263                 {
       
   264                 LOG( SIMPLE, "SENDSM:   KSuccessRequestedIconNotDisplayed" )
       
   265                 iSendSmRsp.iGeneralResult =
       
   266                     RSat::KSuccessRequestedIconNotDisplayed;
       
   267                 }
       
   268             else
       
   269                 {
       
   270                 LOG( SIMPLE, "SENDSM:   Succeed" )
       
   271                 iSendSmRsp.iGeneralResult = RSat::KSuccess;
       
   272                 }
       
   273             }
       
   274         else
       
   275             {
       
   276             LOG( SIMPLE, "SENDSM:   KPartialComprehension" )
       
   277             iPartialComprehension = EFalse;
       
   278             iSendSmRsp.iGeneralResult = RSat::KPartialComprehension;
       
   279             }
       
   280         }
       
   281 
       
   282     // If command had icon data and was done succesfully, report that icon
       
   283     // was not shown
       
   284     // To be removed when icons are allowed in this command
       
   285     if ( ( RSat::KSuccess == iSendSmRsp.iGeneralResult ) &&
       
   286         iIconCommand )
       
   287         {
       
   288         LOG( SIMPLE, 
       
   289         "SENDSM: CSendSmHandler::SmsSent KSuccessRequestedIconNotDisplayed" )
       
   290         iSendSmRsp.iGeneralResult =
       
   291                     RSat::KSuccessRequestedIconNotDisplayed;
       
   292         }
       
   293 
       
   294     TerminalRsp( RSat::ESendSm, iSendSmRspPckg );
       
   295 
       
   296     LOG( SIMPLE, "SENDSM: CSendSmHandler::SmsSent exiting" )
       
   297     }
       
   298 
       
   299 // -----------------------------------------------------------------------------
       
   300 // Sets the sca number and also sets the numbering plan and the type of number.
       
   301 // -----------------------------------------------------------------------------
       
   302 //
       
   303 TBool CSendSmHandler::SetScaNumber( const RSat::TSatTelNumber& aScaNumber )
       
   304     {
       
   305     LOG2( SIMPLE,
       
   306         "SENDSM: CSendSmHandler::SetScaNumber calling, aScaNumber :%S",
       
   307         &aScaNumber )
       
   308 
       
   309     TBool scaAvailable ( EFalse );
       
   310 
       
   311     iSendSmData.iAddress.iTelNumber = aScaNumber;
       
   312     if ( aScaNumber.Length() > 0 )
       
   313         {
       
   314         LOG2( SIMPLE, "SENDSM:   aScaNumber.Length: %d", aScaNumber.Length() )
       
   315         const RSat::TAddress address = iSendSmData.iAddress;
       
   316 
       
   317         scaAvailable = ETrue;
       
   318 
       
   319         // Is the number in international format, ie first character is '+'.
       
   320         if ( KPlus == address.iTelNumber[0] )
       
   321             {
       
   322             const RSat::TTypeOfNumber ton = address.iTypeOfNumber;
       
   323 
       
   324             // Set the type of number, if it is not known.
       
   325             if ( ( RSat::ETypeOfNumberNotSet == ton ) ||
       
   326                  ( RSat::EUnknownNumber == ton ) )
       
   327                 {
       
   328                 LOG( SIMPLE, "SENDSM:   International Number" )
       
   329                 iSendSmData.iAddress.iTypeOfNumber =
       
   330                     RSat::EInternationalNumber;
       
   331                 }
       
   332 
       
   333             const RSat::TNumberingPlan npi = address.iNumberPlan;
       
   334 
       
   335             // Set the numbering plan if it is not known.
       
   336             if ( ( RSat::ENumberingPlanNotSet == npi ) ||
       
   337                  ( RSat::EUnknownNumberingPlan == npi ) )
       
   338                 {
       
   339                 LOG( SIMPLE, "SENDSM:   Isdn Number Plan" )
       
   340                 iSendSmData.iAddress.iNumberPlan = RSat::EIsdnNumberPlan;
       
   341                 }
       
   342             }
       
   343         }
       
   344 
       
   345     LOG2( SIMPLE,
       
   346         "SENDSM: CSendSmHandler::SetScaNumber exiting, scaAvailable:%i",
       
   347         scaAvailable )
       
   348     return scaAvailable;
       
   349     }
       
   350 
       
   351 // -----------------------------------------------------------------------------
       
   352 // From class CActive.
       
   353 // Cancels the sat request.
       
   354 // -----------------------------------------------------------------------------
       
   355 //
       
   356 void CSendSmHandler::DoCancel()
       
   357     {
       
   358     LOG( SIMPLE, "SENDSM: CSendSmHandler::DoCancel calling" )
       
   359 
       
   360     iUtils->USatAPI().NotifySendSmCancel();
       
   361 
       
   362     LOG( SIMPLE, "SENDSM: CSendSmHandler::DoCancel exiting" )
       
   363     }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // From class CSatCommandHandler.
       
   367 // Requests the command notification.
       
   368 // -----------------------------------------------------------------------------
       
   369 //
       
   370 void CSendSmHandler::IssueUSATRequest( TRequestStatus& aStatus )
       
   371     {
       
   372     LOG( SIMPLE, "SENDSM: CSendSmHandler::IssueUSATRequest calling" )
       
   373 
       
   374     // Clear the IPC package.
       
   375     new (&iSendSmData) RSat::TSendSmV1();
       
   376     iNeedUiSession = ETrue;
       
   377     iQueryRsp.iAccepted = EFalse; // default
       
   378     iNotificationRsp.iAccepted = EFalse;
       
   379 
       
   380     iUtils->USatAPI().NotifySendSm( aStatus, iSendSmPckg );
       
   381 
       
   382     LOG( SIMPLE, "SENDSM: CSendSmHandler::IssueUSATRequest exiting" )
       
   383     }
       
   384 
       
   385 // -----------------------------------------------------------------------------
       
   386 // From class CSatCommandHandler.
       
   387 // SendSm command is not allowed in following situations:
       
   388 //   - Phone is not registered to homenetwork and roaming.
       
   389 // -----------------------------------------------------------------------------
       
   390 //
       
   391 TBool CSendSmHandler::CommandAllowed()
       
   392     {
       
   393     LOG( SIMPLE, "SENDSM: CSendSmHandler::CommandAllowed calling" )
       
   394     TBool commandAllowed( ETrue );
       
   395 
       
   396     RMobilePhone::TMobilePhoneRegistrationStatus registrationStatus(
       
   397         iUtils->SystemState().GetNetworkRegistrationStatus() );
       
   398 
       
   399     // Check the PC Suite backup / restore status. If it is ongoing, SendSm is
       
   400     // not allowed.
       
   401     const TBool backupOngoing(
       
   402         iUtils->SystemState().IsBackupProcessOngoing() );
       
   403 
       
   404     if ( ( RSat::EAlphaIdProvided != iSendSmData.iAlphaId.iStatus ) &&
       
   405         ( RSat::ESelfExplanatory == iSendSmData.iIconId.iQualifier ||
       
   406           RSat::ENotSelfExplanatory == iSendSmData.iIconId.iQualifier ) )
       
   407         {
       
   408         commandAllowed = EFalse;
       
   409         iSendSmRsp.iGeneralResult = RSat::KCmdDataNotUnderstood;
       
   410         iSendSmRsp.iInfoType = RSat::KNoAdditionalInfo;
       
   411         iSendSmRsp.iAdditionalInfo.Zero();
       
   412         LOG( SIMPLE, "SENDSM:   Not allowed data not understood" )
       
   413         }
       
   414     else if ( ( RMobilePhone::ERegisteredOnHomeNetwork !=
       
   415         registrationStatus ) &&
       
   416         ( RMobilePhone::ERegisteredRoaming != registrationStatus ) ||
       
   417         backupOngoing )
       
   418         {
       
   419         commandAllowed = EFalse;
       
   420         iSendSmRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   421         iSendSmRsp.iInfoType = RSat::KMeProblem;
       
   422         iSendSmRsp.iAdditionalInfo.SetLength( 1 );
       
   423         iSendSmRsp.iAdditionalInfo[0] = RSat::KNoService;
       
   424         LOG( SIMPLE, "SENDSM:   Not allowed Me unable to process" )
       
   425         }
       
   426     else if ( !IsSCAAvailable() )
       
   427         {
       
   428         LOG( SIMPLE, "SENDSM:   Not allowed !IsSCAAvailable()" )
       
   429         commandAllowed = EFalse;
       
   430         iSendSmRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   431         iSendSmRsp.iInfoType = RSat::KMeProblem;
       
   432         iSendSmRsp.iAdditionalInfo.SetLength( 1 );
       
   433         iSendSmRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem;
       
   434         }
       
   435     // Set icon command flag whether icon data was received and set qualifier
       
   436     // to no icon id
       
   437     // To be removed when icons are allowed in this command
       
   438     else if ( ( RSat::ESelfExplanatory ==
       
   439         iSendSmData.iIconId.iQualifier ) ||
       
   440         ( RSat::ENotSelfExplanatory ==
       
   441         iSendSmData.iIconId.iQualifier ) )
       
   442         {
       
   443         LOG( SIMPLE, "SENDSM:   ENoIconId" )
       
   444         iIconCommand = ETrue;
       
   445         iSendSmData.iIconId.iQualifier = RSat::ENoIconId;
       
   446         }
       
   447     else
       
   448         {
       
   449         LOG( SIMPLE, "SENDSM:   others" )
       
   450         iIconCommand = EFalse;
       
   451         }
       
   452 
       
   453     //lint -e{961} else block not needed.
       
   454     if ( !commandAllowed )
       
   455         {
       
   456         iSendSmRsp.SetPCmdNumber( iSendSmData.PCmdNumber() );
       
   457         TerminalRsp( RSat::ESendSm, iSendSmRspPckg );
       
   458         }
       
   459 
       
   460     LOG2( SIMPLE, "SENDSM: CSendSmHandler::CommandAllowed exiting,\
       
   461           commandAllowed: %d", commandAllowed )
       
   462     return commandAllowed;
       
   463     }
       
   464 
       
   465 // -----------------------------------------------------------------------------
       
   466 // From class CSatCommandHandler.
       
   467 // Need for ui session.
       
   468 // -----------------------------------------------------------------------------
       
   469 //
       
   470 TBool CSendSmHandler::NeedUiSession()
       
   471     {
       
   472     LOG( NORMAL, "SENDSM: CSendSmHandler::NeedUiSession calling" )
       
   473     // Check do we need UI
       
   474 
       
   475     // Store the result for later use
       
   476     iNeedUiSession = !TransparentSmsSending();
       
   477     // Notify Cover UI if it's supported
       
   478     if ( iNeedUiSession && iUtils->CoverUiSupported() )
       
   479         {
       
   480         TSatCommandData medEventData;
       
   481         medEventData.iPCmdNumber = RSat::ESendSm;
       
   482         medEventData.iAlphaId =  iSendSmData.iAlphaId;
       
   483         if ( iUtils->SystemState().IsConfirmSatOperationsOn() )
       
   484             {
       
   485             LOG( NORMAL, 
       
   486             "SENDSM: CSendSmHandler::NeedUiSession KSatLongDuration" )
       
   487             medEventData.iDuration.iNumOfUnits = KSatLongDuration;
       
   488             }
       
   489         else
       
   490             {
       
   491             LOG( NORMAL, 
       
   492             "SENDSM: CSendSmHandler::NeedUiSession KSatDefaultDuration" )
       
   493             medEventData.iDuration.iNumOfUnits = KSatDefaultDuration;
       
   494             }
       
   495 
       
   496         medEventData.iDuration.iTimeUnit = RSat::ESeconds;
       
   497         medEventData.iIconID = iSendSmData.iIconId;
       
   498         TSatCommandPckg tPckg( medEventData );
       
   499         iUtils->RaiseSatEvent( tPckg );
       
   500         }
       
   501 
       
   502     LOG2( NORMAL, "SENDSM: CSendSmHandler::NeedUiSession exiting, \
       
   503           iNeedUiSession: %d", iNeedUiSession )
       
   504     return iNeedUiSession;
       
   505     }
       
   506 
       
   507 // -----------------------------------------------------------------------------
       
   508 // From class CSatCommandHandler.
       
   509 // Called when USAT API notifies that command.
       
   510 // -----------------------------------------------------------------------------
       
   511 //
       
   512 void CSendSmHandler::HandleCommand()
       
   513     {
       
   514     LOG( SIMPLE, "SENDSM: CSendSmHandler::HandleCommand calling" )
       
   515 
       
   516     // If mo sm control is active, command waits for the EMoSmControlDone event
       
   517     // and sends the command then.
       
   518     if ( !iMoSmControlActive )
       
   519         {
       
   520         LOG2( SIMPLE,  
       
   521         "SENDSM: CSendSmHandler::HandleCommand: !iMoSmControlActive, \
       
   522         iNeedUiSession=%d",
       
   523         iNeedUiSession ) 
       
   524 
       
   525         iUtils->NotifyEvent( MSatUtils::ESendSmExecuting );
       
   526 
       
   527         if ( !iNeedUiSession )
       
   528             {
       
   529             LOG( SIMPLE, 
       
   530             "SENDSM: CSendSmHandler::HandleCommand not iNeedUiSession" )
       
   531             // Dont show any messages in ui client, ETSI dictates that
       
   532             // if alpha is is provided and alpha id length is 0 then ui
       
   533             // should not show anyting.
       
   534             // This is OK also for icon support.
       
   535             // Icon is successfully processed. But not shown in this case.
       
   536             if ( !iMsgSender->IsActive() )
       
   537                 {
       
   538                 LOG( SIMPLE, 
       
   539                 "SENDSM: CSendSmHandler::HandleCommand start iMsgSender" )
       
   540                 iMsgSender->Start( iSendSmData );
       
   541                 }
       
   542             }
       
   543         else
       
   544             {
       
   545             iQueryData.iCommand = ESatSSendSmQuery;
       
   546             iQueryData.iQueryText = iSendSmData.iAlphaId.iAlphaId;
       
   547             iQueryData.iIconId.iIdentifier = iSendSmData.iIconId.iIdentifier;
       
   548 
       
   549             iNotificationSent = EFalse;
       
   550             iNotificationData.iCommand = ESatSSendSmsNotify;
       
   551             iNotificationData.iText = iSendSmData.iAlphaId.iAlphaId;
       
   552             iNotificationData.iIconId.iIdentifier =
       
   553                 iSendSmData.iIconId.iIdentifier;
       
   554             LOG2( NORMAL, "SENDSM: CSendSmHandler::HandleCommand \
       
   555                   iSendSmData.iIconId.iQualifier: %d", 
       
   556                   iSendSmData.iIconId.iQualifier )
       
   557             switch ( iSendSmData.iIconId.iQualifier )
       
   558                 {
       
   559                 case RSat::ESelfExplanatory:
       
   560                     {
       
   561                     // Icon qualifier is self explanatory (to display instead
       
   562                     // of the alpha id or text string).
       
   563                     iQueryData.iIconId.iIconQualifier = ESatSelfExplanatory;
       
   564                     iNotificationData.iIconId.iIconQualifier =
       
   565                         ESatSelfExplanatory;
       
   566                     break;
       
   567                     }
       
   568 
       
   569                 case RSat::ENotSelfExplanatory:
       
   570                     {
       
   571                     // Icon qualifier is not self explanatory.
       
   572                     iQueryData.iIconId.iIconQualifier = ESatNotSelfExplanatory;
       
   573                     iNotificationData.iIconId.iIconQualifier =
       
   574                         ESatNotSelfExplanatory;
       
   575                     break;
       
   576                     }
       
   577 
       
   578                 default:
       
   579                     {
       
   580                     // Icon qualifier not present
       
   581                     iQueryData.iIconId.iIconQualifier = ESatENoIconId;
       
   582                     iNotificationData.iIconId.iIconQualifier = ESatENoIconId;
       
   583                     break;
       
   584                     }
       
   585 
       
   586                 }
       
   587             LOG2( NORMAL, "SENDSM: CSendSmHandler::HandleCommand \
       
   588                   iSendSmData.iAlphaId.iStatus: %d", 
       
   589                   iSendSmData.iAlphaId.iStatus )
       
   590             switch ( iSendSmData.iAlphaId.iStatus )
       
   591                 {
       
   592                 case RSat::EAlphaIdNotPresent:
       
   593                     {
       
   594                     iQueryData.iAlphaIdStatus = ESatAlphaIdNotProvided;
       
   595                     iNotificationData.iAlphaIdStatus = ESatAlphaIdNotProvided;
       
   596                     break;
       
   597                     }
       
   598 
       
   599                 case RSat::EAlphaIdProvided:
       
   600                     {
       
   601                     iQueryData.iAlphaIdStatus = ESatAlphaIdNotNull;
       
   602                     iNotificationData.iAlphaIdStatus = ESatAlphaIdNotNull;
       
   603                     break;
       
   604                     }
       
   605 
       
   606                 default:
       
   607                     {
       
   608                     iQueryData.iAlphaIdStatus = ESatAlphaIdNull;
       
   609                     iNotificationData.iAlphaIdStatus = ESatAlphaIdNull;
       
   610                     break;
       
   611                     }
       
   612                 }
       
   613 
       
   614             // Check do we need to confirm operation from user
       
   615             if ( !iUtils->SystemState().IsConfirmSatOperationsOn() )
       
   616                 {
       
   617                 LOG( SIMPLE, 
       
   618                 "SENDSM: CSendSmHandler::HandleCommand confirm operation" )
       
   619                 // No need to confirm, show only notification
       
   620                 // Register notification observer
       
   621                 TRAP_IGNORE( iUtils->RegisterServiceRequestL(
       
   622                     ESatSProactiveNotification,
       
   623                     ESatSProactiveNotificationResponse,
       
   624                     this ) )
       
   625 
       
   626                 LOG( SIMPLE, 
       
   627                     "SENDSM: CSendSmHandler::HandleCommand send ui notification" )
       
   628                 iUtils->SatUiHandler().UiSession()->SendCommand(
       
   629                     &iNotificationDataPckg,
       
   630                     &iNotificationRspPckg,
       
   631                     ESatSProactiveNotification );
       
   632 
       
   633                 iNotificationSent = ETrue;
       
   634                 }
       
   635             else
       
   636                 {
       
   637                 LOG( SIMPLE, 
       
   638                 "SENDSM: CSendSmHandler::HandleCommand user confirmation needed" ) 
       
   639                 // Register service request handler for SendSm command,
       
   640                 // If there is already service request for query, registering
       
   641                 // updates command handler, so client responses comes to this
       
   642                 // command handler
       
   643                 TRAP_IGNORE( iUtils->RegisterServiceRequestL(
       
   644                     ESatSProactiveQuery,
       
   645                     ESatSProactiveQueryResponse,
       
   646                     this ) )
       
   647 
       
   648                 iNotificationSent = EFalse;
       
   649 
       
   650                 LOG( SIMPLE, 
       
   651                 "SENDSM: CSendSmHandler::HandleCommand send user confirmation request" ) 
       
   652 
       
   653                 // Ask the user permission to send sms. Reply will come
       
   654                 // to ClientResponse method.
       
   655                 iUtils->SatUiHandler().UiSession()->SendCommand(
       
   656                     &iQueryPckg,
       
   657                     &iQueryRspPckg,
       
   658                     ESatSProactiveQuery );
       
   659                 }
       
   660             }
       
   661         }
       
   662 
       
   663     LOG( SIMPLE, "SENDSM: CSendSmHandler::HandleCommand exiting" )
       
   664     }
       
   665 
       
   666 // -----------------------------------------------------------------------------
       
   667 // From class CSatCommandHandler.
       
   668 // Called when UI launch fails
       
   669 // -----------------------------------------------------------------------------
       
   670 //
       
   671 void CSendSmHandler::UiLaunchFailed()
       
   672     {
       
   673     LOG( SIMPLE, "SENDSM: CSendSmHandler::UiLaunchFailed calling" )
       
   674 
       
   675     iSendSmRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   676     iSendSmRsp.iInfoType = RSat::KMeProblem;
       
   677     iSendSmRsp.iAdditionalInfo.SetLength( 1 );
       
   678     iSendSmRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem;
       
   679     iSendSmRsp.SetPCmdNumber( iSendSmData.PCmdNumber() );
       
   680 
       
   681     TerminalRsp( RSat::ESendSm, iSendSmRspPckg );
       
   682 
       
   683     LOG( SIMPLE, "SENDSM: CSendSmHandler::UiLaunchFailed exiting" )
       
   684     }
       
   685 
       
   686 // -----------------------------------------------------------------------------
       
   687 // C++ default constructor can NOT contain any code, that
       
   688 // might leave.
       
   689 // -----------------------------------------------------------------------------
       
   690 //
       
   691 //lint -e{1403, 1769} Can not be initialized, harmless.
       
   692 CSendSmHandler::CSendSmHandler() :
       
   693     CSatCommandHandler(),
       
   694     iSendSmData(),
       
   695     iSendSmPckg( iSendSmData ),
       
   696     iSendSmRsp(),
       
   697     iSendSmRspPckg( iSendSmRsp ),
       
   698     iQueryData(),
       
   699     iQueryPckg( iQueryData ),
       
   700     iQueryRsp(),
       
   701     iQueryRspPckg( iQueryRsp ),
       
   702     iNotificationData(),
       
   703     iNotificationDataPckg( iNotificationData ),
       
   704     iNotificationRsp(),
       
   705     iNotificationRspPckg( iNotificationRsp ),
       
   706     // To be removed when icons are allowed in this command
       
   707     iIconCommand( EFalse )
       
   708     {
       
   709     LOG( SIMPLE,
       
   710         "SENDSM: CSendSmHandler::CSendSmHandler calling - exiting" )
       
   711     }
       
   712 
       
   713 // -----------------------------------------------------------------------------
       
   714 // Symbian 2nd phase constructor can leave.
       
   715 // -----------------------------------------------------------------------------
       
   716 //
       
   717 void CSendSmHandler::ConstructL()
       
   718     {
       
   719     LOG( SIMPLE, "SENDSM: CSendSmHandler::ConstructL calling" )
       
   720 
       
   721     iMsgSender = CSatSSendMessageNoLoggingHandler::NewL(
       
   722         iUtils->USatAPI(),
       
   723         *this );
       
   724 
       
   725     iUtils->RegisterL( this, MSatUtils::EMoSmControlExecuting );
       
   726     iUtils->RegisterL( this, MSatUtils::EMoSmControlDone );
       
   727 
       
   728     // Create request handler. This is same that LaunchBrowser uses, so this
       
   729     // is needed also in HandleCommand - function.
       
   730     iUtils->RegisterServiceRequestL(
       
   731         ESatSProactiveQuery,
       
   732         ESatSProactiveQueryResponse,
       
   733         this );
       
   734 
       
   735     LOG( SIMPLE, "SENDSM: CSendSmHandler::ConstructL exiting" )
       
   736     }
       
   737 
       
   738 // -----------------------------------------------------------------------------
       
   739 // SMS sending should be transparent if alpha identifier is provided but it's
       
   740 // length is 0. Also user query setting is not on.
       
   741 // -----------------------------------------------------------------------------
       
   742 //
       
   743 TBool CSendSmHandler::TransparentSmsSending() const
       
   744     {
       
   745     LOG( SIMPLE, "SENDSM: CSendSmHandler::TransparentSmsSending calling" )
       
   746 
       
   747     TBool result( EFalse );
       
   748     const RSat::TAlphaId alphaId( iSendSmData.iAlphaId );
       
   749 
       
   750     if ( ( alphaId.iStatus == RSat::EAlphaIdProvided &&
       
   751            alphaId.iAlphaId.Length() == 0 ) ||
       
   752            alphaId.iStatus == RSat::EAlphaIdNull )
       
   753         {
       
   754         LOG( SIMPLE, 
       
   755         "SENDSM: CSendSmHandler::TransparentSmsSending EAlphaIdProvided" )
       
   756         if ( !iUtils->SystemState().IsConfirmSatOperationsOn() )
       
   757             {
       
   758             LOG( SIMPLE, 
       
   759             "SENDSM: CSendSmHandler::TransparentSmsSending confirm" )
       
   760             result = ETrue;
       
   761             }
       
   762 
       
   763         }
       
   764 
       
   765     LOG2( SIMPLE, "SENDSM: CSendSmHandler::TransparentSmsSending exiting: %i",
       
   766         result )
       
   767     return result;
       
   768     }
       
   769 
       
   770 // -----------------------------------------------------------------------------
       
   771 // Chaeck SCA availability.
       
   772 // -----------------------------------------------------------------------------
       
   773 //
       
   774 TBool CSendSmHandler::IsSCAAvailable()
       
   775     {
       
   776     LOG( SIMPLE, "SENDSM: CSendSmHandler::IsSCAAvailable calling" )
       
   777 
       
   778     TBool scaAvailable ( ETrue );
       
   779 
       
   780     // If Service Center Address in not specified in proactive command,
       
   781     // the SCA is taken from shared data. SMSUi sets the SCA in the
       
   782     // shared data. If the SCA is not found from shared data, then
       
   783     // sending is not allowed.
       
   784     if ( 0 == iSendSmData.iAddress.iTelNumber.Length() )
       
   785         {
       
   786         LOG( SIMPLE, "SENDSM:   TelNumber is empty" )
       
   787 
       
   788         // Address is not defined.
       
   789         if ( RSat::ETypeOfNumberNotSet == iSendSmData.iAddress.iTypeOfNumber )
       
   790             {
       
   791             iPartialComprehension = EFalse;
       
   792             }
       
   793 
       
   794         // Address is set intentionally empty.
       
   795         else
       
   796             {
       
   797             iPartialComprehension = ETrue;
       
   798             LOG( SIMPLE, "SENDSM:   The result is KPartialComprehension" )
       
   799             }
       
   800 
       
   801         scaAvailable = SetScaNumber( iUtils->SystemState().SCANumber() );
       
   802         }
       
   803     else
       
   804         {
       
   805         LOG( SIMPLE, "SENDSM:   TelNumber is not empty." )
       
   806         iPartialComprehension = EFalse;
       
   807         }
       
   808 
       
   809     LOG2( SIMPLE,
       
   810         "SENDSM: CSendSmHandler::IsSCAAvailable exiting: %i", scaAvailable )
       
   811     return scaAvailable;
       
   812     }