satengine/SatServer/Commands/SendUSSDCmd/src/CSendUssdHandler.cpp
changeset 0 ff3b6d0fd310
child 10 a19c8664496d
child 12 ae8abd0db65c
equal deleted inserted replaced
-1:000000000000 0:ff3b6d0fd310
       
     1 /*
       
     2 * Copyright (c) 2002-2007 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 SendUssd command
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include    <CPhCltUssdSatClient.h>
       
    20 #include	<CPhCltUssd.h>
       
    21 
       
    22 #include    "MSatSystemState.h"
       
    23 #include    "MSatApi.h"
       
    24 #include    "MSatUtils.h"
       
    25 #include    "MSatUiSession.h"
       
    26 #include    "SatSOpcodes.h"
       
    27 #include    "MSatSUiClientHandler.h"
       
    28 #include    "CSendUssdHandler.h"
       
    29 #include    "TSatExtErrorUtils.h"
       
    30 #include    "SatLog.h"
       
    31 
       
    32 const TUint8 KQuarterShift( 2 );
       
    33 const TUint8 KHighNibbleShift( 4 );
       
    34 const TUint8 KDcsCharacterSet7Bit( 0x00 );
       
    35 const TUint8 KDcsCharacterSet8Bit( 0x01 );
       
    36 const TUint8 KDcsCharacterSet16Bit( 0x02 );
       
    37 const TUint8 KDcsCharacterSet7Bit2( 0x00 );
       
    38 const TUint8 KDcsCharacterSet16Bit2( 0x01 );
       
    39 const TInt   KSatMaxUSSDString( 182 );
       
    40 
       
    41 // USSD DCS coding.
       
    42 const TUint8 KSatDcs7Bit( 0x40 );
       
    43 const TUint8 KSatDcs8Bit( 0x44 );
       
    44 const TUint8 KSatDcsUCS2( 0x48 );
       
    45 const TUint8 KSatDcsUnknown( 0xFF );
       
    46 
       
    47 // ======== MEMBER FUNCTIONS ========
       
    48 
       
    49 // -----------------------------------------------------------------------------
       
    50 // Two-phased constructor.
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 CSendUssdHandler* CSendUssdHandler::NewL( MSatUtils* aUtils )
       
    54     {
       
    55     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::NewL calling" )
       
    56 
       
    57     CSendUssdHandler* self = new( ELeave ) CSendUssdHandler;
       
    58 
       
    59     CleanupStack::PushL( self );
       
    60     self->BaseConstructL( aUtils );
       
    61     CleanupStack::Pop( self );
       
    62 
       
    63     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::NewL exiting" )
       
    64     return self;
       
    65     }
       
    66 
       
    67 // -----------------------------------------------------------------------------
       
    68 // Destructor.
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 CSendUssdHandler::~CSendUssdHandler()
       
    72     {
       
    73     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::~CSendUssdHandler calling" )
       
    74 
       
    75     Cancel();
       
    76 
       
    77     if ( iUssdClient )
       
    78         {
       
    79         delete iUssdClient;
       
    80         iUssdClient = NULL;
       
    81         }
       
    82 
       
    83     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::~CSendUssdHandler exiting" )
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // From class MSatCommand.
       
    88 // Response from the client
       
    89 // -----------------------------------------------------------------------------
       
    90 //
       
    91 void CSendUssdHandler::ClientResponse()
       
    92     {
       
    93     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::ClientResponse calling" )
       
    94 
       
    95     if ( iQueryRsp.iAccepted && !iNotificationSent )
       
    96         {
       
    97         LOG( NORMAL, 
       
    98         "SENDUSSD: CSendUssdHandler::ClientResponse Sending notification" )
       
    99         iNotificationSent = ETrue;
       
   100 
       
   101         // Register service request
       
   102         TRAP_IGNORE( iUtils->RegisterServiceRequestL(
       
   103             ESatSProactiveNotification,
       
   104             ESatSProactiveNotificationResponse,
       
   105             this ) )
       
   106 
       
   107         // Send notification
       
   108         iUtils->SatUiHandler().UiSession()->SendCommand(
       
   109             &iNotificationDataPckg,
       
   110             &iNotificationRspPckg,
       
   111             ESatSProactiveNotification );
       
   112         }
       
   113 
       
   114     // Notification sent
       
   115     else if ( iNotificationRsp.iAccepted && iNotificationSent )
       
   116         {
       
   117         LOG( NORMAL, 
       
   118         "SENDUSSD: CSendUssdHandler::ClientResponse Notification response" )
       
   119         }
       
   120 
       
   121     // User reject
       
   122     else
       
   123         {
       
   124         iUserAccepted = EFalse;
       
   125         iSendUssdRsp.iInfoType = RSat::KMeProblem;
       
   126         iSendUssdRsp.iAdditionalInfo.SetLength( 1 );
       
   127         iSendUssdRsp.iAdditionalInfo[0] = RSat::KScreenBusy;
       
   128         // Cannot return KPCmdNotAcceptedByUser (ETSI 11.14 v8.3.0 p65)
       
   129         iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   130 
       
   131         if ( iQueryRsp.iSessionTerminatedByUser )
       
   132             {
       
   133             LOG( NORMAL, 
       
   134             "SENDUSSD: CSendUssdHandler::ClientResponse \
       
   135             ESessionTerminatedByUser" )
       
   136             // Notify sim session end command that next sim session end
       
   137             // should close the ui session.
       
   138             iUtils->NotifyEvent( MSatUtils::ESessionTerminatedByUser );
       
   139             }
       
   140 
       
   141         SendTerminalResponse();
       
   142         }
       
   143 
       
   144     // Release the wait
       
   145     if ( iWait.IsStarted() )
       
   146         {
       
   147         LOG( NORMAL, "SENDUSSD: CSendUssdHandler::ClientResponse stop iWait" )
       
   148         iWait.AsyncStop();
       
   149         }
       
   150 
       
   151     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::ClientResponse exiting" )
       
   152     }
       
   153 
       
   154 // -----------------------------------------------------------------------------
       
   155 // From class CSatCommandHandler.
       
   156 // Waits for indication of user rejection
       
   157 // -----------------------------------------------------------------------------
       
   158 //
       
   159 void CSendUssdHandler::Event( TInt aEvent )
       
   160     {
       
   161     LOG2( SIMPLE,
       
   162         "SENDUSSD: CSendUssdHandler::Event calling, aEvent:%d", aEvent )
       
   163 
       
   164     switch ( aEvent )
       
   165         {
       
   166         case MSatUtils::ECancelledUsingEndKey:
       
   167             {
       
   168             // Notify sim session end command that next sim session end
       
   169             // should close the ui session.
       
   170             iUtils->NotifyEvent( MSatUtils::ESessionTerminatedByUser );
       
   171             // This event is handled as above, but notification must be done.
       
   172             }
       
   173         //lint -fallthrough intended here
       
   174         case MSatUtils::ECommandCancelled:
       
   175             {
       
   176             // Cancel Ussd sending
       
   177             if ( iUssdClient )
       
   178                 {
       
   179                 LOG( SIMPLE, 
       
   180                 "SENDUSSD: CSendUssdHandler::Event iUssdClient true" )
       
   181                 iUssdClient->SendSatMessageCancel();
       
   182                 iSendUssdRsp.iGeneralResult =
       
   183                     RSat::KUssdTransactionTerminatedByUser;
       
   184                 iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo;
       
   185                 iSendUssdRsp.iAdditionalInfo.Zero();
       
   186                 SendTerminalResponse();
       
   187                 }
       
   188             break;
       
   189             }
       
   190 
       
   191         default:
       
   192             {
       
   193             // Move event to base class
       
   194             CSatCommandHandler::Event( aEvent );
       
   195             }
       
   196         }
       
   197 
       
   198     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::Event exiting" )
       
   199     }
       
   200 
       
   201 // -----------------------------------------------------------------------------
       
   202 // From class CActive.
       
   203 // Cancels the sat request.
       
   204 // -----------------------------------------------------------------------------
       
   205 //
       
   206 void CSendUssdHandler::DoCancel()
       
   207     {
       
   208     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DoCancel calling" )
       
   209 
       
   210     iUtils->USatAPI().NotifySendUssdCancel();
       
   211 
       
   212     if ( iUssdClient )
       
   213         {
       
   214         LOG( SIMPLE, 
       
   215         "SENDUSSD: CSendUssdHandler::DoCancel iUssdClient true" )
       
   216         delete iUssdClient;
       
   217         iUssdClient = NULL;
       
   218         }
       
   219 
       
   220     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DoCancel exiting" )
       
   221     }
       
   222 
       
   223 // -----------------------------------------------------------------------------
       
   224 // From class CSatCommandHandler.
       
   225 // Requests the command notification.
       
   226 // -----------------------------------------------------------------------------
       
   227 //
       
   228 void CSendUssdHandler::IssueUSATRequest( TRequestStatus& aStatus )
       
   229     {
       
   230     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::IssueUSATRequest calling" )
       
   231 
       
   232     // Clear the IPC package.
       
   233     new (&iSendUssdData) RSat::TSendUssdV1();
       
   234     iNeedUiSession = ETrue;
       
   235     iQueryRsp.iAccepted = EFalse; // default
       
   236     iNotificationRsp.iAccepted = EFalse;
       
   237     iSendUssdRsp.iGeneralResult = RSat::KPSessionTerminatedByUser; // default
       
   238 
       
   239     iUtils->USatAPI().NotifySendUssd( aStatus, iSendUssdPckg );
       
   240 
       
   241     // Unregister from events
       
   242     iUtils->UnregisterEvent( this, MSatUtils::ECommandCancelled );
       
   243     iUtils->UnregisterEvent( this, MSatUtils::ECancelledUsingEndKey );
       
   244 
       
   245     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::IssueUSATRequest exiting" )
       
   246     }
       
   247 
       
   248 // -----------------------------------------------------------------------------
       
   249 // From class CSatCommandHandler.
       
   250 // Precheck before executing the command.
       
   251 // -----------------------------------------------------------------------------
       
   252 //
       
   253 TBool CSendUssdHandler::CommandAllowed()
       
   254     {
       
   255     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::CommandAllowed calling" )
       
   256 
       
   257     // Allow next terminal response to be sent
       
   258     iTerminalRespSent = EFalse;
       
   259 
       
   260     RMobilePhone::TMobilePhoneRegistrationStatus registrationStatus(
       
   261         iUtils->SystemState().GetNetworkRegistrationStatus() );
       
   262 
       
   263     TBool commandAllowed( ETrue );
       
   264 
       
   265     // If icon data without alpha id
       
   266     if ( ( RSat::EAlphaIdProvided != iSendUssdData.iAlphaId.iStatus ) &&
       
   267         ( ( RSat::ESelfExplanatory == iSendUssdData.iIconId.iQualifier ) ||
       
   268         ( RSat::ENotSelfExplanatory == iSendUssdData.iIconId.iQualifier ) ) )
       
   269         {
       
   270         commandAllowed = EFalse;
       
   271         iSendUssdRsp.iGeneralResult = RSat::KCmdDataNotUnderstood;
       
   272         iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo;
       
   273         iSendUssdRsp.iAdditionalInfo.Zero();
       
   274         LOG( SIMPLE,
       
   275         "SENDUSSD: CSendUssdHandler::CommandAllowed Icon without alphaid \
       
   276         not allowed" )
       
   277         }
       
   278     else if (
       
   279          ( RMobilePhone::ERegisteredOnHomeNetwork != registrationStatus ) &&
       
   280          ( RMobilePhone::ERegisteredRoaming != registrationStatus ) )
       
   281         {
       
   282         commandAllowed = EFalse;
       
   283         iSendUssdRsp.iInfoType = RSat::KMeProblem;
       
   284         iSendUssdRsp.iAdditionalInfo.SetLength( 1 );
       
   285         iSendUssdRsp.iAdditionalInfo[0] = RSat::KNoService;
       
   286         iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   287         LOG( SIMPLE,
       
   288         "SENDUSSD: CSendUssdHandler::CommandAllowed Not registered in legal \
       
   289         network" )
       
   290         }
       
   291     // OK
       
   292     else
       
   293         {
       
   294         // Check Ussd string validity
       
   295         TInt dataLength( iSendUssdData.iUssdString.iUssdString.Length() );
       
   296         LOG2( SIMPLE, 
       
   297         "SENDUSSD: CSendUssdHandler::CommandAllowed Length of string: %d", 
       
   298         dataLength )
       
   299 
       
   300         // Validate USSD string length.
       
   301         TBool dataValid(
       
   302             ( dataLength > 0 ) && ( dataLength <= KSatMaxUSSDString ) );
       
   303 
       
   304         if ( dataValid )
       
   305             {
       
   306             LOG( SIMPLE, "SENDUSSD:  dataValid true" )
       
   307             // Validate Data Coding Scheme.
       
   308             dataValid = DcsValid( iSendUssdData.iUssdString.iDcs );
       
   309             if ( !dataValid )
       
   310                 {
       
   311                 LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::CommandAllowed Dcs \
       
   312                 not acceptable" )
       
   313                 }
       
   314             }
       
   315 
       
   316         // Second check in case DcsValid() returns EFalse
       
   317         if ( !dataValid )
       
   318             {
       
   319             LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::CommandAllowed \
       
   320             dataValid false" )
       
   321             commandAllowed = EFalse;
       
   322             iSendUssdRsp.iGeneralResult = RSat::KCmdDataNotUnderstood;
       
   323             iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo;
       
   324             iSendUssdRsp.iAdditionalInfo.Zero();
       
   325             }
       
   326         }
       
   327 
       
   328     // Check is command allowd
       
   329     if ( !commandAllowed )
       
   330         {
       
   331         LOG( SIMPLE, "SENDUSSD: \
       
   332             CSendUssdHandler::CommandAllowed exiting - not allowed" )
       
   333         SendTerminalResponse();
       
   334         }
       
   335     // Set icon command flag whether icon data was received and set qualifier
       
   336     // to no icon id
       
   337     // To be removed when icons are allowed in this command
       
   338     else if ( ( RSat::ESelfExplanatory ==
       
   339         iSendUssdData.iIconId.iQualifier ) ||
       
   340         ( RSat::ENotSelfExplanatory ==
       
   341         iSendUssdData.iIconId.iQualifier ) )
       
   342         {
       
   343         LOG( SIMPLE, "SENDUSSD: \
       
   344             CSendUssdHandler::CommandAllowed ENoIconId" )
       
   345         iIconCommand = ETrue;
       
   346         iSendUssdData.iIconId.iQualifier = RSat::ENoIconId;
       
   347         }
       
   348     else
       
   349         {
       
   350         iIconCommand = EFalse;
       
   351         }
       
   352 
       
   353     LOG2( SIMPLE, "SENDUSSD: CSendUssdHandler::CommandAllowed exiting,\
       
   354     commandAllowed: %d", commandAllowed )
       
   355     return commandAllowed;
       
   356     }
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 // From class CSatCommandHandler.
       
   360 // Answers for need of UI session.
       
   361 // -----------------------------------------------------------------------------
       
   362 //
       
   363 TBool CSendUssdHandler::NeedUiSession()
       
   364     {
       
   365     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::NeedUiSession calling" )
       
   366 
       
   367     iNeedUiSession = !TransparentUssdSending();
       
   368 
       
   369     // Notify Cover UI if it's supported
       
   370     if ( iNeedUiSession && iUtils->CoverUiSupported() )
       
   371         {
       
   372         TSatCommandData medEventData;
       
   373         medEventData.iPCmdNumber = RSat::ESendUssd;
       
   374         medEventData.iAlphaId =  iSendUssdData.iAlphaId;
       
   375         if ( iUtils->SystemState().IsConfirmSatOperationsOn() )
       
   376             {
       
   377             LOG( SIMPLE, 
       
   378             "SENDUSSD: CSendUssdHandler::NeedUiSession KSatLongDuration" )
       
   379             medEventData.iDuration.iNumOfUnits = KSatLongDuration;
       
   380             }
       
   381         else
       
   382             {
       
   383             LOG( SIMPLE, 
       
   384             "SENDUSSD: CSendUssdHandler::NeedUiSession KSatDefaultDuration" )
       
   385             medEventData.iDuration.iNumOfUnits = KSatDefaultDuration;
       
   386             }
       
   387         medEventData.iDuration.iTimeUnit = RSat::ESeconds;
       
   388         medEventData.iIconID = iSendUssdData.iIconId;
       
   389         TSatCommandPckg tPckg( medEventData );
       
   390         iUtils->RaiseSatEvent( tPckg );
       
   391         }
       
   392 
       
   393     LOG2( SIMPLE, 
       
   394     "SENDUSSD: CSendUssdHandler::NeedUiSession exiting,iNeedUiSession:%d",
       
   395     iNeedUiSession )
       
   396     return iNeedUiSession;
       
   397     }
       
   398 
       
   399 // -----------------------------------------------------------------------------
       
   400 // From class CSatCommandHandler.
       
   401 // Called when USAT API notifies that command.
       
   402 // -----------------------------------------------------------------------------
       
   403 //
       
   404 void CSendUssdHandler::HandleCommand()
       
   405     {
       
   406     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::HandleCommand calling" )
       
   407 
       
   408     iUtils->NotifyEvent( MSatUtils::ESendUssdExecuting );
       
   409 
       
   410     // This is ETrue, until user rejects
       
   411     iUserAccepted = ETrue;
       
   412 
       
   413     if ( iNeedUiSession )
       
   414         {
       
   415 
       
   416         TRAP_IGNORE(
       
   417         // Register to listen user cancel events:
       
   418         // Cancel key event from dialog
       
   419         iUtils->RegisterL( this, MSatUtils::ECommandCancelled );
       
   420         // End key from dialog
       
   421         iUtils->RegisterL( this, MSatUtils::ECancelledUsingEndKey ) )
       
   422 
       
   423         // Build Qyery and Notify packages
       
   424         TSatAlphaIdStatus alphaIdStatus;
       
   425         if ( RSat::EAlphaIdNotPresent == iSendUssdData.iAlphaId.iStatus )
       
   426             {
       
   427             LOG( SIMPLE, 
       
   428             "SENDUSSD: CSendUssdHandler::HandleCommand EAlphaIdNotPresent" )
       
   429             alphaIdStatus = ESatAlphaIdNotProvided;
       
   430             }
       
   431 
       
   432         else if ( RSat::EAlphaIdProvided == iSendUssdData.iAlphaId.iStatus )
       
   433             {
       
   434             LOG( SIMPLE, 
       
   435             "SENDUSSD: CSendUssdHandler::HandleCommand EAlphaIdProvided" )
       
   436             alphaIdStatus = ESatAlphaIdNotNull;
       
   437             }
       
   438 
       
   439         else
       
   440             {
       
   441             LOG( SIMPLE, 
       
   442             "SENDUSSD: CSendUssdHandler::HandleCommand others" )
       
   443             alphaIdStatus = ESatAlphaIdNull;
       
   444             }
       
   445 
       
   446         // Has to be casted to TInt before casting to TSatIconQualifier, because
       
   447         // GCC warns about the direct cast.
       
   448         const struct TSatIconId iconId = { iSendUssdData.iIconId.iIdentifier,
       
   449             static_cast<TSatIconQualifier>(
       
   450                 static_cast<TInt>( iSendUssdData.iIconId.iQualifier ) ) };
       
   451 
       
   452         iQueryData.iCommand = ESatSSendUssdQuery;
       
   453         iQueryData.iQueryText = iSendUssdData.iAlphaId.iAlphaId;
       
   454         iQueryData.iIconId = iconId;
       
   455         iQueryData.iAlphaIdStatus = alphaIdStatus;
       
   456 
       
   457         iNotificationSent = EFalse;
       
   458         iNotificationData.iCommand = ESatSSendUssdNotify;
       
   459         iNotificationData.iText = iSendUssdData.iAlphaId.iAlphaId;
       
   460         iNotificationData.iIconId = iconId;
       
   461         iNotificationData.iAlphaIdStatus = alphaIdStatus;
       
   462 
       
   463         MSatUiSession* uiSession = iUtils->SatUiHandler().UiSession();
       
   464 
       
   465         // Send either query or notification
       
   466         if ( iQueryOn )
       
   467             {
       
   468             LOG( NORMAL, 
       
   469             "SENDUSSD: CSendUssdHandler::HandleCommand Sending Query" )
       
   470             iNotificationSent = EFalse;
       
   471 
       
   472             // Register service request
       
   473             TRAP_IGNORE( iUtils->RegisterServiceRequestL(
       
   474                 ESatSProactiveQuery,
       
   475                 ESatSProactiveQueryResponse,
       
   476                 this ) )
       
   477 
       
   478             // Send query
       
   479             uiSession->SendCommand(
       
   480                 &iQueryPckg,
       
   481                 &iQueryRspPckg,
       
   482                 ESatSProactiveQuery );
       
   483             }
       
   484          else
       
   485             {
       
   486             LOG( NORMAL, 
       
   487             "SENDUSSD: CSendUssdHandler::HandleCommand Sending notification" )
       
   488 
       
   489             iNotificationSent = ETrue;
       
   490 
       
   491             // Register service request
       
   492             TRAP_IGNORE( iUtils->RegisterServiceRequestL(
       
   493                 ESatSProactiveNotification,
       
   494                 ESatSProactiveNotificationResponse,
       
   495                 this ) )
       
   496 
       
   497             // Send notification
       
   498             uiSession->SendCommand(
       
   499                 &iNotificationDataPckg,
       
   500                 &iNotificationRspPckg,
       
   501                 ESatSProactiveNotification );
       
   502             }
       
   503 
       
   504         if ( !iWait.IsStarted() )
       
   505             {
       
   506             LOG( SIMPLE, 
       
   507             "SENDUSSD: CSendUssdHandler::HandleCommand start iWait" )
       
   508             // Notification / query sent to UI, wait for response
       
   509             iWait.Start();
       
   510             }
       
   511         }
       
   512 
       
   513     if ( iUserAccepted )
       
   514         {
       
   515         LOG( SIMPLE, 
       
   516         "SENDUSSD: CSendUssdHandler::HandleCommand UserAccepted" )
       
   517         // No need to wait response, send Ussd string
       
   518         SendUssdString();
       
   519         }
       
   520 
       
   521     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::HandleCommand exiting" )
       
   522     }
       
   523 
       
   524 // -----------------------------------------------------------------------------
       
   525 // From class CSatCommandHandler.
       
   526 // Indicates the failure of launching ui client
       
   527 // -----------------------------------------------------------------------------
       
   528 //
       
   529 void CSendUssdHandler::UiLaunchFailed()
       
   530     {
       
   531     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::UiLaunchFailed calling" )
       
   532 
       
   533     iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   534     iSendUssdRsp.iInfoType = RSat::KMeProblem;
       
   535     iSendUssdRsp.iAdditionalInfo.SetLength( 1 );
       
   536     iSendUssdRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem;
       
   537     SendTerminalResponse();
       
   538 
       
   539     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::UiLaunchFailed exiting" )
       
   540     }
       
   541     
       
   542 // -----------------------------------------------------------------------------
       
   543 // C++ default constructor can NOT contain any code, that
       
   544 // might leave.
       
   545 // -----------------------------------------------------------------------------
       
   546 //
       
   547 //lint -e{1403, 1769} Can not be initialized.
       
   548 CSendUssdHandler::CSendUssdHandler() :
       
   549     CSatCommandHandler(),
       
   550     iSendUssdData(),
       
   551     iSendUssdPckg( iSendUssdData ),
       
   552     iSendUssdRsp(),
       
   553     iSendUssdRspPckg( iSendUssdRsp ),
       
   554     iQueryData(),
       
   555     iQueryPckg( iQueryData ),
       
   556     iQueryRsp(),
       
   557     iQueryRspPckg( iQueryRsp ),
       
   558     iNotificationData(),
       
   559     iNotificationDataPckg( iNotificationData ),
       
   560     iNotificationRsp(),
       
   561     iNotificationRspPckg( iNotificationRsp ),
       
   562     // To be removed when icons are allowed in this command
       
   563     iIconCommand( EFalse )
       
   564     {
       
   565     LOG( SIMPLE,
       
   566         "SENDUSSD: CSendUssdHandler::CSendUssdHandler calling - exiting" )
       
   567     }
       
   568 
       
   569 
       
   570 // -----------------------------------------------------------------------------
       
   571 // Handles the Ussd string sending
       
   572 // -----------------------------------------------------------------------------
       
   573 //
       
   574 void CSendUssdHandler::SendUssdString()
       
   575     {
       
   576     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendUssdString calling" )
       
   577 
       
   578     TBool sendCompletedFirst( EFalse ); // This is always false
       
   579 
       
   580     TBuf<RSat::KStringMaxSize> sendMessage;
       
   581     sendMessage.Copy( iSendUssdData.iUssdString.iUssdString );
       
   582 
       
   583     TBuf<RSat::KStringMaxSize> receiveMessage;
       
   584 
       
   585     TRAPD( error, SendUssdStringL(
       
   586         sendMessage,
       
   587         iSendUssdData.iUssdString.iDcs,
       
   588         receiveMessage,
       
   589         sendCompletedFirst,
       
   590         iSendUssdRsp.iUssdString.iDcs ) );
       
   591 
       
   592     iSendUssdRsp.iUssdString.iUssdString.Copy( receiveMessage );
       
   593 
       
   594     HandleSendUssdResult( error );
       
   595 
       
   596     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendUssdString exiting" )
       
   597     }
       
   598 
       
   599 // -----------------------------------------------------------------------------
       
   600 // Handles the Ussd string sending.
       
   601 // -----------------------------------------------------------------------------
       
   602 //
       
   603 void CSendUssdHandler::SendUssdStringL(
       
   604     const TDesC& aSendMessage,
       
   605     const TUint8 aSendDcs,
       
   606     TDes& aReceiveMessage,
       
   607     TBool& aSendCompletedFirst,
       
   608     TUint8& aReceivedDcs )
       
   609     {
       
   610     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendUssdStringL calling" )
       
   611     TInt error( KErrNone );
       
   612 
       
   613     if ( iUssdClient )
       
   614         {
       
   615         delete iUssdClient;
       
   616         iUssdClient = NULL;
       
   617         }
       
   618 
       
   619     // This needs to be EFalse, because otherwise KERN-EXEC:3 and SAT Server
       
   620     // crashes.
       
   621     iUssdClient = CPhCltUssdSatClient::NewL( EFalse );
       
   622 
       
   623     LOG2( NORMAL, 
       
   624     "SENDUSSD: CSendUssdHandler::SendUssdStringL aSendDcs:       %x", 
       
   625     aSendDcs )
       
   626     LOG2( NORMAL, 
       
   627     "SENDUSSD: CSendUssdHandler::SendUssdStringL Send length:    %d", 
       
   628     aSendMessage.Length() )
       
   629 
       
   630     #ifdef ENABLE_SAT_LOGGING
       
   631 
       
   632     const TInt count( aSendMessage.Length() );
       
   633     for ( TInt i = 0; i < count; i++ )
       
   634         {
       
   635         LOG2( NORMAL, 
       
   636         "SENDUSSD: CSendUssdHandler::SendUssdStringL :       0x%X", 
       
   637         (char)aSendMessage[i] )
       
   638         }
       
   639 
       
   640     #endif
       
   641 
       
   642     error = iUssdClient->SendSatMessage(
       
   643         aSendMessage,
       
   644         aSendDcs,
       
   645         aReceiveMessage,
       
   646         aSendCompletedFirst,
       
   647         aReceivedDcs );
       
   648 
       
   649     LOG2( NORMAL, 
       
   650     "SENDUSSD: CSendUssdHandler::SendUssdStringL error:          %d", error )
       
   651     LOG2( NORMAL, 
       
   652     "SENDUSSD: CSendUssdHandler::SendUssdStringL aReceivedDcs:   %x", 
       
   653     aReceivedDcs )
       
   654     LOG2( NORMAL, 
       
   655     "SENDUSSD: CSendUssdHandler::SendUssdStringL Received length:%d", 
       
   656     aReceiveMessage.Length() )
       
   657     LOG2( NORMAL, 
       
   658     "SENDUSSD: CSendUssdHandler::SendUssdStringL Completed first:%i", 
       
   659     aSendCompletedFirst )
       
   660 
       
   661     // Convert received Dcs
       
   662     ConvertReceivedDcs( aReceivedDcs );
       
   663 
       
   664     User::LeaveIfError( error );
       
   665 
       
   666     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendUssdStringL exiting" )
       
   667     }
       
   668     
       
   669 // -----------------------------------------------------------------------------
       
   670 // Handles the result of Ussd sending.
       
   671 // -----------------------------------------------------------------------------
       
   672 //
       
   673 void CSendUssdHandler::HandleSendUssdResult( TInt aError )
       
   674     {
       
   675     LOG2( SIMPLE, "SENDUSSD: CSendUssdHandler::HandleSendUssdResult calling: \
       
   676         %i", aError )
       
   677 
       
   678     if ( iQueryRsp.iSessionTerminatedByUser ||
       
   679          iNotificationRsp.iSessionTerminatedByUser ||
       
   680          ( KErrCancel == aError ) ) // End key
       
   681         {
       
   682         LOG( SIMPLE, 
       
   683         "SENDUSSD: CSendUssdHandler::HandleSendUssdResult TerminatedByUser" )
       
   684         iSendUssdRsp.iGeneralResult = RSat::KUssdTransactionTerminatedByUser;
       
   685         iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo;
       
   686         iSendUssdRsp.iAdditionalInfo.Zero();
       
   687         }
       
   688     else if ( TSatExtErrorUtils::IsExtendedError( aError ) ) // extended error
       
   689         {
       
   690         TUint8 addInfo( 0 );
       
   691         // Check and map network failure
       
   692         if ( TSatExtErrorUtils::IsNetworkError( aError ) )
       
   693             {
       
   694             LOG( SIMPLE, 
       
   695             "SENDUSSD: CSendUssdHandler::HandleSendUssdResult NetworkError" )
       
   696             // Network error, map and modify
       
   697             addInfo = TSatExtErrorUtils::MapError( aError );
       
   698             iSendUssdRsp.iGeneralResult = RSat::KNetworkUnableToProcessCmd;
       
   699             iSendUssdRsp.iInfoType = RSat::KSatNetworkErrorInfo;
       
   700             }
       
   701         else
       
   702             {
       
   703             LOG( SIMPLE, 
       
   704             "SENDUSSD: CSendUssdHandler::HandleSendUssdResult MeProblem" )
       
   705             // Not a network error, don't modify
       
   706             addInfo = TSatExtErrorUtils::MapError( aError, EFalse );
       
   707             iSendUssdRsp.iGeneralResult = RSat::KUssdReturnError;
       
   708             iSendUssdRsp.iInfoType = RSat::KMeProblem;
       
   709             }
       
   710         // Add additional info to response
       
   711         iSendUssdRsp.iAdditionalInfo.SetLength( 1 );
       
   712         iSendUssdRsp.iAdditionalInfo[0] = static_cast<TUint16>( addInfo );
       
   713         }
       
   714     else if ( KErrInUse == aError )
       
   715         {
       
   716         LOG( SIMPLE, 
       
   717         "SENDUSSD: CSendUssdHandler::HandleSendUssdResult KMeBusyOnUssd" )
       
   718         iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   719         iSendUssdRsp.iInfoType = RSat::KMeProblem;
       
   720         iSendUssdRsp.iAdditionalInfo.SetLength( 1 );
       
   721         iSendUssdRsp.iAdditionalInfo[0] = RSat::KMeBusyOnUssd;
       
   722         }
       
   723     else if ( KErrGeneral == aError )
       
   724         {
       
   725         LOG( SIMPLE, 
       
   726         "SENDUSSD: CSendUssdHandler::HandleSendUssdResult KMeBusyOnSs" )
       
   727         iSendUssdRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
       
   728         iSendUssdRsp.iInfoType = RSat::KMeProblem;
       
   729         iSendUssdRsp.iAdditionalInfo.SetLength( 1 );
       
   730         iSendUssdRsp.iAdditionalInfo[0] = RSat::KMeBusyOnSs;
       
   731         }
       
   732     else if ( KErrNotFound == aError )
       
   733         {
       
   734         LOG( SIMPLE, 
       
   735         "SENDUSSD: CSendUssdHandler::HandleSendUssdResult \
       
   736         KNoSpecificMeProblem" )
       
   737         iSendUssdRsp.iGeneralResult = RSat::KUssdReturnError;
       
   738         iSendUssdRsp.iInfoType = RSat::KMeProblem;
       
   739         iSendUssdRsp.iAdditionalInfo.SetLength( 1 );
       
   740         iSendUssdRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem;
       
   741         }
       
   742     else if ( KErrNone == aError )   //  Success case
       
   743         {
       
   744         LOG( SIMPLE, 
       
   745         "SENDUSSD: CSendUssdHandler::HandleSendUssdResult success" )
       
   746         // Convert terminal rsp if icon used
       
   747         iSendUssdRsp.iGeneralResult = RSat::KSuccess;
       
   748 
       
   749         // If command had icon data and was done succesfully,
       
   750         // report that icon was not shown.
       
   751         // To be removed and correct handling (i.e. ClientResponse to
       
   752         // notification is received) for general result
       
   753         // KSuccessRequestedIconNotDisplayed must be added when icons
       
   754         // are allowed in this command 
       
   755         if ( iIconCommand )
       
   756             {
       
   757             LOG( SIMPLE, 
       
   758             "SENDUSSD: CSendUssdHandler::HandleSendUssdResult \
       
   759             IconNotDisplayed" )
       
   760             iSendUssdRsp.iGeneralResult =
       
   761                         RSat::KSuccessRequestedIconNotDisplayed;
       
   762             }
       
   763 
       
   764         iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo;
       
   765         iSendUssdRsp.iAdditionalInfo.Zero();
       
   766         }
       
   767     else // unknown error
       
   768         {
       
   769         LOG( SIMPLE, 
       
   770         "SENDUSSD: CSendUssdHandler::HandleSendUssdResult unknown error" )
       
   771         iSendUssdRsp.iGeneralResult = RSat::KUssdReturnError;
       
   772         iSendUssdRsp.iInfoType = RSat::KNoAdditionalInfo;
       
   773         iSendUssdRsp.iAdditionalInfo.Zero();
       
   774         }
       
   775 
       
   776     SendTerminalResponse();
       
   777     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::HandleSendUssdResult exiting" )
       
   778     }
       
   779 
       
   780 
       
   781 // -----------------------------------------------------------------------------
       
   782 // Converts reveived Dcs to correct format.
       
   783 // -----------------------------------------------------------------------------
       
   784 //
       
   785 void CSendUssdHandler::ConvertReceivedDcs( TUint8& aReceivedDcs ) const
       
   786     {
       
   787     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs calling" )
       
   788 
       
   789     switch ( aReceivedDcs )
       
   790         {
       
   791         case KPhCltDcs7Bit:
       
   792             {
       
   793             LOG( NORMAL, 
       
   794             "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs Dcs7Bit" )
       
   795             aReceivedDcs = KSatDcs7Bit;
       
   796             }
       
   797             break;
       
   798 
       
   799         case KPhCltDcs8Bit:
       
   800             {
       
   801             LOG( NORMAL, 
       
   802             "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs Dcs8Bit" )
       
   803             aReceivedDcs = KSatDcs8Bit;
       
   804             }
       
   805             break;
       
   806 
       
   807         case KPhCltDcsUcs2:
       
   808             {
       
   809             LOG( NORMAL, 
       
   810             "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs DcsUCS2" )
       
   811             aReceivedDcs = KSatDcsUCS2;
       
   812             }
       
   813             break;
       
   814 
       
   815         case KPhCltDcsUnknown:
       
   816             {
       
   817             LOG( NORMAL, 
       
   818             "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs DcsUnknown" )
       
   819             aReceivedDcs = KSatDcsUnknown;
       
   820             }
       
   821             break;
       
   822 
       
   823         case KSatDcs7Bit:
       
   824         case KSatDcs8Bit:
       
   825         case KSatDcsUCS2:
       
   826         case KSatDcsUnknown:
       
   827             {
       
   828             LOG( NORMAL, 
       
   829             "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs Already valid" )
       
   830             }
       
   831             break;
       
   832 
       
   833         default:
       
   834             {
       
   835             LOG( NORMAL, 
       
   836             "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs Unknown" )
       
   837             aReceivedDcs = KSatDcsUnknown;
       
   838             }
       
   839             break;
       
   840         }
       
   841 
       
   842     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::ConvertReceivedDcs exiting" )
       
   843     }
       
   844     
       
   845 // -----------------------------------------------------------------------------
       
   846 // Sends terminal response. Makes sure that terminal response
       
   847 // is not send more that once / command.
       
   848 // -----------------------------------------------------------------------------
       
   849 //
       
   850 void CSendUssdHandler::SendTerminalResponse()
       
   851     {
       
   852     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendTerminalResponse calling" )
       
   853 
       
   854     if ( !iTerminalRespSent )
       
   855         {
       
   856         LOG( SIMPLE, 
       
   857         "SENDUSSD: CSendUssdHandler::SendTerminalResponse iTerminalRespSent \
       
   858         false" )
       
   859         iTerminalRespSent = ETrue;
       
   860         iSendUssdRsp.SetPCmdNumber( iSendUssdData.PCmdNumber() );
       
   861         TerminalRsp( RSat::ESendUssd, iSendUssdRspPckg );
       
   862         }
       
   863 
       
   864     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::SendTerminalResponse exiting" )
       
   865     }
       
   866 
       
   867 // -----------------------------------------------------------------------------
       
   868 // Check validity of a given Data Coding Cheme (Dcs).
       
   869 // -----------------------------------------------------------------------------
       
   870 //
       
   871 TBool CSendUssdHandler::DcsValid( const TUint8 aDcs ) const
       
   872     {
       
   873     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DcsValid calling" )
       
   874 
       
   875     TBool isDcsValid( EFalse );
       
   876                                                                //      76543210
       
   877     TUint8 codingGroup  = ( aDcs & 0xF0 ) >> KHighNibbleShift; // bits XXXX____
       
   878     TUint8 characterSet = ( aDcs & 0x0C ) >> KQuarterShift;    // bits ____XX__
       
   879     TUint8 lowQuartet   = ( aDcs & 0x0F );                     // bits ____XXXX
       
   880     LOG2( SIMPLE, 
       
   881     "SENDUSSD: CSendUssdHandler::DcsValid codingGroup: %x", codingGroup)
       
   882     switch ( codingGroup )
       
   883         {
       
   884         case 0x00:
       
   885         case 0x02:
       
   886         case 0x03:
       
   887         case 0x0F:
       
   888             {
       
   889             isDcsValid = ETrue;
       
   890             break;
       
   891             }
       
   892 
       
   893         case 0x01:
       
   894             {
       
   895             if ( ( KDcsCharacterSet7Bit2 == lowQuartet ) ||
       
   896                  ( KDcsCharacterSet16Bit2 == lowQuartet ) )
       
   897                 {
       
   898                 LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DcsValid valid" )
       
   899                 isDcsValid = ETrue;
       
   900                 }
       
   901             break;
       
   902             }
       
   903 
       
   904         case 0x04:
       
   905         case 0x05:
       
   906         case 0x06:
       
   907         case 0x07:
       
   908         case 0x09:
       
   909             {
       
   910             if ( ( KDcsCharacterSet7Bit == characterSet ) ||
       
   911                  ( KDcsCharacterSet8Bit == characterSet ) ||
       
   912                  ( KDcsCharacterSet16Bit == characterSet ) )
       
   913                 {
       
   914                 LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::DcsValid isDcsValid" )
       
   915                 isDcsValid = ETrue;
       
   916                 }
       
   917             break;
       
   918             }
       
   919 
       
   920         default:
       
   921             {
       
   922             LOG2( SIMPLE, "SENDUSSD:   Reserved Dcs found: %x", aDcs )
       
   923             }
       
   924         }
       
   925 
       
   926     LOG2(
       
   927         SIMPLE,
       
   928         "SENDUSSD: CSendUssdHandler::DcsValid exiting, valid = %d",
       
   929         isDcsValid )
       
   930     return isDcsValid;
       
   931     }
       
   932 
       
   933 // -----------------------------------------------------------------------------
       
   934 // USSD sending should be transparent if alpha identifier is provided but it's
       
   935 // length is 0. Also user query setting is not on.
       
   936 // -----------------------------------------------------------------------------
       
   937 //
       
   938 TBool CSendUssdHandler::TransparentUssdSending()
       
   939     {
       
   940     LOG( SIMPLE, "SENDUSSD: CSendUssdHandler::TransparentUssdSending calling" )
       
   941     TBool result( EFalse );
       
   942     const RSat::TAlphaId alphaId( iSendUssdData.iAlphaId );
       
   943 
       
   944     // Store to member variable for later use
       
   945     iQueryOn = iUtils->SystemState().IsConfirmSatOperationsOn();
       
   946 
       
   947     if ( ( alphaId.iStatus == RSat::EAlphaIdProvided &&
       
   948            alphaId.iAlphaId.Length() == 0 ) ||
       
   949            alphaId.iStatus == RSat::EAlphaIdNull )
       
   950         {
       
   951         LOG( SIMPLE, 
       
   952         "SENDUSSD: CSendUssdHandler::TransparentUssdSending AlphaId" )
       
   953         if ( !iQueryOn )
       
   954             {
       
   955             LOG( SIMPLE, 
       
   956             "SENDUSSD: CSendUssdHandler::TransparentUssdSending iQueryOn \
       
   957             false" )
       
   958             result = ETrue;
       
   959             }
       
   960         }
       
   961 
       
   962     LOG2( SIMPLE, 
       
   963     "SENDUSSD: CSendUssdHandler::TransparentUssdSending exiting: %i", result )
       
   964     return result;
       
   965     }
       
   966