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